tests: assert that mask is zero is post_dispatch callback
[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         assert(mask == 0);
36         *p = 1;
37
38         return 0;
39 }
40
41 TEST(post_dispatch_check)
42 {
43         struct wl_event_loop *loop = wl_event_loop_create();
44         struct wl_event_source *source;
45         int dispatch_ran = 0;
46
47         source = wl_event_loop_add_fd(loop, 1, WL_EVENT_READABLE,
48                                       fd_dispatch, &dispatch_ran);
49         wl_event_source_check(source);
50
51         wl_event_loop_dispatch(loop, 0);
52         assert(dispatch_ran);
53
54         wl_event_source_remove(source);
55         wl_event_loop_destroy(loop);
56 }
57
58 struct free_source_context {
59         struct wl_event_source *source1, *source2;
60         int p1[2], p2[2];
61         int count;
62 };
63
64 static int
65 free_source_callback(int fd, uint32_t mask, void *data)
66 {
67         struct free_source_context *context = data;
68
69         context->count++;
70
71         /* Remove other source */
72         if (fd == context->p1[0]) {
73                 wl_event_source_remove(context->source2);
74                 context->source2 = NULL;
75         } else if (fd == context->p2[0]) {
76                 wl_event_source_remove(context->source1);
77                 context->source1 = NULL;
78         } else {
79                 assert(0);
80         }
81
82         return 1;
83 }
84
85 TEST(free_source_with_data)
86 {
87         struct wl_event_loop *loop = wl_event_loop_create();
88         struct free_source_context context;
89         int data;
90
91         /* This test is a little tricky to get right, since we don't
92          * have any guarantee from the event loop (ie epoll) on the
93          * order of which it reports events.  We want to have one
94          * source free the other, but we don't know which one is going
95          * to run first.  So we add two fd sources with a callback
96          * that frees the other source and check that only one of them
97          * run (and that we don't crash, of course).
98          */
99
100         context.count = 0;
101         assert(pipe(context.p1) == 0);
102         assert(pipe(context.p2) == 0);
103         context.source1 =
104                 wl_event_loop_add_fd(loop, context.p1[0], WL_EVENT_READABLE,
105                                      free_source_callback, &context);
106         assert(context.source1);
107         context.source2 =
108                 wl_event_loop_add_fd(loop, context.p2[0], WL_EVENT_READABLE,
109                                      free_source_callback, &context);
110         assert(context.source2);
111
112         data = 5;
113         assert(write(context.p1[1], &data, sizeof data) == sizeof data);
114         assert(write(context.p2[1], &data, sizeof data) == sizeof data);
115
116         wl_event_loop_dispatch(loop, 0);
117
118         assert(context.count == 1);
119
120         if (context.source1)
121                 wl_event_source_remove(context.source1);
122         if (context.source2)
123                 wl_event_source_remove(context.source2);
124         wl_event_loop_destroy(loop);
125
126         assert(close(context.p1[0]) == 0);
127         assert(close(context.p1[1]) == 0);
128         assert(close(context.p2[0]) == 0);
129         assert(close(context.p2[1]) == 0);
130 }
131
132 static int
133 signal_callback(int signal_number, void *data)
134 {
135         int *got_it = data;
136
137         assert(signal_number == SIGUSR1);
138         *got_it = 1;
139
140         return 1;
141 }
142
143 TEST(event_loop_signal)
144 {
145         struct wl_event_loop *loop = wl_event_loop_create();
146         struct wl_event_source *source;
147         int got_it = 0;
148
149         source = wl_event_loop_add_signal(loop, SIGUSR1,
150                                           signal_callback, &got_it);
151         wl_event_loop_dispatch(loop, 0);
152         assert(!got_it);
153         kill(getpid(), SIGUSR1);
154         wl_event_loop_dispatch(loop, 0);
155         assert(got_it);
156
157         wl_event_source_remove(source);
158         wl_event_loop_destroy(loop);
159 }
160
161
162 static int
163 timer_callback(void *data)
164 {
165         int *got_it = data;
166
167         *got_it = 1;
168
169         return 1;
170 }
171
172 TEST(event_loop_timer)
173 {
174         struct wl_event_loop *loop = wl_event_loop_create();
175         struct wl_event_source *source;
176         int got_it = 0;
177
178         source = wl_event_loop_add_timer(loop, timer_callback, &got_it);
179         wl_event_source_timer_update(source, 10);
180         wl_event_loop_dispatch(loop, 0);
181         assert(!got_it);
182         wl_event_loop_dispatch(loop, 20);
183         assert(got_it);
184
185         wl_event_source_remove(source);
186         wl_event_loop_destroy(loop);
187 }