]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/test-event.c
sd-event: EPOLLONESHOT only disables event reporting after an event. The fd is still...
[thirdparty/systemd.git] / src / libsystemd-bus / 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"
25
26static int prepare_handler(sd_event_source *s, void *userdata) {
27 log_info("preparing %c", PTR_TO_INT(userdata));
28 return 1;
29}
30
31static bool got_a, got_b, got_c;
9ec9694c 32static unsigned got_d;
fd38203a
LP
33
34static int io_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
35
36 log_info("got IO on %c", PTR_TO_INT(userdata));
37
38 if (userdata == INT_TO_PTR('a')) {
baf76283 39 assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
fd38203a
LP
40 assert_se(!got_a);
41 got_a = true;
42 } else if (userdata == INT_TO_PTR('b')) {
43 assert_se(!got_b);
44 got_b = true;
9ec9694c
DS
45 } else if (userdata == INT_TO_PTR('d')) {
46 got_d++;
47 if (got_d < 2)
48 assert_se(sd_event_source_set_enabled(s, SD_EVENT_ONESHOT) >= 0);
49 else
50 assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
fd38203a
LP
51 } else
52 assert_not_reached("Yuck!");
53
54 return 1;
55}
56
57static int child_handler(sd_event_source *s, const siginfo_t *si, void *userdata) {
58
59 assert(s);
60 assert(si);
61
62 log_info("got child on %c", PTR_TO_INT(userdata));
63
64 assert(userdata == INT_TO_PTR('f'));
65
66 assert_se(sd_event_request_quit(sd_event_get(s)) >= 0);
67 sd_event_source_unref(s);
68
69 return 1;
70}
71
72static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
73 sd_event_source *p;
74 sigset_t ss;
75 pid_t pid;
76
77 assert(s);
78 assert(si);
79
80 log_info("got signal on %c", PTR_TO_INT(userdata));
81
82 assert(userdata == INT_TO_PTR('e'));
83
84 assert_se(sigemptyset(&ss) >= 0);
85 assert_se(sigaddset(&ss, SIGCHLD) >= 0);
86 assert_se(sigprocmask(SIG_BLOCK, &ss, NULL) >= 0);
87
88 pid = fork();
89 assert_se(pid >= 0);
90
91 if (pid == 0)
92 _exit(0);
93
94 assert_se(sd_event_add_child(sd_event_get(s), pid, WEXITED, child_handler, INT_TO_PTR('f'), &p) >= 0);
baf76283 95 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
96
97 sd_event_source_unref(s);
98
99 return 1;
100}
101
102static int defer_handler(sd_event_source *s, void *userdata) {
103 sd_event_source *p;
104 sigset_t ss;
105
106 assert(s);
107
108 log_info("got defer on %c", PTR_TO_INT(userdata));
109
110 assert(userdata == INT_TO_PTR('d'));
111
112 assert_se(sigemptyset(&ss) >= 0);
113 assert_se(sigaddset(&ss, SIGUSR1) >= 0);
114 assert_se(sigprocmask(SIG_BLOCK, &ss, NULL) >= 0);
115 assert_se(sd_event_add_signal(sd_event_get(s), SIGUSR1, signal_handler, INT_TO_PTR('e'), &p) >= 0);
baf76283 116 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
117 raise(SIGUSR1);
118
119 sd_event_source_unref(s);
120
121 return 1;
122}
123
124static bool do_quit = false;
125
126static int time_handler(sd_event_source *s, uint64_t usec, void *userdata) {
127 log_info("got timer on %c", PTR_TO_INT(userdata));
128
129 if (userdata == INT_TO_PTR('c')) {
130
131 if (do_quit) {
132 sd_event_source *p;
133
134 assert_se(sd_event_add_defer(sd_event_get(s), defer_handler, INT_TO_PTR('d'), &p) >= 0);
baf76283 135 assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
136 } else {
137 assert(!got_c);
138 got_c = true;
139 }
140 } else
141 assert_not_reached("Huh?");
142
143 return 2;
144}
145
da7e457c
LP
146static bool got_quit = false;
147
148static int quit_handler(sd_event_source *s, void *userdata) {
149 log_info("got quit handler on %c", PTR_TO_INT(userdata));
150
151 got_quit = true;
152
153 return 3;
154}
155
fd38203a
LP
156int main(int argc, char *argv[]) {
157 sd_event *e = NULL;
9ec9694c 158 sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL;
fd38203a 159 static const char ch = 'x';
9ec9694c 160 int a[2] = { -1, -1 }, b[2] = { -1, -1}, d[2] = { -1, -1};
fd38203a
LP
161
162 assert_se(pipe(a) >= 0);
163 assert_se(pipe(b) >= 0);
9ec9694c 164 assert_se(pipe(d) >= 0);
fd38203a
LP
165
166 assert_se(sd_event_new(&e) >= 0);
167
9ec9694c
DS
168 got_a = false, got_b = false, got_c = false, got_d = 0;
169
170 /* Add a oneshot handler, trigger it, re-enable it, and trigger
171 * it again. */
172 assert_se(sd_event_add_io(e, d[0], EPOLLIN, io_handler, INT_TO_PTR('d'), &w) >= 0);
173 assert_se(sd_event_source_set_enabled(w, SD_EVENT_ONESHOT) >= 0);
174 assert_se(write(d[1], &ch, 1) >= 0);
175 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
176 assert_se(got_d == 1);
177 assert_se(write(d[1], &ch, 1) >= 0);
178 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
179 assert_se(got_d == 2);
fd38203a
LP
180
181 assert_se(sd_event_add_io(e, a[0], EPOLLIN, io_handler, INT_TO_PTR('a'), &x) >= 0);
182 assert_se(sd_event_add_io(e, b[0], EPOLLIN, io_handler, INT_TO_PTR('b'), &y) >= 0);
c2ba3ad6 183 assert_se(sd_event_add_monotonic(e, 0, 0, time_handler, INT_TO_PTR('c'), &z) >= 0);
da7e457c 184 assert_se(sd_event_add_quit(e, quit_handler, INT_TO_PTR('g'), &q) >= 0);
fd38203a
LP
185
186 assert_se(sd_event_source_set_priority(x, 99) >= 0);
baf76283 187 assert_se(sd_event_source_set_enabled(y, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
188 assert_se(sd_event_source_set_prepare(x, prepare_handler) >= 0);
189 assert_se(sd_event_source_set_priority(z, 50) >= 0);
baf76283 190 assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
191 assert_se(sd_event_source_set_prepare(z, prepare_handler) >= 0);
192
193 assert_se(write(a[1], &ch, 1) >= 0);
194 assert_se(write(b[1], &ch, 1) >= 0);
195
196 assert_se(!got_a && !got_b && !got_c);
197
198 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
199
200 assert_se(!got_a && got_b && !got_c);
201
202 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
203
204 assert_se(!got_a && got_b && got_c);
205
206 assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
207
208 assert_se(got_a && got_b && got_c);
209
210 sd_event_source_unref(x);
211 sd_event_source_unref(y);
212
213 do_quit = true;
214 assert_se(sd_event_source_set_time(z, now(CLOCK_MONOTONIC) + 200 * USEC_PER_MSEC) >= 0);
baf76283 215 assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
fd38203a
LP
216
217 assert_se(sd_event_loop(e) >= 0);
218
219 sd_event_source_unref(z);
da7e457c 220 sd_event_source_unref(q);
fd38203a
LP
221
222 sd_event_unref(e);
223
224 close_pipe(a);
225 close_pipe(b);
226
227 return 0;
228}