]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-event/test-event.c
CODING_STYLE: document order in which to #include headers
[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"
fd38203a
LP
26
27static int prepare_handler(sd_event_source *s, void *userdata) {
28 log_info("preparing %c", PTR_TO_INT(userdata));
29 return 1;
30}
31
12179984 32static bool got_a, got_b, got_c, got_unref;
9ec9694c 33static unsigned got_d;
fd38203a 34
12179984
LP
35static int unref_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
36 sd_event_source_unref(s);
37 got_unref = true;
38 return 0;
39}
40
fd38203a
LP
41static int io_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
42
43 log_info("got IO on %c", PTR_TO_INT(userdata));
44
45 if (userdata == INT_TO_PTR('a')) {
baf76283 46 assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
fd38203a
LP
47 assert_se(!got_a);
48 got_a = true;
49 } else if (userdata == INT_TO_PTR('b')) {
50 assert_se(!got_b);
51 got_b = true;
9ec9694c
DS
52 } else if (userdata == INT_TO_PTR('d')) {
53 got_d++;
54 if (got_d < 2)
55 assert_se(sd_event_source_set_enabled(s, SD_EVENT_ONESHOT) >= 0);
56 else
57 assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
fd38203a
LP
58 } else
59 assert_not_reached("Yuck!");
60
61 return 1;
62}
63
64static int child_handler(sd_event_source *s, const siginfo_t *si, void *userdata) {
65
0c0cdb06
RC
66 assert_se(s);
67 assert_se(si);
fd38203a
LP
68
69 log_info("got child on %c", PTR_TO_INT(userdata));
70
0c0cdb06 71 assert_se(userdata == INT_TO_PTR('f'));
fd38203a 72
6203e07a 73 assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0);
fd38203a
LP
74 sd_event_source_unref(s);
75
76 return 1;
77}
78
79static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
39883f62 80 sd_event_source *p = NULL;
fd38203a
LP
81 sigset_t ss;
82 pid_t pid;
83
0c0cdb06
RC
84 assert_se(s);
85 assert_se(si);
fd38203a
LP
86
87 log_info("got signal on %c", PTR_TO_INT(userdata));
88
0c0cdb06 89 assert_se(userdata == INT_TO_PTR('e'));
fd38203a
LP
90
91 assert_se(sigemptyset(&ss) >= 0);
92 assert_se(sigaddset(&ss, SIGCHLD) >= 0);
93 assert_se(sigprocmask(SIG_BLOCK, &ss, NULL) >= 0);
94
95 pid = fork();
96 assert_se(pid >= 0);
97
98 if (pid == 0)
99 _exit(0);
100
151b9b96 101 assert_se(sd_event_add_child(sd_event_source_get_event(s), &p, pid, WEXITED, child_handler, INT_TO_PTR('f')) >= 0);
baf76283 102 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
103
104 sd_event_source_unref(s);
105
106 return 1;
107}
108
109static int defer_handler(sd_event_source *s, void *userdata) {
39883f62 110 sd_event_source *p = NULL;
fd38203a
LP
111 sigset_t ss;
112
0c0cdb06 113 assert_se(s);
fd38203a
LP
114
115 log_info("got defer on %c", PTR_TO_INT(userdata));
116
0c0cdb06 117 assert_se(userdata == INT_TO_PTR('d'));
fd38203a
LP
118
119 assert_se(sigemptyset(&ss) >= 0);
120 assert_se(sigaddset(&ss, SIGUSR1) >= 0);
121 assert_se(sigprocmask(SIG_BLOCK, &ss, NULL) >= 0);
151b9b96 122 assert_se(sd_event_add_signal(sd_event_source_get_event(s), &p, SIGUSR1, signal_handler, INT_TO_PTR('e')) >= 0);
baf76283 123 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
124 raise(SIGUSR1);
125
126 sd_event_source_unref(s);
127
128 return 1;
129}
130
131static bool do_quit = false;
132
133static int time_handler(sd_event_source *s, uint64_t usec, void *userdata) {
134 log_info("got timer on %c", PTR_TO_INT(userdata));
135
136 if (userdata == INT_TO_PTR('c')) {
137
138 if (do_quit) {
139 sd_event_source *p;
140
151b9b96 141 assert_se(sd_event_add_defer(sd_event_source_get_event(s), &p, defer_handler, INT_TO_PTR('d')) >= 0);
baf76283 142 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a 143 } else {
0c0cdb06 144 assert_se(!got_c);
fd38203a
LP
145 got_c = true;
146 }
147 } else
148 assert_not_reached("Huh?");
149
150 return 2;
151}
152
6203e07a 153static bool got_exit = false;
da7e457c 154
6203e07a 155static int exit_handler(sd_event_source *s, void *userdata) {
da7e457c
LP
156 log_info("got quit handler on %c", PTR_TO_INT(userdata));
157
6203e07a 158 got_exit = true;
da7e457c
LP
159
160 return 3;
161}
162
fd38203a
LP
163int main(int argc, char *argv[]) {
164 sd_event *e = NULL;
12179984 165 sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL, *t = NULL;
fd38203a 166 static const char ch = 'x';
12179984 167 int a[2] = { -1, -1 }, b[2] = { -1, -1}, d[2] = { -1, -1}, k[2] = { -1, -1 };
fd38203a
LP
168
169 assert_se(pipe(a) >= 0);
170 assert_se(pipe(b) >= 0);
9ec9694c 171 assert_se(pipe(d) >= 0);
12179984 172 assert_se(pipe(k) >= 0);
fd38203a 173
afc6adb5 174 assert_se(sd_event_default(&e) >= 0);
fd38203a 175
cde93897
LP
176 assert_se(sd_event_set_watchdog(e, true) >= 0);
177
12179984
LP
178 /* Test whether we cleanly can destroy an io event source from its own handler */
179 got_unref = false;
151b9b96 180 assert_se(sd_event_add_io(e, &t, k[0], EPOLLIN, unref_handler, NULL) >= 0);
12179984
LP
181 assert_se(write(k[1], &ch, 1) == 1);
182 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
183 assert_se(got_unref);
184
9ec9694c
DS
185 got_a = false, got_b = false, got_c = false, got_d = 0;
186
187 /* Add a oneshot handler, trigger it, re-enable it, and trigger
188 * it again. */
151b9b96 189 assert_se(sd_event_add_io(e, &w, d[0], EPOLLIN, io_handler, INT_TO_PTR('d')) >= 0);
9ec9694c
DS
190 assert_se(sd_event_source_set_enabled(w, SD_EVENT_ONESHOT) >= 0);
191 assert_se(write(d[1], &ch, 1) >= 0);
192 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
193 assert_se(got_d == 1);
194 assert_se(write(d[1], &ch, 1) >= 0);
195 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
196 assert_se(got_d == 2);
fd38203a 197
151b9b96
LP
198 assert_se(sd_event_add_io(e, &x, a[0], EPOLLIN, io_handler, INT_TO_PTR('a')) >= 0);
199 assert_se(sd_event_add_io(e, &y, b[0], EPOLLIN, io_handler, INT_TO_PTR('b')) >= 0);
6a0f1f6d 200 assert_se(sd_event_add_time(e, &z, CLOCK_MONOTONIC, 0, 0, time_handler, INT_TO_PTR('c')) >= 0);
151b9b96 201 assert_se(sd_event_add_exit(e, &q, exit_handler, INT_TO_PTR('g')) >= 0);
fd38203a
LP
202
203 assert_se(sd_event_source_set_priority(x, 99) >= 0);
baf76283 204 assert_se(sd_event_source_set_enabled(y, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
205 assert_se(sd_event_source_set_prepare(x, prepare_handler) >= 0);
206 assert_se(sd_event_source_set_priority(z, 50) >= 0);
baf76283 207 assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
fd38203a 208 assert_se(sd_event_source_set_prepare(z, prepare_handler) >= 0);
a71fe8b8
LP
209
210 /* Test for floating event sources */
211 assert_se(sigprocmask_many(SIG_BLOCK, SIGRTMIN+1, -1) == 0);
212 assert_se(sd_event_add_signal(e, NULL, SIGRTMIN+1, NULL, NULL) >= 0);
fd38203a
LP
213
214 assert_se(write(a[1], &ch, 1) >= 0);
215 assert_se(write(b[1], &ch, 1) >= 0);
216
217 assert_se(!got_a && !got_b && !got_c);
218
219 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
220
221 assert_se(!got_a && got_b && !got_c);
222
223 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
224
225 assert_se(!got_a && got_b && got_c);
226
227 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
228
229 assert_se(got_a && got_b && got_c);
230
231 sd_event_source_unref(x);
232 sd_event_source_unref(y);
233
234 do_quit = true;
235 assert_se(sd_event_source_set_time(z, now(CLOCK_MONOTONIC) + 200 * USEC_PER_MSEC) >= 0);
baf76283 236 assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
237
238 assert_se(sd_event_loop(e) >= 0);
239
240 sd_event_source_unref(z);
da7e457c 241 sd_event_source_unref(q);
fd38203a 242
d5e4ec5b
LP
243 sd_event_source_unref(w);
244
fd38203a
LP
245 sd_event_unref(e);
246
3d94f76c
LP
247 safe_close_pair(a);
248 safe_close_pair(b);
249 safe_close_pair(d);
250 safe_close_pair(k);
fd38203a
LP
251
252 return 0;
253}