chiark / gitweb /
delete unused variables
[elogind.git] / src / libsystemd-bus / test-event.c
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
26 static int prepare_handler(sd_event_source *s, void *userdata) {
27         log_info("preparing %c", PTR_TO_INT(userdata));
28         return 1;
29 }
30
31 static bool got_a, got_b, got_c;
32 static unsigned got_d;
33
34 static 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')) {
39                 assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
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;
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);
51         } else
52                 assert_not_reached("Yuck!");
53
54         return 1;
55 }
56
57 static 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_source_get_event(s)) >= 0);
67         sd_event_source_unref(s);
68
69         return 1;
70 }
71
72 static 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_source_get_event(s), pid, WEXITED, child_handler, INT_TO_PTR('f'), &p) >= 0);
95         assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
96
97         sd_event_source_unref(s);
98
99         return 1;
100 }
101
102 static 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_source_get_event(s), SIGUSR1, signal_handler, INT_TO_PTR('e'), &p) >= 0);
116         assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
117         raise(SIGUSR1);
118
119         sd_event_source_unref(s);
120
121         return 1;
122 }
123
124 static bool do_quit = false;
125
126 static 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_source_get_event(s), defer_handler, INT_TO_PTR('d'), &p) >= 0);
135                         assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
136                 } else {
137                         assert(!got_c);
138                         got_c = true;
139                 }
140         } else
141                 assert_not_reached("Huh?");
142
143         return 2;
144 }
145
146 static bool got_quit = false;
147
148 static 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
156 int main(int argc, char *argv[]) {
157         sd_event *e = NULL;
158         sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL;
159         static const char ch = 'x';
160         int a[2] = { -1, -1 }, b[2] = { -1, -1}, d[2] = { -1, -1};
161
162         assert_se(pipe(a) >= 0);
163         assert_se(pipe(b) >= 0);
164         assert_se(pipe(d) >= 0);
165
166         assert_se(sd_event_default(&e) >= 0);
167
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);
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);
183         assert_se(sd_event_add_monotonic(e, 0, 0, time_handler, INT_TO_PTR('c'), &z) >= 0);
184         assert_se(sd_event_add_quit(e, quit_handler, INT_TO_PTR('g'), &q) >= 0);
185
186         assert_se(sd_event_source_set_priority(x, 99) >= 0);
187         assert_se(sd_event_source_set_enabled(y, SD_EVENT_ONESHOT) >= 0);
188         assert_se(sd_event_source_set_prepare(x, prepare_handler) >= 0);
189         assert_se(sd_event_source_set_priority(z, 50) >= 0);
190         assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
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);
215         assert_se(sd_event_source_set_enabled(z, SD_EVENT_ONESHOT) >= 0);
216
217         assert_se(sd_event_loop(e) >= 0);
218
219         sd_event_source_unref(z);
220         sd_event_source_unref(q);
221
222         sd_event_source_unref(w);
223
224         sd_event_unref(e);
225
226         close_pipe(a);
227         close_pipe(b);
228
229         return 0;
230 }