1818c5d8cc721053be659c92b577217914905883Lloyd Pique/*
2818c5d8cc721053be659c92b577217914905883Lloyd Pique * Copyright © 2012 Intel Corporation
3818c5d8cc721053be659c92b577217914905883Lloyd Pique * Copyright © 2012 Jason Ekstrand
4818c5d8cc721053be659c92b577217914905883Lloyd Pique *
5818c5d8cc721053be659c92b577217914905883Lloyd Pique * Permission is hereby granted, free of charge, to any person obtaining
6818c5d8cc721053be659c92b577217914905883Lloyd Pique * a copy of this software and associated documentation files (the
7818c5d8cc721053be659c92b577217914905883Lloyd Pique * "Software"), to deal in the Software without restriction, including
8818c5d8cc721053be659c92b577217914905883Lloyd Pique * without limitation the rights to use, copy, modify, merge, publish,
9818c5d8cc721053be659c92b577217914905883Lloyd Pique * distribute, sublicense, and/or sell copies of the Software, and to
10818c5d8cc721053be659c92b577217914905883Lloyd Pique * permit persons to whom the Software is furnished to do so, subject to
11818c5d8cc721053be659c92b577217914905883Lloyd Pique * the following conditions:
12818c5d8cc721053be659c92b577217914905883Lloyd Pique *
13818c5d8cc721053be659c92b577217914905883Lloyd Pique * The above copyright notice and this permission notice (including the
14818c5d8cc721053be659c92b577217914905883Lloyd Pique * next paragraph) shall be included in all copies or substantial
15818c5d8cc721053be659c92b577217914905883Lloyd Pique * portions of the Software.
16818c5d8cc721053be659c92b577217914905883Lloyd Pique *
17818c5d8cc721053be659c92b577217914905883Lloyd Pique * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18818c5d8cc721053be659c92b577217914905883Lloyd Pique * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19818c5d8cc721053be659c92b577217914905883Lloyd Pique * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20818c5d8cc721053be659c92b577217914905883Lloyd Pique * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21818c5d8cc721053be659c92b577217914905883Lloyd Pique * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22818c5d8cc721053be659c92b577217914905883Lloyd Pique * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23818c5d8cc721053be659c92b577217914905883Lloyd Pique * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24818c5d8cc721053be659c92b577217914905883Lloyd Pique * SOFTWARE.
25818c5d8cc721053be659c92b577217914905883Lloyd Pique */
26818c5d8cc721053be659c92b577217914905883Lloyd Pique
27818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <stdlib.h>
28293a0fb21eafd159514a0ac98d687669f9bb55b1Dennis Kempin#include <stdint.h>
29818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <assert.h>
30818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <unistd.h>
31818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <signal.h>
32818c5d8cc721053be659c92b577217914905883Lloyd Pique#include <sys/time.h>
33818c5d8cc721053be659c92b577217914905883Lloyd Pique
34818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "wayland-private.h"
35818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "wayland-server.h"
36818c5d8cc721053be659c92b577217914905883Lloyd Pique#include "test-runner.h"
37818c5d8cc721053be659c92b577217914905883Lloyd Pique
38818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int
39818c5d8cc721053be659c92b577217914905883Lloyd Piquefd_dispatch(int fd, uint32_t mask, void *data)
40818c5d8cc721053be659c92b577217914905883Lloyd Pique{
41818c5d8cc721053be659c92b577217914905883Lloyd Pique	int *p = data;
42818c5d8cc721053be659c92b577217914905883Lloyd Pique
43818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(mask == 0);
44818c5d8cc721053be659c92b577217914905883Lloyd Pique	++(*p);
45818c5d8cc721053be659c92b577217914905883Lloyd Pique
46818c5d8cc721053be659c92b577217914905883Lloyd Pique	return 0;
47818c5d8cc721053be659c92b577217914905883Lloyd Pique}
48818c5d8cc721053be659c92b577217914905883Lloyd Pique
49818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_post_dispatch_check)
50818c5d8cc721053be659c92b577217914905883Lloyd Pique{
51818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_loop *loop = wl_event_loop_create();
52818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_source *source;
53818c5d8cc721053be659c92b577217914905883Lloyd Pique	int dispatch_ran = 0;
54818c5d8cc721053be659c92b577217914905883Lloyd Pique	int p[2];
55818c5d8cc721053be659c92b577217914905883Lloyd Pique
56818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(loop);
57818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(pipe(p) == 0);
58818c5d8cc721053be659c92b577217914905883Lloyd Pique
59818c5d8cc721053be659c92b577217914905883Lloyd Pique	source = wl_event_loop_add_fd(loop, p[0], WL_EVENT_READABLE,
60818c5d8cc721053be659c92b577217914905883Lloyd Pique				      fd_dispatch, &dispatch_ran);
61818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(source);
62818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_source_check(source);
63818c5d8cc721053be659c92b577217914905883Lloyd Pique
64818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_dispatch(loop, 0);
65818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(dispatch_ran == 1);
66818c5d8cc721053be659c92b577217914905883Lloyd Pique
67818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(close(p[0]) == 0);
68818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(close(p[1]) == 0);
69818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_source_remove(source);
70818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_destroy(loop);
71818c5d8cc721053be659c92b577217914905883Lloyd Pique}
72818c5d8cc721053be659c92b577217914905883Lloyd Pique
73818c5d8cc721053be659c92b577217914905883Lloyd Piquestruct free_source_context {
74818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_source *source1, *source2;
75818c5d8cc721053be659c92b577217914905883Lloyd Pique	int p1[2], p2[2];
76818c5d8cc721053be659c92b577217914905883Lloyd Pique	int count;
77818c5d8cc721053be659c92b577217914905883Lloyd Pique};
78818c5d8cc721053be659c92b577217914905883Lloyd Pique
79818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int
80818c5d8cc721053be659c92b577217914905883Lloyd Piquefree_source_callback(int fd, uint32_t mask, void *data)
81818c5d8cc721053be659c92b577217914905883Lloyd Pique{
82818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct free_source_context *context = data;
83818c5d8cc721053be659c92b577217914905883Lloyd Pique
84818c5d8cc721053be659c92b577217914905883Lloyd Pique	context->count++;
85818c5d8cc721053be659c92b577217914905883Lloyd Pique
86818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* Remove other source */
87818c5d8cc721053be659c92b577217914905883Lloyd Pique	if (fd == context->p1[0]) {
88818c5d8cc721053be659c92b577217914905883Lloyd Pique		wl_event_source_remove(context->source2);
89818c5d8cc721053be659c92b577217914905883Lloyd Pique		context->source2 = NULL;
90818c5d8cc721053be659c92b577217914905883Lloyd Pique	} else if (fd == context->p2[0]) {
91818c5d8cc721053be659c92b577217914905883Lloyd Pique		wl_event_source_remove(context->source1);
92818c5d8cc721053be659c92b577217914905883Lloyd Pique		context->source1 = NULL;
93818c5d8cc721053be659c92b577217914905883Lloyd Pique	} else {
94818c5d8cc721053be659c92b577217914905883Lloyd Pique		assert(0);
95818c5d8cc721053be659c92b577217914905883Lloyd Pique	}
96818c5d8cc721053be659c92b577217914905883Lloyd Pique
97818c5d8cc721053be659c92b577217914905883Lloyd Pique	return 1;
98818c5d8cc721053be659c92b577217914905883Lloyd Pique}
99818c5d8cc721053be659c92b577217914905883Lloyd Pique
100818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_free_source_with_data)
101818c5d8cc721053be659c92b577217914905883Lloyd Pique{
102818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_loop *loop = wl_event_loop_create();
103818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct free_source_context context;
104818c5d8cc721053be659c92b577217914905883Lloyd Pique	int data;
105818c5d8cc721053be659c92b577217914905883Lloyd Pique
106818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* This test is a little tricky to get right, since we don't
107818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * have any guarantee from the event loop (ie epoll) on the
108818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * order of which it reports events.  We want to have one
109818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * source free the other, but we don't know which one is going
110818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * to run first.  So we add two fd sources with a callback
111818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * that frees the other source and check that only one of them
112818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * run (and that we don't crash, of course).
113818c5d8cc721053be659c92b577217914905883Lloyd Pique	 */
114818c5d8cc721053be659c92b577217914905883Lloyd Pique
115818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(loop);
116818c5d8cc721053be659c92b577217914905883Lloyd Pique
117818c5d8cc721053be659c92b577217914905883Lloyd Pique	context.count = 0;
118818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(pipe(context.p1) == 0);
119818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(pipe(context.p2) == 0);
120818c5d8cc721053be659c92b577217914905883Lloyd Pique	context.source1 =
121818c5d8cc721053be659c92b577217914905883Lloyd Pique		wl_event_loop_add_fd(loop, context.p1[0], WL_EVENT_READABLE,
122818c5d8cc721053be659c92b577217914905883Lloyd Pique				     free_source_callback, &context);
123818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(context.source1);
124818c5d8cc721053be659c92b577217914905883Lloyd Pique	context.source2 =
125818c5d8cc721053be659c92b577217914905883Lloyd Pique		wl_event_loop_add_fd(loop, context.p2[0], WL_EVENT_READABLE,
126818c5d8cc721053be659c92b577217914905883Lloyd Pique				     free_source_callback, &context);
127818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(context.source2);
128818c5d8cc721053be659c92b577217914905883Lloyd Pique
129818c5d8cc721053be659c92b577217914905883Lloyd Pique	data = 5;
130818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(write(context.p1[1], &data, sizeof data) == sizeof data);
131818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(write(context.p2[1], &data, sizeof data) == sizeof data);
132818c5d8cc721053be659c92b577217914905883Lloyd Pique
133818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_dispatch(loop, 0);
134818c5d8cc721053be659c92b577217914905883Lloyd Pique
135818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(context.count == 1);
136818c5d8cc721053be659c92b577217914905883Lloyd Pique
137818c5d8cc721053be659c92b577217914905883Lloyd Pique	if (context.source1)
138818c5d8cc721053be659c92b577217914905883Lloyd Pique		wl_event_source_remove(context.source1);
139818c5d8cc721053be659c92b577217914905883Lloyd Pique	if (context.source2)
140818c5d8cc721053be659c92b577217914905883Lloyd Pique		wl_event_source_remove(context.source2);
141818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_destroy(loop);
142818c5d8cc721053be659c92b577217914905883Lloyd Pique
143818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(close(context.p1[0]) == 0);
144818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(close(context.p1[1]) == 0);
145818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(close(context.p2[0]) == 0);
146818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(close(context.p2[1]) == 0);
147818c5d8cc721053be659c92b577217914905883Lloyd Pique}
148818c5d8cc721053be659c92b577217914905883Lloyd Pique
149818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int
150818c5d8cc721053be659c92b577217914905883Lloyd Piquesignal_callback(int signal_number, void *data)
151818c5d8cc721053be659c92b577217914905883Lloyd Pique{
152818c5d8cc721053be659c92b577217914905883Lloyd Pique	int *got_it = data;
153818c5d8cc721053be659c92b577217914905883Lloyd Pique
154818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(signal_number == SIGUSR1);
155818c5d8cc721053be659c92b577217914905883Lloyd Pique	++(*got_it);
156818c5d8cc721053be659c92b577217914905883Lloyd Pique
157818c5d8cc721053be659c92b577217914905883Lloyd Pique	return 1;
158818c5d8cc721053be659c92b577217914905883Lloyd Pique}
159818c5d8cc721053be659c92b577217914905883Lloyd Pique
160818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_signal)
161818c5d8cc721053be659c92b577217914905883Lloyd Pique{
162818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_loop *loop = wl_event_loop_create();
163818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_source *source;
164818c5d8cc721053be659c92b577217914905883Lloyd Pique	int got_it = 0;
165818c5d8cc721053be659c92b577217914905883Lloyd Pique
166818c5d8cc721053be659c92b577217914905883Lloyd Pique	source = wl_event_loop_add_signal(loop, SIGUSR1,
167818c5d8cc721053be659c92b577217914905883Lloyd Pique					  signal_callback, &got_it);
168818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(source);
169818c5d8cc721053be659c92b577217914905883Lloyd Pique
170818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_dispatch(loop, 0);
171818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(!got_it);
172818c5d8cc721053be659c92b577217914905883Lloyd Pique	kill(getpid(), SIGUSR1);
173818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_dispatch(loop, 0);
174818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(got_it == 1);
175818c5d8cc721053be659c92b577217914905883Lloyd Pique
176818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_source_remove(source);
177818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_destroy(loop);
178818c5d8cc721053be659c92b577217914905883Lloyd Pique}
179818c5d8cc721053be659c92b577217914905883Lloyd Pique
180818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_multiple_same_signals)
181818c5d8cc721053be659c92b577217914905883Lloyd Pique{
182818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_loop *loop = wl_event_loop_create();
183818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_source *s1, *s2;
184818c5d8cc721053be659c92b577217914905883Lloyd Pique	int calls_no = 0;
185818c5d8cc721053be659c92b577217914905883Lloyd Pique	int i;
186818c5d8cc721053be659c92b577217914905883Lloyd Pique
187818c5d8cc721053be659c92b577217914905883Lloyd Pique	s1 = wl_event_loop_add_signal(loop, SIGUSR1,
188818c5d8cc721053be659c92b577217914905883Lloyd Pique				      signal_callback, &calls_no);
189818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(s1);
190818c5d8cc721053be659c92b577217914905883Lloyd Pique
191818c5d8cc721053be659c92b577217914905883Lloyd Pique	s2 = wl_event_loop_add_signal(loop, SIGUSR1,
192818c5d8cc721053be659c92b577217914905883Lloyd Pique				      signal_callback, &calls_no);
193818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(s2);
194818c5d8cc721053be659c92b577217914905883Lloyd Pique
195818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_event_loop_dispatch(loop, 0) == 0);
196818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(!calls_no);
197818c5d8cc721053be659c92b577217914905883Lloyd Pique
198818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* Try it more times */
199818c5d8cc721053be659c92b577217914905883Lloyd Pique	for (i = 0; i < 5; ++i) {
200818c5d8cc721053be659c92b577217914905883Lloyd Pique		calls_no = 0;
201818c5d8cc721053be659c92b577217914905883Lloyd Pique		kill(getpid(), SIGUSR1);
202818c5d8cc721053be659c92b577217914905883Lloyd Pique		assert(wl_event_loop_dispatch(loop, 0) == 0);
203818c5d8cc721053be659c92b577217914905883Lloyd Pique		assert(calls_no == 2);
204818c5d8cc721053be659c92b577217914905883Lloyd Pique	}
205818c5d8cc721053be659c92b577217914905883Lloyd Pique
206818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_source_remove(s1);
207818c5d8cc721053be659c92b577217914905883Lloyd Pique
208818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* Try it again  with one source */
209818c5d8cc721053be659c92b577217914905883Lloyd Pique	calls_no = 0;
210818c5d8cc721053be659c92b577217914905883Lloyd Pique	kill(getpid(), SIGUSR1);
211818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_event_loop_dispatch(loop, 0) == 0);
212818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(calls_no == 1);
213818c5d8cc721053be659c92b577217914905883Lloyd Pique
214818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_source_remove(s2);
215818c5d8cc721053be659c92b577217914905883Lloyd Pique
216818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_destroy(loop);
217818c5d8cc721053be659c92b577217914905883Lloyd Pique}
218818c5d8cc721053be659c92b577217914905883Lloyd Pique
219818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int
220818c5d8cc721053be659c92b577217914905883Lloyd Piquetimer_callback(void *data)
221818c5d8cc721053be659c92b577217914905883Lloyd Pique{
222818c5d8cc721053be659c92b577217914905883Lloyd Pique	int *got_it = data;
223818c5d8cc721053be659c92b577217914905883Lloyd Pique
224818c5d8cc721053be659c92b577217914905883Lloyd Pique	++(*got_it);
225818c5d8cc721053be659c92b577217914905883Lloyd Pique
226818c5d8cc721053be659c92b577217914905883Lloyd Pique	return 1;
227818c5d8cc721053be659c92b577217914905883Lloyd Pique}
228818c5d8cc721053be659c92b577217914905883Lloyd Pique
229818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_timer)
230818c5d8cc721053be659c92b577217914905883Lloyd Pique{
231818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_loop *loop = wl_event_loop_create();
232818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_source *source;
233818c5d8cc721053be659c92b577217914905883Lloyd Pique	int got_it = 0;
234818c5d8cc721053be659c92b577217914905883Lloyd Pique
235818c5d8cc721053be659c92b577217914905883Lloyd Pique	source = wl_event_loop_add_timer(loop, timer_callback, &got_it);
236818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(source);
237818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_source_timer_update(source, 10);
238818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_dispatch(loop, 0);
239818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(!got_it);
240818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_dispatch(loop, 20);
241818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(got_it == 1);
242818c5d8cc721053be659c92b577217914905883Lloyd Pique
243818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_source_remove(source);
244818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_destroy(loop);
245818c5d8cc721053be659c92b577217914905883Lloyd Pique}
246818c5d8cc721053be659c92b577217914905883Lloyd Pique
247818c5d8cc721053be659c92b577217914905883Lloyd Pique#define MSEC_TO_USEC(msec) ((msec) * 1000)
248818c5d8cc721053be659c92b577217914905883Lloyd Pique
249818c5d8cc721053be659c92b577217914905883Lloyd Piquestruct timer_update_context {
250818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_source *source1, *source2;
251818c5d8cc721053be659c92b577217914905883Lloyd Pique	int count;
252818c5d8cc721053be659c92b577217914905883Lloyd Pique};
253818c5d8cc721053be659c92b577217914905883Lloyd Pique
254818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int
255818c5d8cc721053be659c92b577217914905883Lloyd Piquetimer_update_callback_1(void *data)
256818c5d8cc721053be659c92b577217914905883Lloyd Pique{
257818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct timer_update_context *context = data;
258818c5d8cc721053be659c92b577217914905883Lloyd Pique
259818c5d8cc721053be659c92b577217914905883Lloyd Pique	context->count++;
260818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_source_timer_update(context->source2, 1000);
261818c5d8cc721053be659c92b577217914905883Lloyd Pique	return 1;
262818c5d8cc721053be659c92b577217914905883Lloyd Pique}
263818c5d8cc721053be659c92b577217914905883Lloyd Pique
264818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic int
265818c5d8cc721053be659c92b577217914905883Lloyd Piquetimer_update_callback_2(void *data)
266818c5d8cc721053be659c92b577217914905883Lloyd Pique{
267818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct timer_update_context *context = data;
268818c5d8cc721053be659c92b577217914905883Lloyd Pique
269818c5d8cc721053be659c92b577217914905883Lloyd Pique	context->count++;
270818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_source_timer_update(context->source1, 1000);
271818c5d8cc721053be659c92b577217914905883Lloyd Pique	return 1;
272818c5d8cc721053be659c92b577217914905883Lloyd Pique}
273818c5d8cc721053be659c92b577217914905883Lloyd Pique
274818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_timer_updates)
275818c5d8cc721053be659c92b577217914905883Lloyd Pique{
276818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_loop *loop = wl_event_loop_create();
277818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct timer_update_context context;
278818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct timeval start_time, end_time, interval;
279818c5d8cc721053be659c92b577217914905883Lloyd Pique
280818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* Create two timers that should expire at the same time (after 10ms).
281818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * The first timer to receive its expiry callback updates the other timer
282818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * with a much larger timeout (1s). This highlights a bug where
283818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * wl_event_source_timer_dispatch would block for this larger timeout
284818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * when reading from the timer fd, before calling the second timer's
285818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * callback.
286818c5d8cc721053be659c92b577217914905883Lloyd Pique	 */
287818c5d8cc721053be659c92b577217914905883Lloyd Pique
288818c5d8cc721053be659c92b577217914905883Lloyd Pique	context.source1 = wl_event_loop_add_timer(loop, timer_update_callback_1,
289818c5d8cc721053be659c92b577217914905883Lloyd Pique						  &context);
290818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(context.source1);
291818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_event_source_timer_update(context.source1, 10) == 0);
292818c5d8cc721053be659c92b577217914905883Lloyd Pique
293818c5d8cc721053be659c92b577217914905883Lloyd Pique	context.source2 = wl_event_loop_add_timer(loop, timer_update_callback_2,
294818c5d8cc721053be659c92b577217914905883Lloyd Pique						  &context);
295818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(context.source2);
296818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_event_source_timer_update(context.source2, 10) == 0);
297818c5d8cc721053be659c92b577217914905883Lloyd Pique
298818c5d8cc721053be659c92b577217914905883Lloyd Pique	context.count = 0;
299818c5d8cc721053be659c92b577217914905883Lloyd Pique
300818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* Since calling the functions between source2's update and
301818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * wl_event_loop_dispatch() takes some time, it may happen
302818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * that only one timer expires until we call epoll_wait.
303818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * This naturally means that only one source is dispatched
304818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * and the test fails. To fix that, sleep 15 ms before
305818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * calling wl_event_loop_dispatch(). That should be enough
306818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * for the second timer to expire.
307818c5d8cc721053be659c92b577217914905883Lloyd Pique	 *
308818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * https://bugs.freedesktop.org/show_bug.cgi?id=80594
309818c5d8cc721053be659c92b577217914905883Lloyd Pique	 */
310818c5d8cc721053be659c92b577217914905883Lloyd Pique	usleep(MSEC_TO_USEC(15));
311818c5d8cc721053be659c92b577217914905883Lloyd Pique
312818c5d8cc721053be659c92b577217914905883Lloyd Pique	gettimeofday(&start_time, NULL);
313818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_dispatch(loop, 20);
314818c5d8cc721053be659c92b577217914905883Lloyd Pique	gettimeofday(&end_time, NULL);
315818c5d8cc721053be659c92b577217914905883Lloyd Pique
316818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(context.count == 2);
317818c5d8cc721053be659c92b577217914905883Lloyd Pique
318818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* Dispatching the events should not have taken much more than 20ms,
319818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * since this is the timeout passed to wl_event_loop_dispatch. If it
320818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * blocked, then it will have taken over 1s.
321818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * Of course, it could take over 1s anyway on a very slow or heavily
322818c5d8cc721053be659c92b577217914905883Lloyd Pique	 * loaded system, so this test isn't 100% perfect.
323818c5d8cc721053be659c92b577217914905883Lloyd Pique	 */
324818c5d8cc721053be659c92b577217914905883Lloyd Pique
325818c5d8cc721053be659c92b577217914905883Lloyd Pique	timersub(&end_time, &start_time, &interval);
326818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(interval.tv_sec < 1);
327818c5d8cc721053be659c92b577217914905883Lloyd Pique
328818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_source_remove(context.source1);
329818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_source_remove(context.source2);
330818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_destroy(loop);
331818c5d8cc721053be659c92b577217914905883Lloyd Pique}
332818c5d8cc721053be659c92b577217914905883Lloyd Pique
333818c5d8cc721053be659c92b577217914905883Lloyd Piquestruct event_loop_destroy_listener {
334818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_listener listener;
335818c5d8cc721053be659c92b577217914905883Lloyd Pique	int done;
336818c5d8cc721053be659c92b577217914905883Lloyd Pique};
337818c5d8cc721053be659c92b577217914905883Lloyd Pique
338818c5d8cc721053be659c92b577217914905883Lloyd Piquestatic void
339818c5d8cc721053be659c92b577217914905883Lloyd Piqueevent_loop_destroy_notify(struct wl_listener *l, void *data)
340818c5d8cc721053be659c92b577217914905883Lloyd Pique{
341818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct event_loop_destroy_listener *listener =
342818c5d8cc721053be659c92b577217914905883Lloyd Pique		container_of(l, struct event_loop_destroy_listener, listener);
343818c5d8cc721053be659c92b577217914905883Lloyd Pique
344818c5d8cc721053be659c92b577217914905883Lloyd Pique	listener->done = 1;
345818c5d8cc721053be659c92b577217914905883Lloyd Pique}
346818c5d8cc721053be659c92b577217914905883Lloyd Pique
347818c5d8cc721053be659c92b577217914905883Lloyd PiqueTEST(event_loop_destroy)
348818c5d8cc721053be659c92b577217914905883Lloyd Pique{
349818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_event_loop *loop;
350818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct wl_display * display;
351818c5d8cc721053be659c92b577217914905883Lloyd Pique	struct event_loop_destroy_listener a, b;
352818c5d8cc721053be659c92b577217914905883Lloyd Pique
353818c5d8cc721053be659c92b577217914905883Lloyd Pique	loop = wl_event_loop_create();
354818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(loop);
355818c5d8cc721053be659c92b577217914905883Lloyd Pique
356818c5d8cc721053be659c92b577217914905883Lloyd Pique	a.listener.notify = &event_loop_destroy_notify;
357818c5d8cc721053be659c92b577217914905883Lloyd Pique	a.done = 0;
358818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_add_destroy_listener(loop, &a.listener);
359818c5d8cc721053be659c92b577217914905883Lloyd Pique
360818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(wl_event_loop_get_destroy_listener(loop,
361818c5d8cc721053be659c92b577217914905883Lloyd Pique	       event_loop_destroy_notify) == &a.listener);
362818c5d8cc721053be659c92b577217914905883Lloyd Pique
363818c5d8cc721053be659c92b577217914905883Lloyd Pique	b.listener.notify = &event_loop_destroy_notify;
364818c5d8cc721053be659c92b577217914905883Lloyd Pique	b.done = 0;
365818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_add_destroy_listener(loop, &b.listener);
366818c5d8cc721053be659c92b577217914905883Lloyd Pique
367818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_list_remove(&a.listener.link);
368818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_destroy(loop);
369818c5d8cc721053be659c92b577217914905883Lloyd Pique
370818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(!a.done);
371818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(b.done);
372818c5d8cc721053be659c92b577217914905883Lloyd Pique
373818c5d8cc721053be659c92b577217914905883Lloyd Pique	/* Test to make sure it gets fired on display destruction */
374818c5d8cc721053be659c92b577217914905883Lloyd Pique	display = wl_display_create();
375818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(display);
376818c5d8cc721053be659c92b577217914905883Lloyd Pique	loop = wl_display_get_event_loop(display);
377818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(loop);
378818c5d8cc721053be659c92b577217914905883Lloyd Pique
379818c5d8cc721053be659c92b577217914905883Lloyd Pique	a.done = 0;
380818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_event_loop_add_destroy_listener(loop, &a.listener);
381818c5d8cc721053be659c92b577217914905883Lloyd Pique
382818c5d8cc721053be659c92b577217914905883Lloyd Pique	wl_display_destroy(display);
383818c5d8cc721053be659c92b577217914905883Lloyd Pique
384818c5d8cc721053be659c92b577217914905883Lloyd Pique	assert(a.done);
385818c5d8cc721053be659c92b577217914905883Lloyd Pique}
386818c5d8cc721053be659c92b577217914905883Lloyd Pique
387