tests: Add timerfd test
[profile/ivi/wayland.git] / tests / event-loop-test.c
1 /*
2  * Copyright © 2012 Intel Corporation
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22
23 #include <stdlib.h>
24 #include <assert.h>
25 #include <unistd.h>
26 #include <signal.h>
27 #include "../src/wayland-server.h"
28 #include "test-runner.h"
29
30 static int
31 fd_dispatch(int fd, uint32_t mask, void *data)
32 {
33         int *p = data;
34
35         *p = 1;
36
37         return 0;
38 }
39
40 TEST(post_dispatch_check)
41 {
42         struct wl_event_loop *loop = wl_event_loop_create();
43         struct wl_event_source *source;
44         int dispatch_ran = 0;
45
46         source = wl_event_loop_add_fd(loop, 1, WL_EVENT_READABLE,
47                                       fd_dispatch, &dispatch_ran);
48         wl_event_source_check(source);
49
50         wl_event_loop_dispatch(loop, 0);
51         assert(dispatch_ran);
52
53         wl_event_source_remove(source);
54         wl_event_loop_destroy(loop);
55 }
56
57 struct free_source_context {
58         struct wl_event_source *source1, *source2;
59         int p1[2], p2[2];
60         int count;
61 };
62
63 static int
64 free_source_callback(int fd, uint32_t mask, void *data)
65 {
66         struct free_source_context *context = data;
67
68         context->count++;
69
70         /* Remove other source */
71         if (fd == context->p1[0]) {
72                 wl_event_source_remove(context->source2);
73                 context->source2 = NULL;
74         } else if (fd == context->p2[0]) {
75                 wl_event_source_remove(context->source1);
76                 context->source1 = NULL;
77         } else {
78                 assert(0);
79         }
80
81         return 1;
82 }
83
84 TEST(free_source_with_data)
85 {
86         struct wl_event_loop *loop = wl_event_loop_create();
87         struct free_source_context context;
88         int data;
89
90         /* This test is a little tricky to get right, since we don't
91          * have any guarantee from the event loop (ie epoll) on the
92          * order of which it reports events.  We want to have one
93          * source free the other, but we don't know which one is going
94          * to run first.  So we add two fd sources with a callback
95          * that frees the other source and check that only one of them
96          * run (and that we don't crash, of course).
97          */
98
99         context.count = 0;
100         assert(pipe(context.p1) == 0);
101         assert(pipe(context.p2) == 0);
102         context.source1 =
103                 wl_event_loop_add_fd(loop, context.p1[0], WL_EVENT_READABLE,
104                                      free_source_callback, &context);
105         assert(context.source1);
106         context.source2 =
107                 wl_event_loop_add_fd(loop, context.p2[0], WL_EVENT_READABLE,
108                                      free_source_callback, &context);
109         assert(context.source2);
110
111         data = 5;
112         assert(write(context.p1[1], &data, sizeof data) == sizeof data);
113         assert(write(context.p2[1], &data, sizeof data) == sizeof data);
114
115         wl_event_loop_dispatch(loop, 0);
116
117         assert(context.count == 1);
118
119         if (context.source1)
120                 wl_event_source_remove(context.source1);
121         if (context.source2)
122                 wl_event_source_remove(context.source2);
123         wl_event_loop_destroy(loop);
124
125         assert(close(context.p1[0]) == 0);
126         assert(close(context.p1[1]) == 0);
127         assert(close(context.p2[0]) == 0);
128         assert(close(context.p2[1]) == 0);
129 }
130
131 static int
132 signal_callback(int signal_number, void *data)
133 {
134         int *got_it = data;
135
136         assert(signal_number == SIGUSR1);
137         *got_it = 1;
138
139         return 1;
140 }
141
142 TEST(event_loop_signal)
143 {
144         struct wl_event_loop *loop = wl_event_loop_create();
145         struct wl_event_source *source;
146         int got_it = 0;
147
148         source = wl_event_loop_add_signal(loop, SIGUSR1,
149                                           signal_callback, &got_it);
150         wl_event_loop_dispatch(loop, 0);
151         assert(!got_it);
152         kill(getpid(), SIGUSR1);
153         wl_event_loop_dispatch(loop, 0);
154         assert(got_it);
155
156         wl_event_source_remove(source);
157         wl_event_loop_destroy(loop);
158 }
159
160
161 static int
162 timer_callback(void *data)
163 {
164         int *got_it = data;
165
166         *got_it = 1;
167
168         return 1;
169 }
170
171 TEST(event_loop_timer)
172 {
173         struct wl_event_loop *loop = wl_event_loop_create();
174         struct wl_event_source *source;
175         int got_it = 0;
176
177         source = wl_event_loop_add_timer(loop, timer_callback, &got_it);
178         wl_event_source_timer_update(source, 10);
179         wl_event_loop_dispatch(loop, 0);
180         assert(!got_it);
181         wl_event_loop_dispatch(loop, 20);
182         assert(got_it);
183
184         wl_event_source_remove(source);
185         wl_event_loop_destroy(loop);
186 }