]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-event/test-event.c
util: split out signal-util.[ch] from util.[ch]
[thirdparty/systemd.git] / src / libsystemd / sd-event / test-event.c
CommitLineData
fd38203a
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include "sd-event.h"
23#include "log.h"
24#include "util.h"
0c0cdb06 25#include "macro.h"
24882e06 26#include "signal-util.h"
fd38203a
LP
27
28static int prepare_handler(sd_event_source *s, void *userdata) {
29 log_info("preparing %c", PTR_TO_INT(userdata));
30 return 1;
31}
32
12179984 33static bool got_a, got_b, got_c, got_unref;
9ec9694c 34static unsigned got_d;
fd38203a 35
12179984
LP
36static int unref_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
37 sd_event_source_unref(s);
38 got_unref = true;
39 return 0;
40}
41
fd38203a
LP
42static int io_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
43
44 log_info("got IO on %c", PTR_TO_INT(userdata));
45
46 if (userdata == INT_TO_PTR('a')) {
baf76283 47 assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
fd38203a
LP
48 assert_se(!got_a);
49 got_a = true;
50 } else if (userdata == INT_TO_PTR('b')) {
51 assert_se(!got_b);
52 got_b = true;
9ec9694c
DS
53 } else if (userdata == INT_TO_PTR('d')) {
54 got_d++;
55 if (got_d < 2)
56 assert_se(sd_event_source_set_enabled(s, SD_EVENT_ONESHOT) >= 0);
57 else
58 assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
fd38203a
LP
59 } else
60 assert_not_reached("Yuck!");
61
62 return 1;
63}
64
65static int child_handler(sd_event_source *s, const siginfo_t *si, void *userdata) {
66
0c0cdb06
RC
67 assert_se(s);
68 assert_se(si);
fd38203a
LP
69
70 log_info("got child on %c", PTR_TO_INT(userdata));
71
0c0cdb06 72 assert_se(userdata == INT_TO_PTR('f'));
fd38203a 73
6203e07a 74 assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0);
fd38203a
LP
75 sd_event_source_unref(s);
76
77 return 1;
78}
79
80static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
39883f62 81 sd_event_source *p = NULL;
fd38203a
LP
82 sigset_t ss;
83 pid_t pid;
84
0c0cdb06
RC
85 assert_se(s);
86 assert_se(si);
fd38203a
LP
87
88 log_info("got signal on %c", PTR_TO_INT(userdata));
89
0c0cdb06 90 assert_se(userdata == INT_TO_PTR('e'));
fd38203a
LP
91
92 assert_se(sigemptyset(&ss) >= 0);
93 assert_se(sigaddset(&ss, SIGCHLD) >= 0);
94 assert_se(sigprocmask(SIG_BLOCK, &ss, NULL) >= 0);
95
96 pid = fork();
97 assert_se(pid >= 0);
98
99 if (pid == 0)
100 _exit(0);
101
151b9b96 102 assert_se(sd_event_add_child(sd_event_source_get_event(s), &p, pid, WEXITED, child_handler, INT_TO_PTR('f')) >= 0);
baf76283 103 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
104
105 sd_event_source_unref(s);
106
107 return 1;
108}
109
110static int defer_handler(sd_event_source *s, void *userdata) {
39883f62 111 sd_event_source *p = NULL;
fd38203a
LP
112 sigset_t ss;
113
0c0cdb06 114 assert_se(s);
fd38203a
LP
115
116 log_info("got defer on %c", PTR_TO_INT(userdata));
117
0c0cdb06 118 assert_se(userdata == INT_TO_PTR('d'));
fd38203a
LP
119
120 assert_se(sigemptyset(&ss) >= 0);
121 assert_se(sigaddset(&ss, SIGUSR1) >= 0);
122 assert_se(sigprocmask(SIG_BLOCK, &ss, NULL) >= 0);
151b9b96 123 assert_se(sd_event_add_signal(sd_event_source_get_event(s), &p, SIGUSR1, signal_handler, INT_TO_PTR('e')) >= 0);
baf76283 124 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
125 raise(SIGUSR1);
126
127 sd_event_source_unref(s);
128
129 return 1;
130}
131
132static bool do_quit = false;
133
134static int time_handler(sd_event_source *s, uint64_t usec, void *userdata) {
135 log_info("got timer on %c", PTR_TO_INT(userdata));
136
137 if (userdata == INT_TO_PTR('c')) {
138
139 if (do_quit) {
140 sd_event_source *p;
141
151b9b96 142 assert_se(sd_event_add_defer(sd_event_source_get_event(s), &p, defer_handler, INT_TO_PTR('d')) >= 0);
baf76283 143 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a 144 } else {
0c0cdb06 145 assert_se(!got_c);
fd38203a
LP
146 got_c = true;
147 }
148 } else
149 assert_not_reached("Huh?");
150
151 return 2;
152}
153
6203e07a 154static bool got_exit = false;
da7e457c 155
6203e07a 156static int exit_handler(sd_event_source *s, void *userdata) {
da7e457c
LP
157 log_info("got quit handler on %c", PTR_TO_INT(userdata));
158
6203e07a 159 got_exit = true;
da7e457c
LP
160
161 return 3;
162}
163
fd38203a
LP
164int main(int argc, char *argv[]) {
165 sd_event *e = NULL;
12179984 166 sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL, *t = NULL;
fd38203a 167 static const char ch = 'x';
12179984 168 int a[2] = { -1, -1 }, b[2] = { -1, -1}, d[2] = { -1, -1}, k[2] = { -1, -1 };
fd38203a
LP
169
170 assert_se(pipe(a) >= 0);
171 assert_se(pipe(b) >= 0);
9ec9694c 172 assert_se(pipe(d) >= 0);
12179984 173 assert_se(pipe(k) >= 0);
fd38203a 174
afc6adb5 175 assert_se(sd_event_default(&e) >= 0);
fd38203a 176
cde93897
LP
177 assert_se(sd_event_set_watchdog(e, true) >= 0);
178
12179984
LP
179 /* Test whether we cleanly can destroy an io event source from its own handler */
180 got_unref = false;
151b9b96 181 assert_se(sd_event_add_io(e, &t, k[0], EPOLLIN, unref_handler, NULL) >= 0);
12179984
LP
182 assert_se(write(k[1], &ch, 1) == 1);
183 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
184 assert_se(got_unref);
185
9ec9694c
DS
186 got_a = false, got_b = false, got_c = false, got_d = 0;
187
188 /* Add a oneshot handler, trigger it, re-enable it, and trigger
189 * it again. */
151b9b96 190 assert_se(sd_event_add_io(e, &w, d[0], EPOLLIN, io_handler, INT_TO_PTR('d')) >= 0);
9ec9694c
DS
191 assert_se(sd_event_source_set_enabled(w, SD_EVENT_ONESHOT) >= 0);
192 assert_se(write(d[1], &ch, 1) >= 0);
193 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
194 assert_se(got_d == 1);
195 assert_se(write(d[1], &ch, 1) >= 0);
196 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
197 assert_se(got_d == 2);
fd38203a 198
151b9b96
LP
199 assert_se(sd_event_add_io(e, &x, a[0], EPOLLIN, io_handler, INT_TO_PTR('a')) >= 0);
200 assert_se(sd_event_add_io(e, &y, b[0], EPOLLIN, io_handler, INT_TO_PTR('b')) >= 0);
6a0f1f6d 201 assert_se(sd_event_add_time(e, &z, CLOCK_MONOTONIC, 0, 0, time_handler, INT_TO_PTR('c')) >= 0);
151b9b96 202 assert_se(sd_event_add_exit(e, &q, exit_handler, INT_TO_PTR('g')) >= 0);
fd38203a
LP
203
204 assert_se(sd_event_source_set_priority(x, 99) >= 0);
baf76283 205 assert_se(sd_event_source_set_enabled(y, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
206 assert_se(sd_event_source_set_prepare(x, prepare_handler) >= 0);
207 assert_se(sd_event_source_set_priority(z, 50) >= 0);
baf76283 208 assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
fd38203a 209 assert_se(sd_event_source_set_prepare(z, prepare_handler) >= 0);
a71fe8b8
LP
210
211 /* Test for floating event sources */
212 assert_se(sigprocmask_many(SIG_BLOCK, SIGRTMIN+1, -1) == 0);
213 assert_se(sd_event_add_signal(e, NULL, SIGRTMIN+1, NULL, NULL) >= 0);
fd38203a
LP
214
215 assert_se(write(a[1], &ch, 1) >= 0);
216 assert_se(write(b[1], &ch, 1) >= 0);
217
218 assert_se(!got_a && !got_b && !got_c);
219
220 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
221
222 assert_se(!got_a && got_b && !got_c);
223
224 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
225
226 assert_se(!got_a && got_b && got_c);
227
228 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
229
230 assert_se(got_a && got_b && got_c);
231
232 sd_event_source_unref(x);
233 sd_event_source_unref(y);
234
235 do_quit = true;
236 assert_se(sd_event_source_set_time(z, now(CLOCK_MONOTONIC) + 200 * USEC_PER_MSEC) >= 0);
baf76283 237 assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
238
239 assert_se(sd_event_loop(e) >= 0);
240
241 sd_event_source_unref(z);
da7e457c 242 sd_event_source_unref(q);
fd38203a 243
d5e4ec5b
LP
244 sd_event_source_unref(w);
245
fd38203a
LP
246 sd_event_unref(e);
247
3d94f76c
LP
248 safe_close_pair(a);
249 safe_close_pair(b);
250 safe_close_pair(d);
251 safe_close_pair(k);
fd38203a
LP
252
253 return 0;
254}