1f2728fe8SHeiher // SPDX-License-Identifier: GPL-2.0
2f2728fe8SHeiher 
3f2728fe8SHeiher #define _GNU_SOURCE
4e9ce39b5SWillem de Bruijn #include <asm/unistd.h>
5e9ce39b5SWillem de Bruijn #include <linux/time_types.h>
6f2728fe8SHeiher #include <poll.h>
7f2728fe8SHeiher #include <unistd.h>
8474328c0SRoman Penyaev #include <assert.h>
9f2728fe8SHeiher #include <signal.h>
10f2728fe8SHeiher #include <pthread.h>
11f2728fe8SHeiher #include <sys/epoll.h>
12f2728fe8SHeiher #include <sys/socket.h>
13282144e0SRoman Penyaev #include <sys/eventfd.h>
14f2728fe8SHeiher #include "../../kselftest_harness.h"
15f2728fe8SHeiher 
16f2728fe8SHeiher struct epoll_mtcontext
17f2728fe8SHeiher {
18f2728fe8SHeiher 	int efd[3];
19f2728fe8SHeiher 	int sfd[4];
20282144e0SRoman Penyaev 	volatile int count;
21f2728fe8SHeiher 
22f2728fe8SHeiher 	pthread_t main;
23f2728fe8SHeiher 	pthread_t waiter;
24f2728fe8SHeiher };
25f2728fe8SHeiher 
26e9ce39b5SWillem de Bruijn #ifndef __NR_epoll_pwait2
27e9ce39b5SWillem de Bruijn #define __NR_epoll_pwait2 -1
28e9ce39b5SWillem de Bruijn #endif
29e9ce39b5SWillem de Bruijn 
sys_epoll_pwait2(int fd,struct epoll_event * events,int maxevents,const struct __kernel_timespec * timeout,const sigset_t * sigset,size_t sigsetsize)30e9ce39b5SWillem de Bruijn static inline int sys_epoll_pwait2(int fd, struct epoll_event *events,
31e9ce39b5SWillem de Bruijn 				   int maxevents,
32e9ce39b5SWillem de Bruijn 				   const struct __kernel_timespec *timeout,
33e9ce39b5SWillem de Bruijn 				   const sigset_t *sigset, size_t sigsetsize)
34e9ce39b5SWillem de Bruijn {
35e9ce39b5SWillem de Bruijn 	return syscall(__NR_epoll_pwait2, fd, events, maxevents, timeout,
36e9ce39b5SWillem de Bruijn 		       sigset, sigsetsize);
37e9ce39b5SWillem de Bruijn }
38e9ce39b5SWillem de Bruijn 
signal_handler(int signum)39f2728fe8SHeiher static void signal_handler(int signum)
40f2728fe8SHeiher {
41f2728fe8SHeiher }
42f2728fe8SHeiher 
kill_timeout(struct epoll_mtcontext * ctx)43f2728fe8SHeiher static void kill_timeout(struct epoll_mtcontext *ctx)
44f2728fe8SHeiher {
45f2728fe8SHeiher 	usleep(1000000);
46f2728fe8SHeiher 	pthread_kill(ctx->main, SIGUSR1);
47f2728fe8SHeiher 	pthread_kill(ctx->waiter, SIGUSR1);
48f2728fe8SHeiher }
49f2728fe8SHeiher 
waiter_entry1a(void * data)50f2728fe8SHeiher static void *waiter_entry1a(void *data)
51f2728fe8SHeiher {
52f2728fe8SHeiher 	struct epoll_event e;
53f2728fe8SHeiher 	struct epoll_mtcontext *ctx = data;
54f2728fe8SHeiher 
55f2728fe8SHeiher 	if (epoll_wait(ctx->efd[0], &e, 1, -1) > 0)
56f2728fe8SHeiher 		__sync_fetch_and_add(&ctx->count, 1);
57f2728fe8SHeiher 
58f2728fe8SHeiher 	return NULL;
59f2728fe8SHeiher }
60f2728fe8SHeiher 
waiter_entry1ap(void * data)61f2728fe8SHeiher static void *waiter_entry1ap(void *data)
62f2728fe8SHeiher {
63f2728fe8SHeiher 	struct pollfd pfd;
64f2728fe8SHeiher 	struct epoll_event e;
65f2728fe8SHeiher 	struct epoll_mtcontext *ctx = data;
66f2728fe8SHeiher 
67f2728fe8SHeiher 	pfd.fd = ctx->efd[0];
68f2728fe8SHeiher 	pfd.events = POLLIN;
69f2728fe8SHeiher 	if (poll(&pfd, 1, -1) > 0) {
70f2728fe8SHeiher 		if (epoll_wait(ctx->efd[0], &e, 1, 0) > 0)
71f2728fe8SHeiher 			__sync_fetch_and_add(&ctx->count, 1);
72f2728fe8SHeiher 	}
73f2728fe8SHeiher 
74f2728fe8SHeiher 	return NULL;
75f2728fe8SHeiher }
76f2728fe8SHeiher 
waiter_entry1o(void * data)77f2728fe8SHeiher static void *waiter_entry1o(void *data)
78f2728fe8SHeiher {
79f2728fe8SHeiher 	struct epoll_event e;
80f2728fe8SHeiher 	struct epoll_mtcontext *ctx = data;
81f2728fe8SHeiher 
82f2728fe8SHeiher 	if (epoll_wait(ctx->efd[0], &e, 1, -1) > 0)
83f2728fe8SHeiher 		__sync_fetch_and_or(&ctx->count, 1);
84f2728fe8SHeiher 
85f2728fe8SHeiher 	return NULL;
86f2728fe8SHeiher }
87f2728fe8SHeiher 
waiter_entry1op(void * data)88f2728fe8SHeiher static void *waiter_entry1op(void *data)
89f2728fe8SHeiher {
90f2728fe8SHeiher 	struct pollfd pfd;
91f2728fe8SHeiher 	struct epoll_event e;
92f2728fe8SHeiher 	struct epoll_mtcontext *ctx = data;
93f2728fe8SHeiher 
94f2728fe8SHeiher 	pfd.fd = ctx->efd[0];
95f2728fe8SHeiher 	pfd.events = POLLIN;
96f2728fe8SHeiher 	if (poll(&pfd, 1, -1) > 0) {
97f2728fe8SHeiher 		if (epoll_wait(ctx->efd[0], &e, 1, 0) > 0)
98f2728fe8SHeiher 			__sync_fetch_and_or(&ctx->count, 1);
99f2728fe8SHeiher 	}
100f2728fe8SHeiher 
101f2728fe8SHeiher 	return NULL;
102f2728fe8SHeiher }
103f2728fe8SHeiher 
waiter_entry2a(void * data)104f2728fe8SHeiher static void *waiter_entry2a(void *data)
105f2728fe8SHeiher {
106f2728fe8SHeiher 	struct epoll_event events[2];
107f2728fe8SHeiher 	struct epoll_mtcontext *ctx = data;
108f2728fe8SHeiher 
109f2728fe8SHeiher 	if (epoll_wait(ctx->efd[0], events, 2, -1) > 0)
110f2728fe8SHeiher 		__sync_fetch_and_add(&ctx->count, 1);
111f2728fe8SHeiher 
112f2728fe8SHeiher 	return NULL;
113f2728fe8SHeiher }
114f2728fe8SHeiher 
waiter_entry2ap(void * data)115f2728fe8SHeiher static void *waiter_entry2ap(void *data)
116f2728fe8SHeiher {
117f2728fe8SHeiher 	struct pollfd pfd;
118f2728fe8SHeiher 	struct epoll_event events[2];
119f2728fe8SHeiher 	struct epoll_mtcontext *ctx = data;
120f2728fe8SHeiher 
121f2728fe8SHeiher 	pfd.fd = ctx->efd[0];
122f2728fe8SHeiher 	pfd.events = POLLIN;
123f2728fe8SHeiher 	if (poll(&pfd, 1, -1) > 0) {
124f2728fe8SHeiher 		if (epoll_wait(ctx->efd[0], events, 2, 0) > 0)
125f2728fe8SHeiher 			__sync_fetch_and_add(&ctx->count, 1);
126f2728fe8SHeiher 	}
127f2728fe8SHeiher 
128f2728fe8SHeiher 	return NULL;
129f2728fe8SHeiher }
130f2728fe8SHeiher 
emitter_entry1(void * data)131f2728fe8SHeiher static void *emitter_entry1(void *data)
132f2728fe8SHeiher {
133f2728fe8SHeiher 	struct epoll_mtcontext *ctx = data;
134f2728fe8SHeiher 
135f2728fe8SHeiher 	usleep(100000);
136f2728fe8SHeiher 	write(ctx->sfd[1], "w", 1);
137f2728fe8SHeiher 
138f2728fe8SHeiher 	kill_timeout(ctx);
139f2728fe8SHeiher 
140f2728fe8SHeiher 	return NULL;
141f2728fe8SHeiher }
142f2728fe8SHeiher 
emitter_entry2(void * data)143f2728fe8SHeiher static void *emitter_entry2(void *data)
144f2728fe8SHeiher {
145f2728fe8SHeiher 	struct epoll_mtcontext *ctx = data;
146f2728fe8SHeiher 
147f2728fe8SHeiher 	usleep(100000);
148f2728fe8SHeiher 	write(ctx->sfd[1], "w", 1);
149f2728fe8SHeiher 	write(ctx->sfd[3], "w", 1);
150f2728fe8SHeiher 
151f2728fe8SHeiher 	kill_timeout(ctx);
152f2728fe8SHeiher 
153f2728fe8SHeiher 	return NULL;
154f2728fe8SHeiher }
155f2728fe8SHeiher 
156f2728fe8SHeiher /*
157f2728fe8SHeiher  *          t0
158f2728fe8SHeiher  *           | (ew)
159f2728fe8SHeiher  *          e0
160f2728fe8SHeiher  *           | (lt)
161f2728fe8SHeiher  *          s0
162f2728fe8SHeiher  */
TEST(epoll1)163f2728fe8SHeiher TEST(epoll1)
164f2728fe8SHeiher {
165f2728fe8SHeiher 	int efd;
166f2728fe8SHeiher 	int sfd[2];
167f2728fe8SHeiher 	struct epoll_event e;
168f2728fe8SHeiher 
169f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
170f2728fe8SHeiher 
171f2728fe8SHeiher 	efd = epoll_create(1);
172f2728fe8SHeiher 	ASSERT_GE(efd, 0);
173f2728fe8SHeiher 
174f2728fe8SHeiher 	e.events = EPOLLIN;
175f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e), 0);
176f2728fe8SHeiher 
177f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
178f2728fe8SHeiher 
179f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, &e, 1, 0), 1);
180f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, &e, 1, 0), 1);
181f2728fe8SHeiher 
182f2728fe8SHeiher 	close(efd);
183f2728fe8SHeiher 	close(sfd[0]);
184f2728fe8SHeiher 	close(sfd[1]);
185f2728fe8SHeiher }
186f2728fe8SHeiher 
187f2728fe8SHeiher /*
188f2728fe8SHeiher  *          t0
189f2728fe8SHeiher  *           | (ew)
190f2728fe8SHeiher  *          e0
191f2728fe8SHeiher  *           | (et)
192f2728fe8SHeiher  *          s0
193f2728fe8SHeiher  */
TEST(epoll2)194f2728fe8SHeiher TEST(epoll2)
195f2728fe8SHeiher {
196f2728fe8SHeiher 	int efd;
197f2728fe8SHeiher 	int sfd[2];
198f2728fe8SHeiher 	struct epoll_event e;
199f2728fe8SHeiher 
200f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
201f2728fe8SHeiher 
202f2728fe8SHeiher 	efd = epoll_create(1);
203f2728fe8SHeiher 	ASSERT_GE(efd, 0);
204f2728fe8SHeiher 
205f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
206f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e), 0);
207f2728fe8SHeiher 
208f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
209f2728fe8SHeiher 
210f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, &e, 1, 0), 1);
211f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, &e, 1, 0), 0);
212f2728fe8SHeiher 
213f2728fe8SHeiher 	close(efd);
214f2728fe8SHeiher 	close(sfd[0]);
215f2728fe8SHeiher 	close(sfd[1]);
216f2728fe8SHeiher }
217f2728fe8SHeiher 
218f2728fe8SHeiher /*
219f2728fe8SHeiher  *           t0
220f2728fe8SHeiher  *            | (ew)
221f2728fe8SHeiher  *           e0
222f2728fe8SHeiher  *     (lt) /  \ (lt)
223f2728fe8SHeiher  *        s0    s2
224f2728fe8SHeiher  */
TEST(epoll3)225f2728fe8SHeiher TEST(epoll3)
226f2728fe8SHeiher {
227f2728fe8SHeiher 	int efd;
228f2728fe8SHeiher 	int sfd[4];
229f2728fe8SHeiher 	struct epoll_event events[2];
230f2728fe8SHeiher 
231f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
232f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
233f2728fe8SHeiher 
234f2728fe8SHeiher 	efd = epoll_create(1);
235f2728fe8SHeiher 	ASSERT_GE(efd, 0);
236f2728fe8SHeiher 
237f2728fe8SHeiher 	events[0].events = EPOLLIN;
238f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], events), 0);
239f2728fe8SHeiher 
240f2728fe8SHeiher 	events[0].events = EPOLLIN;
241f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[2], events), 0);
242f2728fe8SHeiher 
243f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
244f2728fe8SHeiher 	ASSERT_EQ(write(sfd[3], "w", 1), 1);
245f2728fe8SHeiher 
246f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
247f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
248f2728fe8SHeiher 
249f2728fe8SHeiher 	close(efd);
250f2728fe8SHeiher 	close(sfd[0]);
251f2728fe8SHeiher 	close(sfd[1]);
252f2728fe8SHeiher 	close(sfd[2]);
253f2728fe8SHeiher 	close(sfd[3]);
254f2728fe8SHeiher }
255f2728fe8SHeiher 
256f2728fe8SHeiher /*
257f2728fe8SHeiher  *           t0
258f2728fe8SHeiher  *            | (ew)
259f2728fe8SHeiher  *           e0
260f2728fe8SHeiher  *     (et) /  \ (et)
261f2728fe8SHeiher  *        s0    s2
262f2728fe8SHeiher  */
TEST(epoll4)263f2728fe8SHeiher TEST(epoll4)
264f2728fe8SHeiher {
265f2728fe8SHeiher 	int efd;
266f2728fe8SHeiher 	int sfd[4];
267f2728fe8SHeiher 	struct epoll_event events[2];
268f2728fe8SHeiher 
269f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
270f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
271f2728fe8SHeiher 
272f2728fe8SHeiher 	efd = epoll_create(1);
273f2728fe8SHeiher 	ASSERT_GE(efd, 0);
274f2728fe8SHeiher 
275f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
276f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], events), 0);
277f2728fe8SHeiher 
278f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
279f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[2], events), 0);
280f2728fe8SHeiher 
281f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
282f2728fe8SHeiher 	ASSERT_EQ(write(sfd[3], "w", 1), 1);
283f2728fe8SHeiher 
284f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
285f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, events, 2, 0), 0);
286f2728fe8SHeiher 
287f2728fe8SHeiher 	close(efd);
288f2728fe8SHeiher 	close(sfd[0]);
289f2728fe8SHeiher 	close(sfd[1]);
290f2728fe8SHeiher 	close(sfd[2]);
291f2728fe8SHeiher 	close(sfd[3]);
292f2728fe8SHeiher }
293f2728fe8SHeiher 
294f2728fe8SHeiher /*
295f2728fe8SHeiher  *          t0
296f2728fe8SHeiher  *           | (p)
297f2728fe8SHeiher  *          e0
298f2728fe8SHeiher  *           | (lt)
299f2728fe8SHeiher  *          s0
300f2728fe8SHeiher  */
TEST(epoll5)301f2728fe8SHeiher TEST(epoll5)
302f2728fe8SHeiher {
303f2728fe8SHeiher 	int efd;
304f2728fe8SHeiher 	int sfd[2];
305f2728fe8SHeiher 	struct pollfd pfd;
306f2728fe8SHeiher 	struct epoll_event e;
307f2728fe8SHeiher 
308f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
309f2728fe8SHeiher 
310f2728fe8SHeiher 	efd = epoll_create(1);
311f2728fe8SHeiher 	ASSERT_GE(efd, 0);
312f2728fe8SHeiher 
313f2728fe8SHeiher 	e.events = EPOLLIN;
314f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e), 0);
315f2728fe8SHeiher 
316f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
317f2728fe8SHeiher 
318f2728fe8SHeiher 	pfd.fd = efd;
319f2728fe8SHeiher 	pfd.events = POLLIN;
320f2728fe8SHeiher 	ASSERT_EQ(poll(&pfd, 1, 0), 1);
321f2728fe8SHeiher 	ASSERT_EQ(epoll_wait(efd, &e, 1, 0), 1);
322f2728fe8SHeiher 
323f2728fe8SHeiher 	pfd.fd = efd;
324f2728fe8SHeiher 	pfd.events = POLLIN;
325f2728fe8SHeiher 	ASSERT_EQ(poll(&pfd, 1, 0), 1);
326f2728fe8SHeiher 	ASSERT_EQ(epoll_wait(efd, &e, 1, 0), 1);
327f2728fe8SHeiher 
328f2728fe8SHeiher 	close(efd);
329f2728fe8SHeiher 	close(sfd[0]);
330f2728fe8SHeiher 	close(sfd[1]);
331f2728fe8SHeiher }
332f2728fe8SHeiher 
333f2728fe8SHeiher /*
334f2728fe8SHeiher  *          t0
335f2728fe8SHeiher  *           | (p)
336f2728fe8SHeiher  *          e0
337f2728fe8SHeiher  *           | (et)
338f2728fe8SHeiher  *          s0
339f2728fe8SHeiher  */
TEST(epoll6)340f2728fe8SHeiher TEST(epoll6)
341f2728fe8SHeiher {
342f2728fe8SHeiher 	int efd;
343f2728fe8SHeiher 	int sfd[2];
344f2728fe8SHeiher 	struct pollfd pfd;
345f2728fe8SHeiher 	struct epoll_event e;
346f2728fe8SHeiher 
347f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
348f2728fe8SHeiher 
349f2728fe8SHeiher 	efd = epoll_create(1);
350f2728fe8SHeiher 	ASSERT_GE(efd, 0);
351f2728fe8SHeiher 
352f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
353f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e), 0);
354f2728fe8SHeiher 
355f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
356f2728fe8SHeiher 
357f2728fe8SHeiher 	pfd.fd = efd;
358f2728fe8SHeiher 	pfd.events = POLLIN;
359f2728fe8SHeiher 	ASSERT_EQ(poll(&pfd, 1, 0), 1);
360f2728fe8SHeiher 	ASSERT_EQ(epoll_wait(efd, &e, 1, 0), 1);
361f2728fe8SHeiher 
362f2728fe8SHeiher 	pfd.fd = efd;
363f2728fe8SHeiher 	pfd.events = POLLIN;
364f2728fe8SHeiher 	ASSERT_EQ(poll(&pfd, 1, 0), 0);
365f2728fe8SHeiher 	ASSERT_EQ(epoll_wait(efd, &e, 1, 0), 0);
366f2728fe8SHeiher 
367f2728fe8SHeiher 	close(efd);
368f2728fe8SHeiher 	close(sfd[0]);
369f2728fe8SHeiher 	close(sfd[1]);
370f2728fe8SHeiher }
371f2728fe8SHeiher 
372f2728fe8SHeiher /*
373f2728fe8SHeiher  *           t0
374f2728fe8SHeiher  *            | (p)
375f2728fe8SHeiher  *           e0
376f2728fe8SHeiher  *     (lt) /  \ (lt)
377f2728fe8SHeiher  *        s0    s2
378f2728fe8SHeiher  */
379f2728fe8SHeiher 
TEST(epoll7)380f2728fe8SHeiher TEST(epoll7)
381f2728fe8SHeiher {
382f2728fe8SHeiher 	int efd;
383f2728fe8SHeiher 	int sfd[4];
384f2728fe8SHeiher 	struct pollfd pfd;
385f2728fe8SHeiher 	struct epoll_event events[2];
386f2728fe8SHeiher 
387f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
388f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
389f2728fe8SHeiher 
390f2728fe8SHeiher 	efd = epoll_create(1);
391f2728fe8SHeiher 	ASSERT_GE(efd, 0);
392f2728fe8SHeiher 
393f2728fe8SHeiher 	events[0].events = EPOLLIN;
394f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], events), 0);
395f2728fe8SHeiher 
396f2728fe8SHeiher 	events[0].events = EPOLLIN;
397f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[2], events), 0);
398f2728fe8SHeiher 
399f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
400f2728fe8SHeiher 	ASSERT_EQ(write(sfd[3], "w", 1), 1);
401f2728fe8SHeiher 
402f2728fe8SHeiher 	pfd.fd = efd;
403f2728fe8SHeiher 	pfd.events = POLLIN;
404f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
405f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
406f2728fe8SHeiher 
407f2728fe8SHeiher 	pfd.fd = efd;
408f2728fe8SHeiher 	pfd.events = POLLIN;
409f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
410f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
411f2728fe8SHeiher 
412f2728fe8SHeiher 	close(efd);
413f2728fe8SHeiher 	close(sfd[0]);
414f2728fe8SHeiher 	close(sfd[1]);
415f2728fe8SHeiher 	close(sfd[2]);
416f2728fe8SHeiher 	close(sfd[3]);
417f2728fe8SHeiher }
418f2728fe8SHeiher 
419f2728fe8SHeiher /*
420f2728fe8SHeiher  *           t0
421f2728fe8SHeiher  *            | (p)
422f2728fe8SHeiher  *           e0
423f2728fe8SHeiher  *     (et) /  \ (et)
424f2728fe8SHeiher  *        s0    s2
425f2728fe8SHeiher  */
TEST(epoll8)426f2728fe8SHeiher TEST(epoll8)
427f2728fe8SHeiher {
428f2728fe8SHeiher 	int efd;
429f2728fe8SHeiher 	int sfd[4];
430f2728fe8SHeiher 	struct pollfd pfd;
431f2728fe8SHeiher 	struct epoll_event events[2];
432f2728fe8SHeiher 
433f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
434f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
435f2728fe8SHeiher 
436f2728fe8SHeiher 	efd = epoll_create(1);
437f2728fe8SHeiher 	ASSERT_GE(efd, 0);
438f2728fe8SHeiher 
439f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
440f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], events), 0);
441f2728fe8SHeiher 
442f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
443f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[2], events), 0);
444f2728fe8SHeiher 
445f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
446f2728fe8SHeiher 	ASSERT_EQ(write(sfd[3], "w", 1), 1);
447f2728fe8SHeiher 
448f2728fe8SHeiher 	pfd.fd = efd;
449f2728fe8SHeiher 	pfd.events = POLLIN;
450f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
451f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, events, 2, 0), 2);
452f2728fe8SHeiher 
453f2728fe8SHeiher 	pfd.fd = efd;
454f2728fe8SHeiher 	pfd.events = POLLIN;
455f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 0);
456f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd, events, 2, 0), 0);
457f2728fe8SHeiher 
458f2728fe8SHeiher 	close(efd);
459f2728fe8SHeiher 	close(sfd[0]);
460f2728fe8SHeiher 	close(sfd[1]);
461f2728fe8SHeiher 	close(sfd[2]);
462f2728fe8SHeiher 	close(sfd[3]);
463f2728fe8SHeiher }
464f2728fe8SHeiher 
465f2728fe8SHeiher /*
466f2728fe8SHeiher  *        t0    t1
467f2728fe8SHeiher  *     (ew) \  / (ew)
468f2728fe8SHeiher  *           e0
469f2728fe8SHeiher  *            | (lt)
470f2728fe8SHeiher  *           s0
471f2728fe8SHeiher  */
TEST(epoll9)472f2728fe8SHeiher TEST(epoll9)
473f2728fe8SHeiher {
474f2728fe8SHeiher 	pthread_t emitter;
475f2728fe8SHeiher 	struct epoll_event e;
476f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
477f2728fe8SHeiher 
478f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
479f2728fe8SHeiher 
480f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
481f2728fe8SHeiher 
482f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
483f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
484f2728fe8SHeiher 
485f2728fe8SHeiher 	e.events = EPOLLIN;
486f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
487f2728fe8SHeiher 
488f2728fe8SHeiher 	ctx.main = pthread_self();
489f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
490f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
491f2728fe8SHeiher 
492f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
493f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
494f2728fe8SHeiher 
495f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
496f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
497f2728fe8SHeiher 
498f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
499f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
500f2728fe8SHeiher 		pthread_join(emitter, NULL);
501f2728fe8SHeiher 	}
502f2728fe8SHeiher 
503f2728fe8SHeiher 	close(ctx.efd[0]);
504f2728fe8SHeiher 	close(ctx.sfd[0]);
505f2728fe8SHeiher 	close(ctx.sfd[1]);
506f2728fe8SHeiher }
507f2728fe8SHeiher 
508f2728fe8SHeiher /*
509f2728fe8SHeiher  *        t0    t1
510f2728fe8SHeiher  *     (ew) \  / (ew)
511f2728fe8SHeiher  *           e0
512f2728fe8SHeiher  *            | (et)
513f2728fe8SHeiher  *           s0
514f2728fe8SHeiher  */
TEST(epoll10)515f2728fe8SHeiher TEST(epoll10)
516f2728fe8SHeiher {
517f2728fe8SHeiher 	pthread_t emitter;
518f2728fe8SHeiher 	struct epoll_event e;
519f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
520f2728fe8SHeiher 
521f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
522f2728fe8SHeiher 
523f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
524f2728fe8SHeiher 
525f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
526f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
527f2728fe8SHeiher 
528f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
529f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
530f2728fe8SHeiher 
531f2728fe8SHeiher 	ctx.main = pthread_self();
532f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
533f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
534f2728fe8SHeiher 
535f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
536f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
537f2728fe8SHeiher 
538f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
539f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 1);
540f2728fe8SHeiher 
541f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
542f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
543f2728fe8SHeiher 		pthread_join(emitter, NULL);
544f2728fe8SHeiher 	}
545f2728fe8SHeiher 
546f2728fe8SHeiher 	close(ctx.efd[0]);
547f2728fe8SHeiher 	close(ctx.sfd[0]);
548f2728fe8SHeiher 	close(ctx.sfd[1]);
549f2728fe8SHeiher }
550f2728fe8SHeiher 
551f2728fe8SHeiher /*
552f2728fe8SHeiher  *        t0    t1
553f2728fe8SHeiher  *     (ew) \  / (ew)
554f2728fe8SHeiher  *           e0
555f2728fe8SHeiher  *     (lt) /  \ (lt)
556f2728fe8SHeiher  *        s0    s2
557f2728fe8SHeiher  */
TEST(epoll11)558f2728fe8SHeiher TEST(epoll11)
559f2728fe8SHeiher {
560f2728fe8SHeiher 	pthread_t emitter;
561f2728fe8SHeiher 	struct epoll_event events[2];
562f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
563f2728fe8SHeiher 
564f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
565f2728fe8SHeiher 
566f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
567f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
568f2728fe8SHeiher 
569f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
570f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
571f2728fe8SHeiher 
572f2728fe8SHeiher 	events[0].events = EPOLLIN;
573f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], events), 0);
574f2728fe8SHeiher 
575f2728fe8SHeiher 	events[0].events = EPOLLIN;
576f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[2], events), 0);
577f2728fe8SHeiher 
578f2728fe8SHeiher 	ctx.main = pthread_self();
579f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry2a, &ctx), 0);
580f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
581f2728fe8SHeiher 
582f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], events, 2, -1) > 0)
583f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
584f2728fe8SHeiher 
585f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
586f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
587f2728fe8SHeiher 
588f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
589f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
590f2728fe8SHeiher 		pthread_join(emitter, NULL);
591f2728fe8SHeiher 	}
592f2728fe8SHeiher 
593f2728fe8SHeiher 	close(ctx.efd[0]);
594f2728fe8SHeiher 	close(ctx.sfd[0]);
595f2728fe8SHeiher 	close(ctx.sfd[1]);
596f2728fe8SHeiher 	close(ctx.sfd[2]);
597f2728fe8SHeiher 	close(ctx.sfd[3]);
598f2728fe8SHeiher }
599f2728fe8SHeiher 
600f2728fe8SHeiher /*
601f2728fe8SHeiher  *        t0    t1
602f2728fe8SHeiher  *     (ew) \  / (ew)
603f2728fe8SHeiher  *           e0
604f2728fe8SHeiher  *     (et) /  \ (et)
605f2728fe8SHeiher  *        s0    s2
606f2728fe8SHeiher  */
TEST(epoll12)607f2728fe8SHeiher TEST(epoll12)
608f2728fe8SHeiher {
609f2728fe8SHeiher 	pthread_t emitter;
610f2728fe8SHeiher 	struct epoll_event events[2];
611f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
612f2728fe8SHeiher 
613f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
614f2728fe8SHeiher 
615f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
616f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
617f2728fe8SHeiher 
618f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
619f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
620f2728fe8SHeiher 
621f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
622f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], events), 0);
623f2728fe8SHeiher 
624f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
625f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[2], events), 0);
626f2728fe8SHeiher 
627f2728fe8SHeiher 	ctx.main = pthread_self();
628f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
629f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
630f2728fe8SHeiher 
631f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], events, 1, -1) > 0)
632f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
633f2728fe8SHeiher 
634f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
635f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
636f2728fe8SHeiher 
637f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
638f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
639f2728fe8SHeiher 		pthread_join(emitter, NULL);
640f2728fe8SHeiher 	}
641f2728fe8SHeiher 
642f2728fe8SHeiher 	close(ctx.efd[0]);
643f2728fe8SHeiher 	close(ctx.sfd[0]);
644f2728fe8SHeiher 	close(ctx.sfd[1]);
645f2728fe8SHeiher 	close(ctx.sfd[2]);
646f2728fe8SHeiher 	close(ctx.sfd[3]);
647f2728fe8SHeiher }
648f2728fe8SHeiher 
649f2728fe8SHeiher /*
650f2728fe8SHeiher  *        t0    t1
651f2728fe8SHeiher  *     (ew) \  / (p)
652f2728fe8SHeiher  *           e0
653f2728fe8SHeiher  *            | (lt)
654f2728fe8SHeiher  *           s0
655f2728fe8SHeiher  */
TEST(epoll13)656f2728fe8SHeiher TEST(epoll13)
657f2728fe8SHeiher {
658f2728fe8SHeiher 	pthread_t emitter;
659f2728fe8SHeiher 	struct epoll_event e;
660f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
661f2728fe8SHeiher 
662f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
663f2728fe8SHeiher 
664f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
665f2728fe8SHeiher 
666f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
667f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
668f2728fe8SHeiher 
669f2728fe8SHeiher 	e.events = EPOLLIN;
670f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
671f2728fe8SHeiher 
672f2728fe8SHeiher 	ctx.main = pthread_self();
673f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
674f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
675f2728fe8SHeiher 
676f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
677f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
678f2728fe8SHeiher 
679f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
680f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
681f2728fe8SHeiher 
682f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
683f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
684f2728fe8SHeiher 		pthread_join(emitter, NULL);
685f2728fe8SHeiher 	}
686f2728fe8SHeiher 
687f2728fe8SHeiher 	close(ctx.efd[0]);
688f2728fe8SHeiher 	close(ctx.sfd[0]);
689f2728fe8SHeiher 	close(ctx.sfd[1]);
690f2728fe8SHeiher }
691f2728fe8SHeiher 
692f2728fe8SHeiher /*
693f2728fe8SHeiher  *        t0    t1
694f2728fe8SHeiher  *     (ew) \  / (p)
695f2728fe8SHeiher  *           e0
696f2728fe8SHeiher  *            | (et)
697f2728fe8SHeiher  *           s0
698f2728fe8SHeiher  */
TEST(epoll14)699f2728fe8SHeiher TEST(epoll14)
700f2728fe8SHeiher {
701f2728fe8SHeiher 	pthread_t emitter;
702f2728fe8SHeiher 	struct epoll_event e;
703f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
704f2728fe8SHeiher 
705f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
706f2728fe8SHeiher 
707f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
708f2728fe8SHeiher 
709f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
710f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
711f2728fe8SHeiher 
712f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
713f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
714f2728fe8SHeiher 
715f2728fe8SHeiher 	ctx.main = pthread_self();
716f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
717f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
718f2728fe8SHeiher 
719f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
720f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
721f2728fe8SHeiher 
722f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
723f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 1);
724f2728fe8SHeiher 
725f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
726f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
727f2728fe8SHeiher 		pthread_join(emitter, NULL);
728f2728fe8SHeiher 	}
729f2728fe8SHeiher 
730f2728fe8SHeiher 	close(ctx.efd[0]);
731f2728fe8SHeiher 	close(ctx.sfd[0]);
732f2728fe8SHeiher 	close(ctx.sfd[1]);
733f2728fe8SHeiher }
734f2728fe8SHeiher 
735f2728fe8SHeiher /*
736f2728fe8SHeiher  *        t0    t1
737f2728fe8SHeiher  *     (ew) \  / (p)
738f2728fe8SHeiher  *           e0
739f2728fe8SHeiher  *     (lt) /  \ (lt)
740f2728fe8SHeiher  *        s0    s2
741f2728fe8SHeiher  */
TEST(epoll15)742f2728fe8SHeiher TEST(epoll15)
743f2728fe8SHeiher {
744f2728fe8SHeiher 	pthread_t emitter;
745f2728fe8SHeiher 	struct epoll_event events[2];
746f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
747f2728fe8SHeiher 
748f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
749f2728fe8SHeiher 
750f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
751f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
752f2728fe8SHeiher 
753f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
754f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
755f2728fe8SHeiher 
756f2728fe8SHeiher 	events[0].events = EPOLLIN;
757f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], events), 0);
758f2728fe8SHeiher 
759f2728fe8SHeiher 	events[0].events = EPOLLIN;
760f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[2], events), 0);
761f2728fe8SHeiher 
762f2728fe8SHeiher 	ctx.main = pthread_self();
763f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry2ap, &ctx), 0);
764f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
765f2728fe8SHeiher 
766f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], events, 2, -1) > 0)
767f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
768f2728fe8SHeiher 
769f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
770f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
771f2728fe8SHeiher 
772f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
773f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
774f2728fe8SHeiher 		pthread_join(emitter, NULL);
775f2728fe8SHeiher 	}
776f2728fe8SHeiher 
777f2728fe8SHeiher 	close(ctx.efd[0]);
778f2728fe8SHeiher 	close(ctx.sfd[0]);
779f2728fe8SHeiher 	close(ctx.sfd[1]);
780f2728fe8SHeiher 	close(ctx.sfd[2]);
781f2728fe8SHeiher 	close(ctx.sfd[3]);
782f2728fe8SHeiher }
783f2728fe8SHeiher 
784f2728fe8SHeiher /*
785f2728fe8SHeiher  *        t0    t1
786f2728fe8SHeiher  *     (ew) \  / (p)
787f2728fe8SHeiher  *           e0
788f2728fe8SHeiher  *     (et) /  \ (et)
789f2728fe8SHeiher  *        s0    s2
790f2728fe8SHeiher  */
TEST(epoll16)791f2728fe8SHeiher TEST(epoll16)
792f2728fe8SHeiher {
793f2728fe8SHeiher 	pthread_t emitter;
794f2728fe8SHeiher 	struct epoll_event events[2];
795f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
796f2728fe8SHeiher 
797f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
798f2728fe8SHeiher 
799f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
800f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
801f2728fe8SHeiher 
802f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
803f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
804f2728fe8SHeiher 
805f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
806f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], events), 0);
807f2728fe8SHeiher 
808f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
809f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[2], events), 0);
810f2728fe8SHeiher 
811f2728fe8SHeiher 	ctx.main = pthread_self();
812f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
813f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
814f2728fe8SHeiher 
815f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], events, 1, -1) > 0)
816f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
817f2728fe8SHeiher 
818f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
819f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
820f2728fe8SHeiher 
821f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
822f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
823f2728fe8SHeiher 		pthread_join(emitter, NULL);
824f2728fe8SHeiher 	}
825f2728fe8SHeiher 
826f2728fe8SHeiher 	close(ctx.efd[0]);
827f2728fe8SHeiher 	close(ctx.sfd[0]);
828f2728fe8SHeiher 	close(ctx.sfd[1]);
829f2728fe8SHeiher 	close(ctx.sfd[2]);
830f2728fe8SHeiher 	close(ctx.sfd[3]);
831f2728fe8SHeiher }
832f2728fe8SHeiher 
833f2728fe8SHeiher /*
834f2728fe8SHeiher  *          t0
835f2728fe8SHeiher  *           | (ew)
836f2728fe8SHeiher  *          e0
837f2728fe8SHeiher  *           | (lt)
838f2728fe8SHeiher  *          e1
839f2728fe8SHeiher  *           | (lt)
840f2728fe8SHeiher  *          s0
841f2728fe8SHeiher  */
TEST(epoll17)842f2728fe8SHeiher TEST(epoll17)
843f2728fe8SHeiher {
844f2728fe8SHeiher 	int efd[2];
845f2728fe8SHeiher 	int sfd[2];
846f2728fe8SHeiher 	struct epoll_event e;
847f2728fe8SHeiher 
848f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
849f2728fe8SHeiher 
850f2728fe8SHeiher 	efd[0] = epoll_create(1);
851f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
852f2728fe8SHeiher 
853f2728fe8SHeiher 	efd[1] = epoll_create(1);
854f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
855f2728fe8SHeiher 
856f2728fe8SHeiher 	e.events = EPOLLIN;
857f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
858f2728fe8SHeiher 
859f2728fe8SHeiher 	e.events = EPOLLIN;
860f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
861f2728fe8SHeiher 
862f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
863f2728fe8SHeiher 
864f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
865f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
866f2728fe8SHeiher 
867f2728fe8SHeiher 	close(efd[0]);
868f2728fe8SHeiher 	close(efd[1]);
869f2728fe8SHeiher 	close(sfd[0]);
870f2728fe8SHeiher 	close(sfd[1]);
871f2728fe8SHeiher }
872f2728fe8SHeiher 
873f2728fe8SHeiher /*
874f2728fe8SHeiher  *          t0
875f2728fe8SHeiher  *           | (ew)
876f2728fe8SHeiher  *          e0
877f2728fe8SHeiher  *           | (lt)
878f2728fe8SHeiher  *          e1
879f2728fe8SHeiher  *           | (et)
880f2728fe8SHeiher  *          s0
881f2728fe8SHeiher  */
TEST(epoll18)882f2728fe8SHeiher TEST(epoll18)
883f2728fe8SHeiher {
884f2728fe8SHeiher 	int efd[2];
885f2728fe8SHeiher 	int sfd[2];
886f2728fe8SHeiher 	struct epoll_event e;
887f2728fe8SHeiher 
888f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
889f2728fe8SHeiher 
890f2728fe8SHeiher 	efd[0] = epoll_create(1);
891f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
892f2728fe8SHeiher 
893f2728fe8SHeiher 	efd[1] = epoll_create(1);
894f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
895f2728fe8SHeiher 
896f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
897f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
898f2728fe8SHeiher 
899f2728fe8SHeiher 	e.events = EPOLLIN;
900f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
901f2728fe8SHeiher 
902f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
903f2728fe8SHeiher 
904f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
905f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
906f2728fe8SHeiher 
907f2728fe8SHeiher 	close(efd[0]);
908f2728fe8SHeiher 	close(efd[1]);
909f2728fe8SHeiher 	close(sfd[0]);
910f2728fe8SHeiher 	close(sfd[1]);
911f2728fe8SHeiher }
912f2728fe8SHeiher 
913f2728fe8SHeiher /*
914f2728fe8SHeiher  *           t0
915f2728fe8SHeiher  *            | (ew)
916f2728fe8SHeiher  *           e0
917f2728fe8SHeiher  *            | (et)
918f2728fe8SHeiher  *           e1
919f2728fe8SHeiher  *            | (lt)
920f2728fe8SHeiher  *           s0
921f2728fe8SHeiher  */
TEST(epoll19)922f2728fe8SHeiher TEST(epoll19)
923f2728fe8SHeiher {
924f2728fe8SHeiher 	int efd[2];
925f2728fe8SHeiher 	int sfd[2];
926f2728fe8SHeiher 	struct epoll_event e;
927f2728fe8SHeiher 
928f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
929f2728fe8SHeiher 
930f2728fe8SHeiher 	efd[0] = epoll_create(1);
931f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
932f2728fe8SHeiher 
933f2728fe8SHeiher 	efd[1] = epoll_create(1);
934f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
935f2728fe8SHeiher 
936f2728fe8SHeiher 	e.events = EPOLLIN;
937f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
938f2728fe8SHeiher 
939f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
940f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
941f2728fe8SHeiher 
942f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
943f2728fe8SHeiher 
944f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
945f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 0);
946f2728fe8SHeiher 
947f2728fe8SHeiher 	close(efd[0]);
948f2728fe8SHeiher 	close(efd[1]);
949f2728fe8SHeiher 	close(sfd[0]);
950f2728fe8SHeiher 	close(sfd[1]);
951f2728fe8SHeiher }
952f2728fe8SHeiher 
953f2728fe8SHeiher /*
954f2728fe8SHeiher  *           t0
955f2728fe8SHeiher  *            | (ew)
956f2728fe8SHeiher  *           e0
957f2728fe8SHeiher  *            | (et)
958f2728fe8SHeiher  *           e1
959f2728fe8SHeiher  *            | (et)
960f2728fe8SHeiher  *           s0
961f2728fe8SHeiher  */
TEST(epoll20)962f2728fe8SHeiher TEST(epoll20)
963f2728fe8SHeiher {
964f2728fe8SHeiher 	int efd[2];
965f2728fe8SHeiher 	int sfd[2];
966f2728fe8SHeiher 	struct epoll_event e;
967f2728fe8SHeiher 
968f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
969f2728fe8SHeiher 
970f2728fe8SHeiher 	efd[0] = epoll_create(1);
971f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
972f2728fe8SHeiher 
973f2728fe8SHeiher 	efd[1] = epoll_create(1);
974f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
975f2728fe8SHeiher 
976f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
977f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
978f2728fe8SHeiher 
979f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
980f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
981f2728fe8SHeiher 
982f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
983f2728fe8SHeiher 
984f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
985f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 0);
986f2728fe8SHeiher 
987f2728fe8SHeiher 	close(efd[0]);
988f2728fe8SHeiher 	close(efd[1]);
989f2728fe8SHeiher 	close(sfd[0]);
990f2728fe8SHeiher 	close(sfd[1]);
991f2728fe8SHeiher }
992f2728fe8SHeiher 
993f2728fe8SHeiher /*
994f2728fe8SHeiher  *          t0
995f2728fe8SHeiher  *           | (p)
996f2728fe8SHeiher  *          e0
997f2728fe8SHeiher  *           | (lt)
998f2728fe8SHeiher  *          e1
999f2728fe8SHeiher  *           | (lt)
1000f2728fe8SHeiher  *          s0
1001f2728fe8SHeiher  */
TEST(epoll21)1002f2728fe8SHeiher TEST(epoll21)
1003f2728fe8SHeiher {
1004f2728fe8SHeiher 	int efd[2];
1005f2728fe8SHeiher 	int sfd[2];
1006f2728fe8SHeiher 	struct pollfd pfd;
1007f2728fe8SHeiher 	struct epoll_event e;
1008f2728fe8SHeiher 
1009f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
1010f2728fe8SHeiher 
1011f2728fe8SHeiher 	efd[0] = epoll_create(1);
1012f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
1013f2728fe8SHeiher 
1014f2728fe8SHeiher 	efd[1] = epoll_create(1);
1015f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
1016f2728fe8SHeiher 
1017f2728fe8SHeiher 	e.events = EPOLLIN;
1018f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
1019f2728fe8SHeiher 
1020f2728fe8SHeiher 	e.events = EPOLLIN;
1021f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
1022f2728fe8SHeiher 
1023f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
1024f2728fe8SHeiher 
1025f2728fe8SHeiher 	pfd.fd = efd[0];
1026f2728fe8SHeiher 	pfd.events = POLLIN;
1027f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
1028f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
1029f2728fe8SHeiher 
1030f2728fe8SHeiher 	pfd.fd = efd[0];
1031f2728fe8SHeiher 	pfd.events = POLLIN;
1032f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
1033f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
1034f2728fe8SHeiher 
1035f2728fe8SHeiher 	close(efd[0]);
1036f2728fe8SHeiher 	close(efd[1]);
1037f2728fe8SHeiher 	close(sfd[0]);
1038f2728fe8SHeiher 	close(sfd[1]);
1039f2728fe8SHeiher }
1040f2728fe8SHeiher 
1041f2728fe8SHeiher /*
1042f2728fe8SHeiher  *          t0
1043f2728fe8SHeiher  *           | (p)
1044f2728fe8SHeiher  *          e0
1045f2728fe8SHeiher  *           | (lt)
1046f2728fe8SHeiher  *          e1
1047f2728fe8SHeiher  *           | (et)
1048f2728fe8SHeiher  *          s0
1049f2728fe8SHeiher  */
TEST(epoll22)1050f2728fe8SHeiher TEST(epoll22)
1051f2728fe8SHeiher {
1052f2728fe8SHeiher 	int efd[2];
1053f2728fe8SHeiher 	int sfd[2];
1054f2728fe8SHeiher 	struct pollfd pfd;
1055f2728fe8SHeiher 	struct epoll_event e;
1056f2728fe8SHeiher 
1057f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
1058f2728fe8SHeiher 
1059f2728fe8SHeiher 	efd[0] = epoll_create(1);
1060f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
1061f2728fe8SHeiher 
1062f2728fe8SHeiher 	efd[1] = epoll_create(1);
1063f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
1064f2728fe8SHeiher 
1065f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1066f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
1067f2728fe8SHeiher 
1068f2728fe8SHeiher 	e.events = EPOLLIN;
1069f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
1070f2728fe8SHeiher 
1071f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
1072f2728fe8SHeiher 
1073f2728fe8SHeiher 	pfd.fd = efd[0];
1074f2728fe8SHeiher 	pfd.events = POLLIN;
1075f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
1076f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
1077f2728fe8SHeiher 
1078f2728fe8SHeiher 	pfd.fd = efd[0];
1079f2728fe8SHeiher 	pfd.events = POLLIN;
1080f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
1081f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
1082f2728fe8SHeiher 
1083f2728fe8SHeiher 	close(efd[0]);
1084f2728fe8SHeiher 	close(efd[1]);
1085f2728fe8SHeiher 	close(sfd[0]);
1086f2728fe8SHeiher 	close(sfd[1]);
1087f2728fe8SHeiher }
1088f2728fe8SHeiher 
1089f2728fe8SHeiher /*
1090f2728fe8SHeiher  *          t0
1091f2728fe8SHeiher  *           | (p)
1092f2728fe8SHeiher  *          e0
1093f2728fe8SHeiher  *           | (et)
1094f2728fe8SHeiher  *          e1
1095f2728fe8SHeiher  *           | (lt)
1096f2728fe8SHeiher  *          s0
1097f2728fe8SHeiher  */
TEST(epoll23)1098f2728fe8SHeiher TEST(epoll23)
1099f2728fe8SHeiher {
1100f2728fe8SHeiher 	int efd[2];
1101f2728fe8SHeiher 	int sfd[2];
1102f2728fe8SHeiher 	struct pollfd pfd;
1103f2728fe8SHeiher 	struct epoll_event e;
1104f2728fe8SHeiher 
1105f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
1106f2728fe8SHeiher 
1107f2728fe8SHeiher 	efd[0] = epoll_create(1);
1108f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
1109f2728fe8SHeiher 
1110f2728fe8SHeiher 	efd[1] = epoll_create(1);
1111f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
1112f2728fe8SHeiher 
1113f2728fe8SHeiher 	e.events = EPOLLIN;
1114f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
1115f2728fe8SHeiher 
1116f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1117f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
1118f2728fe8SHeiher 
1119f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
1120f2728fe8SHeiher 
1121f2728fe8SHeiher 	pfd.fd = efd[0];
1122f2728fe8SHeiher 	pfd.events = POLLIN;
1123f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
1124f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
1125f2728fe8SHeiher 
1126f2728fe8SHeiher 	pfd.fd = efd[0];
1127f2728fe8SHeiher 	pfd.events = POLLIN;
1128f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 0);
1129f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 0);
1130f2728fe8SHeiher 
1131f2728fe8SHeiher 	close(efd[0]);
1132f2728fe8SHeiher 	close(efd[1]);
1133f2728fe8SHeiher 	close(sfd[0]);
1134f2728fe8SHeiher 	close(sfd[1]);
1135f2728fe8SHeiher }
1136f2728fe8SHeiher 
1137f2728fe8SHeiher /*
1138f2728fe8SHeiher  *          t0
1139f2728fe8SHeiher  *           | (p)
1140f2728fe8SHeiher  *          e0
1141f2728fe8SHeiher  *           | (et)
1142f2728fe8SHeiher  *          e1
1143f2728fe8SHeiher  *           | (et)
1144f2728fe8SHeiher  *          s0
1145f2728fe8SHeiher  */
TEST(epoll24)1146f2728fe8SHeiher TEST(epoll24)
1147f2728fe8SHeiher {
1148f2728fe8SHeiher 	int efd[2];
1149f2728fe8SHeiher 	int sfd[2];
1150f2728fe8SHeiher 	struct pollfd pfd;
1151f2728fe8SHeiher 	struct epoll_event e;
1152f2728fe8SHeiher 
1153f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
1154f2728fe8SHeiher 
1155f2728fe8SHeiher 	efd[0] = epoll_create(1);
1156f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
1157f2728fe8SHeiher 
1158f2728fe8SHeiher 	efd[1] = epoll_create(1);
1159f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
1160f2728fe8SHeiher 
1161f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1162f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], &e), 0);
1163f2728fe8SHeiher 
1164f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1165f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], &e), 0);
1166f2728fe8SHeiher 
1167f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
1168f2728fe8SHeiher 
1169f2728fe8SHeiher 	pfd.fd = efd[0];
1170f2728fe8SHeiher 	pfd.events = POLLIN;
1171f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
1172f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 1);
1173f2728fe8SHeiher 
1174f2728fe8SHeiher 	pfd.fd = efd[0];
1175f2728fe8SHeiher 	pfd.events = POLLIN;
1176f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 0);
1177f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], &e, 1, 0), 0);
1178f2728fe8SHeiher 
1179f2728fe8SHeiher 	close(efd[0]);
1180f2728fe8SHeiher 	close(efd[1]);
1181f2728fe8SHeiher 	close(sfd[0]);
1182f2728fe8SHeiher 	close(sfd[1]);
1183f2728fe8SHeiher }
1184f2728fe8SHeiher 
1185f2728fe8SHeiher /*
1186f2728fe8SHeiher  *        t0    t1
1187f2728fe8SHeiher  *     (ew) \  / (ew)
1188f2728fe8SHeiher  *           e0
1189f2728fe8SHeiher  *            | (lt)
1190f2728fe8SHeiher  *           e1
1191f2728fe8SHeiher  *            | (lt)
1192f2728fe8SHeiher  *           s0
1193f2728fe8SHeiher  */
TEST(epoll25)1194f2728fe8SHeiher TEST(epoll25)
1195f2728fe8SHeiher {
1196f2728fe8SHeiher 	pthread_t emitter;
1197f2728fe8SHeiher 	struct epoll_event e;
1198f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1199f2728fe8SHeiher 
1200f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1201f2728fe8SHeiher 
1202f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1203f2728fe8SHeiher 
1204f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1205f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1206f2728fe8SHeiher 
1207f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1208f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1209f2728fe8SHeiher 
1210f2728fe8SHeiher 	e.events = EPOLLIN;
1211f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1212f2728fe8SHeiher 
1213f2728fe8SHeiher 	e.events = EPOLLIN;
1214f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1215f2728fe8SHeiher 
1216f2728fe8SHeiher 	ctx.main = pthread_self();
1217f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
1218f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1219f2728fe8SHeiher 
1220f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
1221f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
1222f2728fe8SHeiher 
1223f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1224f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
1225f2728fe8SHeiher 
1226f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1227f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1228f2728fe8SHeiher 		pthread_join(emitter, NULL);
1229f2728fe8SHeiher 	}
1230f2728fe8SHeiher 
1231f2728fe8SHeiher 	close(ctx.efd[0]);
1232f2728fe8SHeiher 	close(ctx.efd[1]);
1233f2728fe8SHeiher 	close(ctx.sfd[0]);
1234f2728fe8SHeiher 	close(ctx.sfd[1]);
1235f2728fe8SHeiher }
1236f2728fe8SHeiher 
1237f2728fe8SHeiher /*
1238f2728fe8SHeiher  *        t0    t1
1239f2728fe8SHeiher  *     (ew) \  / (ew)
1240f2728fe8SHeiher  *           e0
1241f2728fe8SHeiher  *            | (lt)
1242f2728fe8SHeiher  *           e1
1243f2728fe8SHeiher  *            | (et)
1244f2728fe8SHeiher  *           s0
1245f2728fe8SHeiher  */
TEST(epoll26)1246f2728fe8SHeiher TEST(epoll26)
1247f2728fe8SHeiher {
1248f2728fe8SHeiher 	pthread_t emitter;
1249f2728fe8SHeiher 	struct epoll_event e;
1250f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1251f2728fe8SHeiher 
1252f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1253f2728fe8SHeiher 
1254f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1255f2728fe8SHeiher 
1256f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1257f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1258f2728fe8SHeiher 
1259f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1260f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1261f2728fe8SHeiher 
1262f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1263f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1264f2728fe8SHeiher 
1265f2728fe8SHeiher 	e.events = EPOLLIN;
1266f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1267f2728fe8SHeiher 
1268f2728fe8SHeiher 	ctx.main = pthread_self();
1269f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
1270f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1271f2728fe8SHeiher 
1272f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
1273f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
1274f2728fe8SHeiher 
1275f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1276f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
1277f2728fe8SHeiher 
1278f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1279f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1280f2728fe8SHeiher 		pthread_join(emitter, NULL);
1281f2728fe8SHeiher 	}
1282f2728fe8SHeiher 
1283f2728fe8SHeiher 	close(ctx.efd[0]);
1284f2728fe8SHeiher 	close(ctx.efd[1]);
1285f2728fe8SHeiher 	close(ctx.sfd[0]);
1286f2728fe8SHeiher 	close(ctx.sfd[1]);
1287f2728fe8SHeiher }
1288f2728fe8SHeiher 
1289f2728fe8SHeiher /*
1290f2728fe8SHeiher  *        t0    t1
1291f2728fe8SHeiher  *     (ew) \  / (ew)
1292f2728fe8SHeiher  *           e0
1293f2728fe8SHeiher  *            | (et)
1294f2728fe8SHeiher  *           e1
1295f2728fe8SHeiher  *            | (lt)
1296f2728fe8SHeiher  *           s0
1297f2728fe8SHeiher  */
TEST(epoll27)1298f2728fe8SHeiher TEST(epoll27)
1299f2728fe8SHeiher {
1300f2728fe8SHeiher 	pthread_t emitter;
1301f2728fe8SHeiher 	struct epoll_event e;
1302f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1303f2728fe8SHeiher 
1304f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1305f2728fe8SHeiher 
1306f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1307f2728fe8SHeiher 
1308f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1309f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1310f2728fe8SHeiher 
1311f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1312f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1313f2728fe8SHeiher 
1314f2728fe8SHeiher 	e.events = EPOLLIN;
1315f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1316f2728fe8SHeiher 
1317f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1318f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1319f2728fe8SHeiher 
1320f2728fe8SHeiher 	ctx.main = pthread_self();
1321f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
1322f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1323f2728fe8SHeiher 
1324f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
1325f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
1326f2728fe8SHeiher 
1327f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1328f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 1);
1329f2728fe8SHeiher 
1330f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1331f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1332f2728fe8SHeiher 		pthread_join(emitter, NULL);
1333f2728fe8SHeiher 	}
1334f2728fe8SHeiher 
1335f2728fe8SHeiher 	close(ctx.efd[0]);
1336f2728fe8SHeiher 	close(ctx.efd[1]);
1337f2728fe8SHeiher 	close(ctx.sfd[0]);
1338f2728fe8SHeiher 	close(ctx.sfd[1]);
1339f2728fe8SHeiher }
1340f2728fe8SHeiher 
1341f2728fe8SHeiher /*
1342f2728fe8SHeiher  *        t0    t1
1343f2728fe8SHeiher  *     (ew) \  / (ew)
1344f2728fe8SHeiher  *           e0
1345f2728fe8SHeiher  *            | (et)
1346f2728fe8SHeiher  *           e1
1347f2728fe8SHeiher  *            | (et)
1348f2728fe8SHeiher  *           s0
1349f2728fe8SHeiher  */
TEST(epoll28)1350f2728fe8SHeiher TEST(epoll28)
1351f2728fe8SHeiher {
1352f2728fe8SHeiher 	pthread_t emitter;
1353f2728fe8SHeiher 	struct epoll_event e;
1354f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1355f2728fe8SHeiher 
1356f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1357f2728fe8SHeiher 
1358f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1359f2728fe8SHeiher 
1360f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1361f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1362f2728fe8SHeiher 
1363f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1364f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1365f2728fe8SHeiher 
1366f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1367f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1368f2728fe8SHeiher 
1369f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1370f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1371f2728fe8SHeiher 
1372f2728fe8SHeiher 	ctx.main = pthread_self();
1373f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
1374f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1375f2728fe8SHeiher 
1376f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
1377f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
1378f2728fe8SHeiher 
1379f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1380f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 1);
1381f2728fe8SHeiher 
1382f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1383f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1384f2728fe8SHeiher 		pthread_join(emitter, NULL);
1385f2728fe8SHeiher 	}
1386f2728fe8SHeiher 
1387f2728fe8SHeiher 	close(ctx.efd[0]);
1388f2728fe8SHeiher 	close(ctx.efd[1]);
1389f2728fe8SHeiher 	close(ctx.sfd[0]);
1390f2728fe8SHeiher 	close(ctx.sfd[1]);
1391f2728fe8SHeiher }
1392f2728fe8SHeiher 
1393f2728fe8SHeiher /*
1394f2728fe8SHeiher  *        t0    t1
1395f2728fe8SHeiher  *     (ew) \  / (p)
1396f2728fe8SHeiher  *           e0
1397f2728fe8SHeiher  *            | (lt)
1398f2728fe8SHeiher  *           e1
1399f2728fe8SHeiher  *            | (lt)
1400f2728fe8SHeiher  *           s0
1401f2728fe8SHeiher  */
TEST(epoll29)1402f2728fe8SHeiher TEST(epoll29)
1403f2728fe8SHeiher {
1404f2728fe8SHeiher 	pthread_t emitter;
1405f2728fe8SHeiher 	struct epoll_event e;
1406f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1407f2728fe8SHeiher 
1408f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1409f2728fe8SHeiher 
1410f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1411f2728fe8SHeiher 
1412f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1413f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1414f2728fe8SHeiher 
1415f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1416f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1417f2728fe8SHeiher 
1418f2728fe8SHeiher 	e.events = EPOLLIN;
1419f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1420f2728fe8SHeiher 
1421f2728fe8SHeiher 	e.events = EPOLLIN;
1422f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1423f2728fe8SHeiher 
1424f2728fe8SHeiher 	ctx.main = pthread_self();
1425f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
1426f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1427f2728fe8SHeiher 
1428f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
1429f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
1430f2728fe8SHeiher 
1431f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1432f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
1433f2728fe8SHeiher 
1434f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1435f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1436f2728fe8SHeiher 		pthread_join(emitter, NULL);
1437f2728fe8SHeiher 	}
1438f2728fe8SHeiher 
1439f2728fe8SHeiher 	close(ctx.efd[0]);
1440f2728fe8SHeiher 	close(ctx.sfd[0]);
1441f2728fe8SHeiher 	close(ctx.sfd[1]);
1442f2728fe8SHeiher }
1443f2728fe8SHeiher 
1444f2728fe8SHeiher /*
1445f2728fe8SHeiher  *        t0    t1
1446f2728fe8SHeiher  *     (ew) \  / (p)
1447f2728fe8SHeiher  *           e0
1448f2728fe8SHeiher  *            | (lt)
1449f2728fe8SHeiher  *           e1
1450f2728fe8SHeiher  *            | (et)
1451f2728fe8SHeiher  *           s0
1452f2728fe8SHeiher  */
TEST(epoll30)1453f2728fe8SHeiher TEST(epoll30)
1454f2728fe8SHeiher {
1455f2728fe8SHeiher 	pthread_t emitter;
1456f2728fe8SHeiher 	struct epoll_event e;
1457f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1458f2728fe8SHeiher 
1459f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1460f2728fe8SHeiher 
1461f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1462f2728fe8SHeiher 
1463f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1464f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1465f2728fe8SHeiher 
1466f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1467f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1468f2728fe8SHeiher 
1469f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1470f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1471f2728fe8SHeiher 
1472f2728fe8SHeiher 	e.events = EPOLLIN;
1473f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1474f2728fe8SHeiher 
1475f2728fe8SHeiher 	ctx.main = pthread_self();
1476f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
1477f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1478f2728fe8SHeiher 
1479f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
1480f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
1481f2728fe8SHeiher 
1482f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1483f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
1484f2728fe8SHeiher 
1485f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1486f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1487f2728fe8SHeiher 		pthread_join(emitter, NULL);
1488f2728fe8SHeiher 	}
1489f2728fe8SHeiher 
1490f2728fe8SHeiher 	close(ctx.efd[0]);
1491f2728fe8SHeiher 	close(ctx.sfd[0]);
1492f2728fe8SHeiher 	close(ctx.sfd[1]);
1493f2728fe8SHeiher }
1494f2728fe8SHeiher 
1495f2728fe8SHeiher /*
1496f2728fe8SHeiher  *        t0    t1
1497f2728fe8SHeiher  *     (ew) \  / (p)
1498f2728fe8SHeiher  *           e0
1499f2728fe8SHeiher  *            | (et)
1500f2728fe8SHeiher  *           e1
1501f2728fe8SHeiher  *            | (lt)
1502f2728fe8SHeiher  *           s0
1503f2728fe8SHeiher  */
TEST(epoll31)1504f2728fe8SHeiher TEST(epoll31)
1505f2728fe8SHeiher {
1506f2728fe8SHeiher 	pthread_t emitter;
1507f2728fe8SHeiher 	struct epoll_event e;
1508f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1509f2728fe8SHeiher 
1510f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1511f2728fe8SHeiher 
1512f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1513f2728fe8SHeiher 
1514f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1515f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1516f2728fe8SHeiher 
1517f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1518f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1519f2728fe8SHeiher 
1520f2728fe8SHeiher 	e.events = EPOLLIN;
1521f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1522f2728fe8SHeiher 
1523f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1524f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1525f2728fe8SHeiher 
1526f2728fe8SHeiher 	ctx.main = pthread_self();
1527f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
1528f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1529f2728fe8SHeiher 
1530f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
1531f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
1532f2728fe8SHeiher 
1533f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1534f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 1);
1535f2728fe8SHeiher 
1536f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1537f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1538f2728fe8SHeiher 		pthread_join(emitter, NULL);
1539f2728fe8SHeiher 	}
1540f2728fe8SHeiher 
1541f2728fe8SHeiher 	close(ctx.efd[0]);
1542f2728fe8SHeiher 	close(ctx.sfd[0]);
1543f2728fe8SHeiher 	close(ctx.sfd[1]);
1544f2728fe8SHeiher }
1545f2728fe8SHeiher 
1546f2728fe8SHeiher /*
1547f2728fe8SHeiher  *        t0    t1
1548f2728fe8SHeiher  *     (ew) \  / (p)
1549f2728fe8SHeiher  *           e0
1550f2728fe8SHeiher  *            | (et)
1551f2728fe8SHeiher  *           e1
1552f2728fe8SHeiher  *            | (et)
1553f2728fe8SHeiher  *           s0
1554f2728fe8SHeiher  */
TEST(epoll32)1555f2728fe8SHeiher TEST(epoll32)
1556f2728fe8SHeiher {
1557f2728fe8SHeiher 	pthread_t emitter;
1558f2728fe8SHeiher 	struct epoll_event e;
1559f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1560f2728fe8SHeiher 
1561f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1562f2728fe8SHeiher 
1563f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1564f2728fe8SHeiher 
1565f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1566f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1567f2728fe8SHeiher 
1568f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1569f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1570f2728fe8SHeiher 
1571f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1572f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1573f2728fe8SHeiher 
1574f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1575f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1576f2728fe8SHeiher 
1577f2728fe8SHeiher 	ctx.main = pthread_self();
1578f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
1579f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1580f2728fe8SHeiher 
1581f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
1582f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
1583f2728fe8SHeiher 
1584f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1585f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 1);
1586f2728fe8SHeiher 
1587f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1588f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1589f2728fe8SHeiher 		pthread_join(emitter, NULL);
1590f2728fe8SHeiher 	}
1591f2728fe8SHeiher 
1592f2728fe8SHeiher 	close(ctx.efd[0]);
1593f2728fe8SHeiher 	close(ctx.sfd[0]);
1594f2728fe8SHeiher 	close(ctx.sfd[1]);
1595f2728fe8SHeiher }
1596f2728fe8SHeiher 
1597f2728fe8SHeiher /*
1598f2728fe8SHeiher  *        t0   t1
1599f2728fe8SHeiher  *    (ew) |    | (ew)
1600f2728fe8SHeiher  *         |   e0
1601f2728fe8SHeiher  *          \  / (lt)
1602f2728fe8SHeiher  *           e1
1603f2728fe8SHeiher  *            | (lt)
1604f2728fe8SHeiher  *           s0
1605f2728fe8SHeiher  */
TEST(epoll33)1606f2728fe8SHeiher TEST(epoll33)
1607f2728fe8SHeiher {
1608f2728fe8SHeiher 	pthread_t emitter;
1609f2728fe8SHeiher 	struct epoll_event e;
1610f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1611f2728fe8SHeiher 
1612f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1613f2728fe8SHeiher 
1614f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1615f2728fe8SHeiher 
1616f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1617f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1618f2728fe8SHeiher 
1619f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1620f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1621f2728fe8SHeiher 
1622f2728fe8SHeiher 	e.events = EPOLLIN;
1623f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1624f2728fe8SHeiher 
1625f2728fe8SHeiher 	e.events = EPOLLIN;
1626f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1627f2728fe8SHeiher 
1628f2728fe8SHeiher 	ctx.main = pthread_self();
1629f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
1630f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1631f2728fe8SHeiher 
1632f2728fe8SHeiher 	if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
1633f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
1634f2728fe8SHeiher 
1635f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1636f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
1637f2728fe8SHeiher 
1638f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1639f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1640f2728fe8SHeiher 		pthread_join(emitter, NULL);
1641f2728fe8SHeiher 	}
1642f2728fe8SHeiher 
1643f2728fe8SHeiher 	close(ctx.efd[0]);
1644f2728fe8SHeiher 	close(ctx.efd[1]);
1645f2728fe8SHeiher 	close(ctx.sfd[0]);
1646f2728fe8SHeiher 	close(ctx.sfd[1]);
1647f2728fe8SHeiher }
1648f2728fe8SHeiher 
1649f2728fe8SHeiher /*
1650f2728fe8SHeiher  *        t0   t1
1651f2728fe8SHeiher  *    (ew) |    | (ew)
1652f2728fe8SHeiher  *         |   e0
1653f2728fe8SHeiher  *          \  / (lt)
1654f2728fe8SHeiher  *           e1
1655f2728fe8SHeiher  *            | (et)
1656f2728fe8SHeiher  *           s0
1657f2728fe8SHeiher  */
TEST(epoll34)1658f2728fe8SHeiher TEST(epoll34)
1659f2728fe8SHeiher {
1660f2728fe8SHeiher 	pthread_t emitter;
1661f2728fe8SHeiher 	struct epoll_event e;
1662f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1663f2728fe8SHeiher 
1664f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1665f2728fe8SHeiher 
1666f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1667f2728fe8SHeiher 
1668f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1669f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1670f2728fe8SHeiher 
1671f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1672f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1673f2728fe8SHeiher 
1674f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1675f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1676f2728fe8SHeiher 
1677f2728fe8SHeiher 	e.events = EPOLLIN;
1678f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1679f2728fe8SHeiher 
1680f2728fe8SHeiher 	ctx.main = pthread_self();
1681f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1o, &ctx), 0);
1682f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1683f2728fe8SHeiher 
1684f2728fe8SHeiher 	if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
1685f2728fe8SHeiher 		__sync_fetch_and_or(&ctx.count, 2);
1686f2728fe8SHeiher 
1687f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1688f2728fe8SHeiher 	EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
1689f2728fe8SHeiher 
1690f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1691f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1692f2728fe8SHeiher 		pthread_join(emitter, NULL);
1693f2728fe8SHeiher 	}
1694f2728fe8SHeiher 
1695f2728fe8SHeiher 	close(ctx.efd[0]);
1696f2728fe8SHeiher 	close(ctx.efd[1]);
1697f2728fe8SHeiher 	close(ctx.sfd[0]);
1698f2728fe8SHeiher 	close(ctx.sfd[1]);
1699f2728fe8SHeiher }
1700f2728fe8SHeiher 
1701f2728fe8SHeiher /*
1702f2728fe8SHeiher  *        t0   t1
1703f2728fe8SHeiher  *    (ew) |    | (ew)
1704f2728fe8SHeiher  *         |   e0
1705f2728fe8SHeiher  *          \  / (et)
1706f2728fe8SHeiher  *           e1
1707f2728fe8SHeiher  *            | (lt)
1708f2728fe8SHeiher  *           s0
1709f2728fe8SHeiher  */
TEST(epoll35)1710f2728fe8SHeiher TEST(epoll35)
1711f2728fe8SHeiher {
1712f2728fe8SHeiher 	pthread_t emitter;
1713f2728fe8SHeiher 	struct epoll_event e;
1714f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1715f2728fe8SHeiher 
1716f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1717f2728fe8SHeiher 
1718f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1719f2728fe8SHeiher 
1720f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1721f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1722f2728fe8SHeiher 
1723f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1724f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1725f2728fe8SHeiher 
1726f2728fe8SHeiher 	e.events = EPOLLIN;
1727f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1728f2728fe8SHeiher 
1729f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1730f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1731f2728fe8SHeiher 
1732f2728fe8SHeiher 	ctx.main = pthread_self();
1733f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
1734f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1735f2728fe8SHeiher 
1736f2728fe8SHeiher 	if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
1737f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
1738f2728fe8SHeiher 
1739f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1740f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
1741f2728fe8SHeiher 
1742f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1743f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1744f2728fe8SHeiher 		pthread_join(emitter, NULL);
1745f2728fe8SHeiher 	}
1746f2728fe8SHeiher 
1747f2728fe8SHeiher 	close(ctx.efd[0]);
1748f2728fe8SHeiher 	close(ctx.efd[1]);
1749f2728fe8SHeiher 	close(ctx.sfd[0]);
1750f2728fe8SHeiher 	close(ctx.sfd[1]);
1751f2728fe8SHeiher }
1752f2728fe8SHeiher 
1753f2728fe8SHeiher /*
1754f2728fe8SHeiher  *        t0   t1
1755f2728fe8SHeiher  *    (ew) |    | (ew)
1756f2728fe8SHeiher  *         |   e0
1757f2728fe8SHeiher  *          \  / (et)
1758f2728fe8SHeiher  *           e1
1759f2728fe8SHeiher  *            | (et)
1760f2728fe8SHeiher  *           s0
1761f2728fe8SHeiher  */
TEST(epoll36)1762f2728fe8SHeiher TEST(epoll36)
1763f2728fe8SHeiher {
1764f2728fe8SHeiher 	pthread_t emitter;
1765f2728fe8SHeiher 	struct epoll_event e;
1766f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1767f2728fe8SHeiher 
1768f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1769f2728fe8SHeiher 
1770f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1771f2728fe8SHeiher 
1772f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1773f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1774f2728fe8SHeiher 
1775f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1776f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1777f2728fe8SHeiher 
1778f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1779f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1780f2728fe8SHeiher 
1781f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1782f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1783f2728fe8SHeiher 
1784f2728fe8SHeiher 	ctx.main = pthread_self();
1785f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1o, &ctx), 0);
1786f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1787f2728fe8SHeiher 
1788f2728fe8SHeiher 	if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
1789f2728fe8SHeiher 		__sync_fetch_and_or(&ctx.count, 2);
1790f2728fe8SHeiher 
1791f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1792f2728fe8SHeiher 	EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
1793f2728fe8SHeiher 
1794f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1795f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1796f2728fe8SHeiher 		pthread_join(emitter, NULL);
1797f2728fe8SHeiher 	}
1798f2728fe8SHeiher 
1799f2728fe8SHeiher 	close(ctx.efd[0]);
1800f2728fe8SHeiher 	close(ctx.efd[1]);
1801f2728fe8SHeiher 	close(ctx.sfd[0]);
1802f2728fe8SHeiher 	close(ctx.sfd[1]);
1803f2728fe8SHeiher }
1804f2728fe8SHeiher 
1805f2728fe8SHeiher /*
1806f2728fe8SHeiher  *        t0   t1
1807f2728fe8SHeiher  *     (p) |    | (ew)
1808f2728fe8SHeiher  *         |   e0
1809f2728fe8SHeiher  *          \  / (lt)
1810f2728fe8SHeiher  *           e1
1811f2728fe8SHeiher  *            | (lt)
1812f2728fe8SHeiher  *           s0
1813f2728fe8SHeiher  */
TEST(epoll37)1814f2728fe8SHeiher TEST(epoll37)
1815f2728fe8SHeiher {
1816f2728fe8SHeiher 	pthread_t emitter;
1817f2728fe8SHeiher 	struct pollfd pfd;
1818f2728fe8SHeiher 	struct epoll_event e;
1819f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1820f2728fe8SHeiher 
1821f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1822f2728fe8SHeiher 
1823f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1824f2728fe8SHeiher 
1825f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1826f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1827f2728fe8SHeiher 
1828f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1829f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1830f2728fe8SHeiher 
1831f2728fe8SHeiher 	e.events = EPOLLIN;
1832f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1833f2728fe8SHeiher 
1834f2728fe8SHeiher 	e.events = EPOLLIN;
1835f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1836f2728fe8SHeiher 
1837f2728fe8SHeiher 	ctx.main = pthread_self();
1838f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
1839f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1840f2728fe8SHeiher 
1841f2728fe8SHeiher 	pfd.fd = ctx.efd[1];
1842f2728fe8SHeiher 	pfd.events = POLLIN;
1843f2728fe8SHeiher 	if (poll(&pfd, 1, -1) > 0) {
1844f2728fe8SHeiher 		if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
1845f2728fe8SHeiher 			__sync_fetch_and_add(&ctx.count, 1);
1846f2728fe8SHeiher 	}
1847f2728fe8SHeiher 
1848f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1849f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
1850f2728fe8SHeiher 
1851f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1852f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1853f2728fe8SHeiher 		pthread_join(emitter, NULL);
1854f2728fe8SHeiher 	}
1855f2728fe8SHeiher 
1856f2728fe8SHeiher 	close(ctx.efd[0]);
1857f2728fe8SHeiher 	close(ctx.efd[1]);
1858f2728fe8SHeiher 	close(ctx.sfd[0]);
1859f2728fe8SHeiher 	close(ctx.sfd[1]);
1860f2728fe8SHeiher }
1861f2728fe8SHeiher 
1862f2728fe8SHeiher /*
1863f2728fe8SHeiher  *        t0   t1
1864f2728fe8SHeiher  *     (p) |    | (ew)
1865f2728fe8SHeiher  *         |   e0
1866f2728fe8SHeiher  *          \  / (lt)
1867f2728fe8SHeiher  *           e1
1868f2728fe8SHeiher  *            | (et)
1869f2728fe8SHeiher  *           s0
1870f2728fe8SHeiher  */
TEST(epoll38)1871f2728fe8SHeiher TEST(epoll38)
1872f2728fe8SHeiher {
1873f2728fe8SHeiher 	pthread_t emitter;
1874f2728fe8SHeiher 	struct pollfd pfd;
1875f2728fe8SHeiher 	struct epoll_event e;
1876f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1877f2728fe8SHeiher 
1878f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1879f2728fe8SHeiher 
1880f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1881f2728fe8SHeiher 
1882f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1883f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1884f2728fe8SHeiher 
1885f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1886f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1887f2728fe8SHeiher 
1888f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1889f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1890f2728fe8SHeiher 
1891f2728fe8SHeiher 	e.events = EPOLLIN;
1892f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1893f2728fe8SHeiher 
1894f2728fe8SHeiher 	ctx.main = pthread_self();
1895f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1o, &ctx), 0);
1896f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1897f2728fe8SHeiher 
1898f2728fe8SHeiher 	pfd.fd = ctx.efd[1];
1899f2728fe8SHeiher 	pfd.events = POLLIN;
1900f2728fe8SHeiher 	if (poll(&pfd, 1, -1) > 0) {
1901f2728fe8SHeiher 		if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
1902f2728fe8SHeiher 			__sync_fetch_and_or(&ctx.count, 2);
1903f2728fe8SHeiher 	}
1904f2728fe8SHeiher 
1905f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1906f2728fe8SHeiher 	EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
1907f2728fe8SHeiher 
1908f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1909f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1910f2728fe8SHeiher 		pthread_join(emitter, NULL);
1911f2728fe8SHeiher 	}
1912f2728fe8SHeiher 
1913f2728fe8SHeiher 	close(ctx.efd[0]);
1914f2728fe8SHeiher 	close(ctx.efd[1]);
1915f2728fe8SHeiher 	close(ctx.sfd[0]);
1916f2728fe8SHeiher 	close(ctx.sfd[1]);
1917f2728fe8SHeiher }
1918f2728fe8SHeiher 
1919f2728fe8SHeiher /*
1920f2728fe8SHeiher  *        t0   t1
1921f2728fe8SHeiher  *     (p) |    | (ew)
1922f2728fe8SHeiher  *         |   e0
1923f2728fe8SHeiher  *          \  / (et)
1924f2728fe8SHeiher  *           e1
1925f2728fe8SHeiher  *            | (lt)
1926f2728fe8SHeiher  *           s0
1927f2728fe8SHeiher  */
TEST(epoll39)1928f2728fe8SHeiher TEST(epoll39)
1929f2728fe8SHeiher {
1930f2728fe8SHeiher 	pthread_t emitter;
1931f2728fe8SHeiher 	struct pollfd pfd;
1932f2728fe8SHeiher 	struct epoll_event e;
1933f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1934f2728fe8SHeiher 
1935f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1936f2728fe8SHeiher 
1937f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1938f2728fe8SHeiher 
1939f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1940f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1941f2728fe8SHeiher 
1942f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
1943f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
1944f2728fe8SHeiher 
1945f2728fe8SHeiher 	e.events = EPOLLIN;
1946f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
1947f2728fe8SHeiher 
1948f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
1949f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
1950f2728fe8SHeiher 
1951f2728fe8SHeiher 	ctx.main = pthread_self();
1952f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
1953f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
1954f2728fe8SHeiher 
1955f2728fe8SHeiher 	pfd.fd = ctx.efd[1];
1956f2728fe8SHeiher 	pfd.events = POLLIN;
1957f2728fe8SHeiher 	if (poll(&pfd, 1, -1) > 0) {
1958f2728fe8SHeiher 		if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
1959f2728fe8SHeiher 			__sync_fetch_and_add(&ctx.count, 1);
1960f2728fe8SHeiher 	}
1961f2728fe8SHeiher 
1962f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
1963f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
1964f2728fe8SHeiher 
1965f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
1966f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
1967f2728fe8SHeiher 		pthread_join(emitter, NULL);
1968f2728fe8SHeiher 	}
1969f2728fe8SHeiher 
1970f2728fe8SHeiher 	close(ctx.efd[0]);
1971f2728fe8SHeiher 	close(ctx.efd[1]);
1972f2728fe8SHeiher 	close(ctx.sfd[0]);
1973f2728fe8SHeiher 	close(ctx.sfd[1]);
1974f2728fe8SHeiher }
1975f2728fe8SHeiher 
1976f2728fe8SHeiher /*
1977f2728fe8SHeiher  *        t0   t1
1978f2728fe8SHeiher  *     (p) |    | (ew)
1979f2728fe8SHeiher  *         |   e0
1980f2728fe8SHeiher  *          \  / (et)
1981f2728fe8SHeiher  *           e1
1982f2728fe8SHeiher  *            | (et)
1983f2728fe8SHeiher  *           s0
1984f2728fe8SHeiher  */
TEST(epoll40)1985f2728fe8SHeiher TEST(epoll40)
1986f2728fe8SHeiher {
1987f2728fe8SHeiher 	pthread_t emitter;
1988f2728fe8SHeiher 	struct pollfd pfd;
1989f2728fe8SHeiher 	struct epoll_event e;
1990f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
1991f2728fe8SHeiher 
1992f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
1993f2728fe8SHeiher 
1994f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
1995f2728fe8SHeiher 
1996f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
1997f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
1998f2728fe8SHeiher 
1999f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2000f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2001f2728fe8SHeiher 
2002f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2003f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2004f2728fe8SHeiher 
2005f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2006f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2007f2728fe8SHeiher 
2008f2728fe8SHeiher 	ctx.main = pthread_self();
2009f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1o, &ctx), 0);
2010f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
2011f2728fe8SHeiher 
2012f2728fe8SHeiher 	pfd.fd = ctx.efd[1];
2013f2728fe8SHeiher 	pfd.events = POLLIN;
2014f2728fe8SHeiher 	if (poll(&pfd, 1, -1) > 0) {
2015f2728fe8SHeiher 		if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
2016f2728fe8SHeiher 			__sync_fetch_and_or(&ctx.count, 2);
2017f2728fe8SHeiher 	}
2018f2728fe8SHeiher 
2019f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2020f2728fe8SHeiher 	EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
2021f2728fe8SHeiher 
2022f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2023f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2024f2728fe8SHeiher 		pthread_join(emitter, NULL);
2025f2728fe8SHeiher 	}
2026f2728fe8SHeiher 
2027f2728fe8SHeiher 	close(ctx.efd[0]);
2028f2728fe8SHeiher 	close(ctx.efd[1]);
2029f2728fe8SHeiher 	close(ctx.sfd[0]);
2030f2728fe8SHeiher 	close(ctx.sfd[1]);
2031f2728fe8SHeiher }
2032f2728fe8SHeiher 
2033f2728fe8SHeiher /*
2034f2728fe8SHeiher  *        t0   t1
2035f2728fe8SHeiher  *    (ew) |    | (p)
2036f2728fe8SHeiher  *         |   e0
2037f2728fe8SHeiher  *          \  / (lt)
2038f2728fe8SHeiher  *           e1
2039f2728fe8SHeiher  *            | (lt)
2040f2728fe8SHeiher  *           s0
2041f2728fe8SHeiher  */
TEST(epoll41)2042f2728fe8SHeiher TEST(epoll41)
2043f2728fe8SHeiher {
2044f2728fe8SHeiher 	pthread_t emitter;
2045f2728fe8SHeiher 	struct epoll_event e;
2046f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2047f2728fe8SHeiher 
2048f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2049f2728fe8SHeiher 
2050f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
2051f2728fe8SHeiher 
2052f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2053f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2054f2728fe8SHeiher 
2055f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2056f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2057f2728fe8SHeiher 
2058f2728fe8SHeiher 	e.events = EPOLLIN;
2059f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2060f2728fe8SHeiher 
2061f2728fe8SHeiher 	e.events = EPOLLIN;
2062f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2063f2728fe8SHeiher 
2064f2728fe8SHeiher 	ctx.main = pthread_self();
2065f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
2066f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
2067f2728fe8SHeiher 
2068f2728fe8SHeiher 	if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
2069f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
2070f2728fe8SHeiher 
2071f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2072f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
2073f2728fe8SHeiher 
2074f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2075f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2076f2728fe8SHeiher 		pthread_join(emitter, NULL);
2077f2728fe8SHeiher 	}
2078f2728fe8SHeiher 
2079f2728fe8SHeiher 	close(ctx.efd[0]);
2080f2728fe8SHeiher 	close(ctx.efd[1]);
2081f2728fe8SHeiher 	close(ctx.sfd[0]);
2082f2728fe8SHeiher 	close(ctx.sfd[1]);
2083f2728fe8SHeiher }
2084f2728fe8SHeiher 
2085f2728fe8SHeiher /*
2086f2728fe8SHeiher  *        t0   t1
2087f2728fe8SHeiher  *    (ew) |    | (p)
2088f2728fe8SHeiher  *         |   e0
2089f2728fe8SHeiher  *          \  / (lt)
2090f2728fe8SHeiher  *           e1
2091f2728fe8SHeiher  *            | (et)
2092f2728fe8SHeiher  *           s0
2093f2728fe8SHeiher  */
TEST(epoll42)2094f2728fe8SHeiher TEST(epoll42)
2095f2728fe8SHeiher {
2096f2728fe8SHeiher 	pthread_t emitter;
2097f2728fe8SHeiher 	struct epoll_event e;
2098f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2099f2728fe8SHeiher 
2100f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2101f2728fe8SHeiher 
2102f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
2103f2728fe8SHeiher 
2104f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2105f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2106f2728fe8SHeiher 
2107f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2108f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2109f2728fe8SHeiher 
2110f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2111f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2112f2728fe8SHeiher 
2113f2728fe8SHeiher 	e.events = EPOLLIN;
2114f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2115f2728fe8SHeiher 
2116f2728fe8SHeiher 	ctx.main = pthread_self();
2117f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1op, &ctx), 0);
2118f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
2119f2728fe8SHeiher 
2120f2728fe8SHeiher 	if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
2121f2728fe8SHeiher 		__sync_fetch_and_or(&ctx.count, 2);
2122f2728fe8SHeiher 
2123f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2124f2728fe8SHeiher 	EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
2125f2728fe8SHeiher 
2126f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2127f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2128f2728fe8SHeiher 		pthread_join(emitter, NULL);
2129f2728fe8SHeiher 	}
2130f2728fe8SHeiher 
2131f2728fe8SHeiher 	close(ctx.efd[0]);
2132f2728fe8SHeiher 	close(ctx.efd[1]);
2133f2728fe8SHeiher 	close(ctx.sfd[0]);
2134f2728fe8SHeiher 	close(ctx.sfd[1]);
2135f2728fe8SHeiher }
2136f2728fe8SHeiher 
2137f2728fe8SHeiher /*
2138f2728fe8SHeiher  *        t0   t1
2139f2728fe8SHeiher  *    (ew) |    | (p)
2140f2728fe8SHeiher  *         |   e0
2141f2728fe8SHeiher  *          \  / (et)
2142f2728fe8SHeiher  *           e1
2143f2728fe8SHeiher  *            | (lt)
2144f2728fe8SHeiher  *           s0
2145f2728fe8SHeiher  */
TEST(epoll43)2146f2728fe8SHeiher TEST(epoll43)
2147f2728fe8SHeiher {
2148f2728fe8SHeiher 	pthread_t emitter;
2149f2728fe8SHeiher 	struct epoll_event e;
2150f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2151f2728fe8SHeiher 
2152f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2153f2728fe8SHeiher 
2154f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
2155f2728fe8SHeiher 
2156f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2157f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2158f2728fe8SHeiher 
2159f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2160f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2161f2728fe8SHeiher 
2162f2728fe8SHeiher 	e.events = EPOLLIN;
2163f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2164f2728fe8SHeiher 
2165f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2166f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2167f2728fe8SHeiher 
2168f2728fe8SHeiher 	ctx.main = pthread_self();
2169f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
2170f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
2171f2728fe8SHeiher 
2172f2728fe8SHeiher 	if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
2173f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
2174f2728fe8SHeiher 
2175f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2176f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
2177f2728fe8SHeiher 
2178f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2179f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2180f2728fe8SHeiher 		pthread_join(emitter, NULL);
2181f2728fe8SHeiher 	}
2182f2728fe8SHeiher 
2183f2728fe8SHeiher 	close(ctx.efd[0]);
2184f2728fe8SHeiher 	close(ctx.efd[1]);
2185f2728fe8SHeiher 	close(ctx.sfd[0]);
2186f2728fe8SHeiher 	close(ctx.sfd[1]);
2187f2728fe8SHeiher }
2188f2728fe8SHeiher 
2189f2728fe8SHeiher /*
2190f2728fe8SHeiher  *        t0   t1
2191f2728fe8SHeiher  *    (ew) |    | (p)
2192f2728fe8SHeiher  *         |   e0
2193f2728fe8SHeiher  *          \  / (et)
2194f2728fe8SHeiher  *           e1
2195f2728fe8SHeiher  *            | (et)
2196f2728fe8SHeiher  *           s0
2197f2728fe8SHeiher  */
TEST(epoll44)2198f2728fe8SHeiher TEST(epoll44)
2199f2728fe8SHeiher {
2200f2728fe8SHeiher 	pthread_t emitter;
2201f2728fe8SHeiher 	struct epoll_event e;
2202f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2203f2728fe8SHeiher 
2204f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2205f2728fe8SHeiher 
2206f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
2207f2728fe8SHeiher 
2208f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2209f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2210f2728fe8SHeiher 
2211f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2212f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2213f2728fe8SHeiher 
2214f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2215f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2216f2728fe8SHeiher 
2217f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2218f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2219f2728fe8SHeiher 
2220f2728fe8SHeiher 	ctx.main = pthread_self();
2221f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1op, &ctx), 0);
2222f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
2223f2728fe8SHeiher 
2224f2728fe8SHeiher 	if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
2225f2728fe8SHeiher 		__sync_fetch_and_or(&ctx.count, 2);
2226f2728fe8SHeiher 
2227f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2228f2728fe8SHeiher 	EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
2229f2728fe8SHeiher 
2230f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2231f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2232f2728fe8SHeiher 		pthread_join(emitter, NULL);
2233f2728fe8SHeiher 	}
2234f2728fe8SHeiher 
2235f2728fe8SHeiher 	close(ctx.efd[0]);
2236f2728fe8SHeiher 	close(ctx.efd[1]);
2237f2728fe8SHeiher 	close(ctx.sfd[0]);
2238f2728fe8SHeiher 	close(ctx.sfd[1]);
2239f2728fe8SHeiher }
2240f2728fe8SHeiher 
2241f2728fe8SHeiher /*
2242f2728fe8SHeiher  *        t0   t1
2243f2728fe8SHeiher  *     (p) |    | (p)
2244f2728fe8SHeiher  *         |   e0
2245f2728fe8SHeiher  *          \  / (lt)
2246f2728fe8SHeiher  *           e1
2247f2728fe8SHeiher  *            | (lt)
2248f2728fe8SHeiher  *           s0
2249f2728fe8SHeiher  */
TEST(epoll45)2250f2728fe8SHeiher TEST(epoll45)
2251f2728fe8SHeiher {
2252f2728fe8SHeiher 	pthread_t emitter;
2253f2728fe8SHeiher 	struct pollfd pfd;
2254f2728fe8SHeiher 	struct epoll_event e;
2255f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2256f2728fe8SHeiher 
2257f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2258f2728fe8SHeiher 
2259f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
2260f2728fe8SHeiher 
2261f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2262f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2263f2728fe8SHeiher 
2264f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2265f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2266f2728fe8SHeiher 
2267f2728fe8SHeiher 	e.events = EPOLLIN;
2268f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2269f2728fe8SHeiher 
2270f2728fe8SHeiher 	e.events = EPOLLIN;
2271f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2272f2728fe8SHeiher 
2273f2728fe8SHeiher 	ctx.main = pthread_self();
2274f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
2275f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
2276f2728fe8SHeiher 
2277f2728fe8SHeiher 	pfd.fd = ctx.efd[1];
2278f2728fe8SHeiher 	pfd.events = POLLIN;
2279f2728fe8SHeiher 	if (poll(&pfd, 1, -1) > 0) {
2280f2728fe8SHeiher 		if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
2281f2728fe8SHeiher 			__sync_fetch_and_add(&ctx.count, 1);
2282f2728fe8SHeiher 	}
2283f2728fe8SHeiher 
2284f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2285f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
2286f2728fe8SHeiher 
2287f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2288f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2289f2728fe8SHeiher 		pthread_join(emitter, NULL);
2290f2728fe8SHeiher 	}
2291f2728fe8SHeiher 
2292f2728fe8SHeiher 	close(ctx.efd[0]);
2293f2728fe8SHeiher 	close(ctx.efd[1]);
2294f2728fe8SHeiher 	close(ctx.sfd[0]);
2295f2728fe8SHeiher 	close(ctx.sfd[1]);
2296f2728fe8SHeiher }
2297f2728fe8SHeiher 
2298f2728fe8SHeiher /*
2299f2728fe8SHeiher  *        t0   t1
2300f2728fe8SHeiher  *     (p) |    | (p)
2301f2728fe8SHeiher  *         |   e0
2302f2728fe8SHeiher  *          \  / (lt)
2303f2728fe8SHeiher  *           e1
2304f2728fe8SHeiher  *            | (et)
2305f2728fe8SHeiher  *           s0
2306f2728fe8SHeiher  */
TEST(epoll46)2307f2728fe8SHeiher TEST(epoll46)
2308f2728fe8SHeiher {
2309f2728fe8SHeiher 	pthread_t emitter;
2310f2728fe8SHeiher 	struct epoll_event e;
2311f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2312f2728fe8SHeiher 
2313f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2314f2728fe8SHeiher 
2315f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
2316f2728fe8SHeiher 
2317f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2318f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2319f2728fe8SHeiher 
2320f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2321f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2322f2728fe8SHeiher 
2323f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2324f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2325f2728fe8SHeiher 
2326f2728fe8SHeiher 	e.events = EPOLLIN;
2327f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2328f2728fe8SHeiher 
2329f2728fe8SHeiher 	ctx.main = pthread_self();
2330f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1op, &ctx), 0);
2331f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
2332f2728fe8SHeiher 
2333f2728fe8SHeiher 	if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
2334f2728fe8SHeiher 		__sync_fetch_and_or(&ctx.count, 2);
2335f2728fe8SHeiher 
2336f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2337f2728fe8SHeiher 	EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
2338f2728fe8SHeiher 
2339f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2340f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2341f2728fe8SHeiher 		pthread_join(emitter, NULL);
2342f2728fe8SHeiher 	}
2343f2728fe8SHeiher 
2344f2728fe8SHeiher 	close(ctx.efd[0]);
2345f2728fe8SHeiher 	close(ctx.efd[1]);
2346f2728fe8SHeiher 	close(ctx.sfd[0]);
2347f2728fe8SHeiher 	close(ctx.sfd[1]);
2348f2728fe8SHeiher }
2349f2728fe8SHeiher 
2350f2728fe8SHeiher /*
2351f2728fe8SHeiher  *        t0   t1
2352f2728fe8SHeiher  *     (p) |    | (p)
2353f2728fe8SHeiher  *         |   e0
2354f2728fe8SHeiher  *          \  / (et)
2355f2728fe8SHeiher  *           e1
2356f2728fe8SHeiher  *            | (lt)
2357f2728fe8SHeiher  *           s0
2358f2728fe8SHeiher  */
TEST(epoll47)2359f2728fe8SHeiher TEST(epoll47)
2360f2728fe8SHeiher {
2361f2728fe8SHeiher 	pthread_t emitter;
2362f2728fe8SHeiher 	struct pollfd pfd;
2363f2728fe8SHeiher 	struct epoll_event e;
2364f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2365f2728fe8SHeiher 
2366f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2367f2728fe8SHeiher 
2368f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
2369f2728fe8SHeiher 
2370f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2371f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2372f2728fe8SHeiher 
2373f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2374f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2375f2728fe8SHeiher 
2376f2728fe8SHeiher 	e.events = EPOLLIN;
2377f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2378f2728fe8SHeiher 
2379f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2380f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2381f2728fe8SHeiher 
2382f2728fe8SHeiher 	ctx.main = pthread_self();
2383f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
2384f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
2385f2728fe8SHeiher 
2386f2728fe8SHeiher 	pfd.fd = ctx.efd[1];
2387f2728fe8SHeiher 	pfd.events = POLLIN;
2388f2728fe8SHeiher 	if (poll(&pfd, 1, -1) > 0) {
2389f2728fe8SHeiher 		if (epoll_wait(ctx.efd[1], &e, 1, 0) > 0)
2390f2728fe8SHeiher 			__sync_fetch_and_add(&ctx.count, 1);
2391f2728fe8SHeiher 	}
2392f2728fe8SHeiher 
2393f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2394f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
2395f2728fe8SHeiher 
2396f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2397f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2398f2728fe8SHeiher 		pthread_join(emitter, NULL);
2399f2728fe8SHeiher 	}
2400f2728fe8SHeiher 
2401f2728fe8SHeiher 	close(ctx.efd[0]);
2402f2728fe8SHeiher 	close(ctx.efd[1]);
2403f2728fe8SHeiher 	close(ctx.sfd[0]);
2404f2728fe8SHeiher 	close(ctx.sfd[1]);
2405f2728fe8SHeiher }
2406f2728fe8SHeiher 
2407f2728fe8SHeiher /*
2408f2728fe8SHeiher  *        t0   t1
2409f2728fe8SHeiher  *     (p) |    | (p)
2410f2728fe8SHeiher  *         |   e0
2411f2728fe8SHeiher  *          \  / (et)
2412f2728fe8SHeiher  *           e1
2413f2728fe8SHeiher  *            | (et)
2414f2728fe8SHeiher  *           s0
2415f2728fe8SHeiher  */
TEST(epoll48)2416f2728fe8SHeiher TEST(epoll48)
2417f2728fe8SHeiher {
2418f2728fe8SHeiher 	pthread_t emitter;
2419f2728fe8SHeiher 	struct epoll_event e;
2420f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2421f2728fe8SHeiher 
2422f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2423f2728fe8SHeiher 
2424f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
2425f2728fe8SHeiher 
2426f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2427f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2428f2728fe8SHeiher 
2429f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2430f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2431f2728fe8SHeiher 
2432f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2433f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2434f2728fe8SHeiher 
2435f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2436f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2437f2728fe8SHeiher 
2438f2728fe8SHeiher 	ctx.main = pthread_self();
2439f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1op, &ctx), 0);
2440f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry1, &ctx), 0);
2441f2728fe8SHeiher 
2442f2728fe8SHeiher 	if (epoll_wait(ctx.efd[1], &e, 1, -1) > 0)
2443f2728fe8SHeiher 		__sync_fetch_and_or(&ctx.count, 2);
2444f2728fe8SHeiher 
2445f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2446f2728fe8SHeiher 	EXPECT_TRUE((ctx.count == 2) || (ctx.count == 3));
2447f2728fe8SHeiher 
2448f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2449f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2450f2728fe8SHeiher 		pthread_join(emitter, NULL);
2451f2728fe8SHeiher 	}
2452f2728fe8SHeiher 
2453f2728fe8SHeiher 	close(ctx.efd[0]);
2454f2728fe8SHeiher 	close(ctx.efd[1]);
2455f2728fe8SHeiher 	close(ctx.sfd[0]);
2456f2728fe8SHeiher 	close(ctx.sfd[1]);
2457f2728fe8SHeiher }
2458f2728fe8SHeiher 
2459f2728fe8SHeiher /*
2460f2728fe8SHeiher  *           t0
2461f2728fe8SHeiher  *            | (ew)
2462f2728fe8SHeiher  *           e0
2463f2728fe8SHeiher  *     (lt) /  \ (lt)
2464f2728fe8SHeiher  *        e1    e2
2465f2728fe8SHeiher  *    (lt) |     | (lt)
2466f2728fe8SHeiher  *        s0    s2
2467f2728fe8SHeiher  */
TEST(epoll49)2468f2728fe8SHeiher TEST(epoll49)
2469f2728fe8SHeiher {
2470f2728fe8SHeiher 	int efd[3];
2471f2728fe8SHeiher 	int sfd[4];
2472f2728fe8SHeiher 	struct epoll_event events[2];
2473f2728fe8SHeiher 
2474f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
2475f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
2476f2728fe8SHeiher 
2477f2728fe8SHeiher 	efd[0] = epoll_create(1);
2478f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
2479f2728fe8SHeiher 
2480f2728fe8SHeiher 	efd[1] = epoll_create(1);
2481f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
2482f2728fe8SHeiher 
2483f2728fe8SHeiher 	efd[2] = epoll_create(1);
2484f2728fe8SHeiher 	ASSERT_GE(efd[2], 0);
2485f2728fe8SHeiher 
2486f2728fe8SHeiher 	events[0].events = EPOLLIN;
2487f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], events), 0);
2488f2728fe8SHeiher 
2489f2728fe8SHeiher 	events[0].events = EPOLLIN;
2490f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[2], EPOLL_CTL_ADD, sfd[2], events), 0);
2491f2728fe8SHeiher 
2492f2728fe8SHeiher 	events[0].events = EPOLLIN;
2493f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], events), 0);
2494f2728fe8SHeiher 
2495f2728fe8SHeiher 	events[0].events = EPOLLIN;
2496f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[2], events), 0);
2497f2728fe8SHeiher 
2498f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
2499f2728fe8SHeiher 	ASSERT_EQ(write(sfd[3], "w", 1), 1);
2500f2728fe8SHeiher 
2501f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
2502f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
2503f2728fe8SHeiher 
2504f2728fe8SHeiher 	close(efd[0]);
2505f2728fe8SHeiher 	close(efd[1]);
2506f2728fe8SHeiher 	close(efd[2]);
2507f2728fe8SHeiher 	close(sfd[0]);
2508f2728fe8SHeiher 	close(sfd[1]);
2509f2728fe8SHeiher 	close(sfd[2]);
2510f2728fe8SHeiher 	close(sfd[3]);
2511f2728fe8SHeiher }
2512f2728fe8SHeiher 
2513f2728fe8SHeiher /*
2514f2728fe8SHeiher  *           t0
2515f2728fe8SHeiher  *            | (ew)
2516f2728fe8SHeiher  *           e0
2517f2728fe8SHeiher  *     (et) /  \ (et)
2518f2728fe8SHeiher  *        e1    e2
2519f2728fe8SHeiher  *    (lt) |     | (lt)
2520f2728fe8SHeiher  *        s0    s2
2521f2728fe8SHeiher  */
TEST(epoll50)2522f2728fe8SHeiher TEST(epoll50)
2523f2728fe8SHeiher {
2524f2728fe8SHeiher 	int efd[3];
2525f2728fe8SHeiher 	int sfd[4];
2526f2728fe8SHeiher 	struct epoll_event events[2];
2527f2728fe8SHeiher 
2528f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
2529f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
2530f2728fe8SHeiher 
2531f2728fe8SHeiher 	efd[0] = epoll_create(1);
2532f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
2533f2728fe8SHeiher 
2534f2728fe8SHeiher 	efd[1] = epoll_create(1);
2535f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
2536f2728fe8SHeiher 
2537f2728fe8SHeiher 	efd[2] = epoll_create(1);
2538f2728fe8SHeiher 	ASSERT_GE(efd[2], 0);
2539f2728fe8SHeiher 
2540f2728fe8SHeiher 	events[0].events = EPOLLIN;
2541f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], events), 0);
2542f2728fe8SHeiher 
2543f2728fe8SHeiher 	events[0].events = EPOLLIN;
2544f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[2], EPOLL_CTL_ADD, sfd[2], events), 0);
2545f2728fe8SHeiher 
2546f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
2547f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], events), 0);
2548f2728fe8SHeiher 
2549f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
2550f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[2], events), 0);
2551f2728fe8SHeiher 
2552f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
2553f2728fe8SHeiher 	ASSERT_EQ(write(sfd[3], "w", 1), 1);
2554f2728fe8SHeiher 
2555f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
2556f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 0);
2557f2728fe8SHeiher 
2558f2728fe8SHeiher 	close(efd[0]);
2559f2728fe8SHeiher 	close(efd[1]);
2560f2728fe8SHeiher 	close(efd[2]);
2561f2728fe8SHeiher 	close(sfd[0]);
2562f2728fe8SHeiher 	close(sfd[1]);
2563f2728fe8SHeiher 	close(sfd[2]);
2564f2728fe8SHeiher 	close(sfd[3]);
2565f2728fe8SHeiher }
2566f2728fe8SHeiher 
2567f2728fe8SHeiher /*
2568f2728fe8SHeiher  *           t0
2569f2728fe8SHeiher  *            | (p)
2570f2728fe8SHeiher  *           e0
2571f2728fe8SHeiher  *     (lt) /  \ (lt)
2572f2728fe8SHeiher  *        e1    e2
2573f2728fe8SHeiher  *    (lt) |     | (lt)
2574f2728fe8SHeiher  *        s0    s2
2575f2728fe8SHeiher  */
TEST(epoll51)2576f2728fe8SHeiher TEST(epoll51)
2577f2728fe8SHeiher {
2578f2728fe8SHeiher 	int efd[3];
2579f2728fe8SHeiher 	int sfd[4];
2580f2728fe8SHeiher 	struct pollfd pfd;
2581f2728fe8SHeiher 	struct epoll_event events[2];
2582f2728fe8SHeiher 
2583f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
2584f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
2585f2728fe8SHeiher 
2586f2728fe8SHeiher 	efd[0] = epoll_create(1);
2587f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
2588f2728fe8SHeiher 
2589f2728fe8SHeiher 	efd[1] = epoll_create(1);
2590f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
2591f2728fe8SHeiher 
2592f2728fe8SHeiher 	efd[2] = epoll_create(1);
2593f2728fe8SHeiher 	ASSERT_GE(efd[2], 0);
2594f2728fe8SHeiher 
2595f2728fe8SHeiher 	events[0].events = EPOLLIN;
2596f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], events), 0);
2597f2728fe8SHeiher 
2598f2728fe8SHeiher 	events[0].events = EPOLLIN;
2599f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[2], EPOLL_CTL_ADD, sfd[2], events), 0);
2600f2728fe8SHeiher 
2601f2728fe8SHeiher 	events[0].events = EPOLLIN;
2602f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], events), 0);
2603f2728fe8SHeiher 
2604f2728fe8SHeiher 	events[0].events = EPOLLIN;
2605f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[2], events), 0);
2606f2728fe8SHeiher 
2607f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
2608f2728fe8SHeiher 	ASSERT_EQ(write(sfd[3], "w", 1), 1);
2609f2728fe8SHeiher 
2610f2728fe8SHeiher 	pfd.fd = efd[0];
2611f2728fe8SHeiher 	pfd.events = POLLIN;
2612f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
2613f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
2614f2728fe8SHeiher 
2615f2728fe8SHeiher 	pfd.fd = efd[0];
2616f2728fe8SHeiher 	pfd.events = POLLIN;
2617f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
2618f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
2619f2728fe8SHeiher 
2620f2728fe8SHeiher 	close(efd[0]);
2621f2728fe8SHeiher 	close(efd[1]);
2622f2728fe8SHeiher 	close(efd[2]);
2623f2728fe8SHeiher 	close(sfd[0]);
2624f2728fe8SHeiher 	close(sfd[1]);
2625f2728fe8SHeiher 	close(sfd[2]);
2626f2728fe8SHeiher 	close(sfd[3]);
2627f2728fe8SHeiher }
2628f2728fe8SHeiher 
2629f2728fe8SHeiher /*
2630f2728fe8SHeiher  *           t0
2631f2728fe8SHeiher  *            | (p)
2632f2728fe8SHeiher  *           e0
2633f2728fe8SHeiher  *     (et) /  \ (et)
2634f2728fe8SHeiher  *        e1    e2
2635f2728fe8SHeiher  *    (lt) |     | (lt)
2636f2728fe8SHeiher  *        s0    s2
2637f2728fe8SHeiher  */
TEST(epoll52)2638f2728fe8SHeiher TEST(epoll52)
2639f2728fe8SHeiher {
2640f2728fe8SHeiher 	int efd[3];
2641f2728fe8SHeiher 	int sfd[4];
2642f2728fe8SHeiher 	struct pollfd pfd;
2643f2728fe8SHeiher 	struct epoll_event events[2];
2644f2728fe8SHeiher 
2645f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[0]), 0);
2646f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &sfd[2]), 0);
2647f2728fe8SHeiher 
2648f2728fe8SHeiher 	efd[0] = epoll_create(1);
2649f2728fe8SHeiher 	ASSERT_GE(efd[0], 0);
2650f2728fe8SHeiher 
2651f2728fe8SHeiher 	efd[1] = epoll_create(1);
2652f2728fe8SHeiher 	ASSERT_GE(efd[1], 0);
2653f2728fe8SHeiher 
2654f2728fe8SHeiher 	efd[2] = epoll_create(1);
2655f2728fe8SHeiher 	ASSERT_GE(efd[2], 0);
2656f2728fe8SHeiher 
2657f2728fe8SHeiher 	events[0].events = EPOLLIN;
2658f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[1], EPOLL_CTL_ADD, sfd[0], events), 0);
2659f2728fe8SHeiher 
2660f2728fe8SHeiher 	events[0].events = EPOLLIN;
2661f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[2], EPOLL_CTL_ADD, sfd[2], events), 0);
2662f2728fe8SHeiher 
2663f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
2664f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[1], events), 0);
2665f2728fe8SHeiher 
2666f2728fe8SHeiher 	events[0].events = EPOLLIN | EPOLLET;
2667f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(efd[0], EPOLL_CTL_ADD, efd[2], events), 0);
2668f2728fe8SHeiher 
2669f2728fe8SHeiher 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
2670f2728fe8SHeiher 	ASSERT_EQ(write(sfd[3], "w", 1), 1);
2671f2728fe8SHeiher 
2672f2728fe8SHeiher 	pfd.fd = efd[0];
2673f2728fe8SHeiher 	pfd.events = POLLIN;
2674f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 1);
2675f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 2);
2676f2728fe8SHeiher 
2677f2728fe8SHeiher 	pfd.fd = efd[0];
2678f2728fe8SHeiher 	pfd.events = POLLIN;
2679f2728fe8SHeiher 	EXPECT_EQ(poll(&pfd, 1, 0), 0);
2680f2728fe8SHeiher 	EXPECT_EQ(epoll_wait(efd[0], events, 2, 0), 0);
2681f2728fe8SHeiher 
2682f2728fe8SHeiher 	close(efd[0]);
2683f2728fe8SHeiher 	close(efd[1]);
2684f2728fe8SHeiher 	close(efd[2]);
2685f2728fe8SHeiher 	close(sfd[0]);
2686f2728fe8SHeiher 	close(sfd[1]);
2687f2728fe8SHeiher 	close(sfd[2]);
2688f2728fe8SHeiher 	close(sfd[3]);
2689f2728fe8SHeiher }
2690f2728fe8SHeiher 
2691f2728fe8SHeiher /*
2692f2728fe8SHeiher  *        t0    t1
2693f2728fe8SHeiher  *     (ew) \  / (ew)
2694f2728fe8SHeiher  *           e0
2695f2728fe8SHeiher  *     (lt) /  \ (lt)
2696f2728fe8SHeiher  *        e1    e2
2697f2728fe8SHeiher  *    (lt) |     | (lt)
2698f2728fe8SHeiher  *        s0    s2
2699f2728fe8SHeiher  */
TEST(epoll53)2700f2728fe8SHeiher TEST(epoll53)
2701f2728fe8SHeiher {
2702f2728fe8SHeiher 	pthread_t emitter;
2703f2728fe8SHeiher 	struct epoll_event e;
2704f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2705f2728fe8SHeiher 
2706f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2707f2728fe8SHeiher 
2708f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
2709f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
2710f2728fe8SHeiher 
2711f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2712f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2713f2728fe8SHeiher 
2714f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2715f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2716f2728fe8SHeiher 
2717f2728fe8SHeiher 	ctx.efd[2] = epoll_create(1);
2718f2728fe8SHeiher 	ASSERT_GE(ctx.efd[2], 0);
2719f2728fe8SHeiher 
2720f2728fe8SHeiher 	e.events = EPOLLIN;
2721f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2722f2728fe8SHeiher 
2723f2728fe8SHeiher 	e.events = EPOLLIN;
2724f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
2725f2728fe8SHeiher 
2726f2728fe8SHeiher 	e.events = EPOLLIN;
2727f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2728f2728fe8SHeiher 
2729f2728fe8SHeiher 	e.events = EPOLLIN;
2730f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
2731f2728fe8SHeiher 
2732f2728fe8SHeiher 	ctx.main = pthread_self();
2733f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
2734f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
2735f2728fe8SHeiher 
2736f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
2737f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
2738f2728fe8SHeiher 
2739f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2740f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
2741f2728fe8SHeiher 
2742f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2743f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2744f2728fe8SHeiher 		pthread_join(emitter, NULL);
2745f2728fe8SHeiher 	}
2746f2728fe8SHeiher 
2747f2728fe8SHeiher 	close(ctx.efd[0]);
2748f2728fe8SHeiher 	close(ctx.efd[1]);
2749f2728fe8SHeiher 	close(ctx.efd[2]);
2750f2728fe8SHeiher 	close(ctx.sfd[0]);
2751f2728fe8SHeiher 	close(ctx.sfd[1]);
2752f2728fe8SHeiher 	close(ctx.sfd[2]);
2753f2728fe8SHeiher 	close(ctx.sfd[3]);
2754f2728fe8SHeiher }
2755f2728fe8SHeiher 
2756f2728fe8SHeiher /*
2757f2728fe8SHeiher  *        t0    t1
2758f2728fe8SHeiher  *     (ew) \  / (ew)
2759f2728fe8SHeiher  *           e0
2760f2728fe8SHeiher  *     (et) /  \ (et)
2761f2728fe8SHeiher  *        e1    e2
2762f2728fe8SHeiher  *    (lt) |     | (lt)
2763f2728fe8SHeiher  *        s0    s2
2764f2728fe8SHeiher  */
TEST(epoll54)2765f2728fe8SHeiher TEST(epoll54)
2766f2728fe8SHeiher {
2767f2728fe8SHeiher 	pthread_t emitter;
2768f2728fe8SHeiher 	struct epoll_event e;
2769f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2770f2728fe8SHeiher 
2771f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2772f2728fe8SHeiher 
2773f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
2774f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
2775f2728fe8SHeiher 
2776f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2777f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2778f2728fe8SHeiher 
2779f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2780f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2781f2728fe8SHeiher 
2782f2728fe8SHeiher 	ctx.efd[2] = epoll_create(1);
2783f2728fe8SHeiher 	ASSERT_GE(ctx.efd[2], 0);
2784f2728fe8SHeiher 
2785f2728fe8SHeiher 	e.events = EPOLLIN;
2786f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2787f2728fe8SHeiher 
2788f2728fe8SHeiher 	e.events = EPOLLIN;
2789f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
2790f2728fe8SHeiher 
2791f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2792f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2793f2728fe8SHeiher 
2794f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2795f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
2796f2728fe8SHeiher 
2797f2728fe8SHeiher 	ctx.main = pthread_self();
2798f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1a, &ctx), 0);
2799f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
2800f2728fe8SHeiher 
2801f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
2802f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
2803f2728fe8SHeiher 
2804f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2805f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
2806f2728fe8SHeiher 
2807f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2808f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2809f2728fe8SHeiher 		pthread_join(emitter, NULL);
2810f2728fe8SHeiher 	}
2811f2728fe8SHeiher 
2812f2728fe8SHeiher 	close(ctx.efd[0]);
2813f2728fe8SHeiher 	close(ctx.efd[1]);
2814f2728fe8SHeiher 	close(ctx.efd[2]);
2815f2728fe8SHeiher 	close(ctx.sfd[0]);
2816f2728fe8SHeiher 	close(ctx.sfd[1]);
2817f2728fe8SHeiher 	close(ctx.sfd[2]);
2818f2728fe8SHeiher 	close(ctx.sfd[3]);
2819f2728fe8SHeiher }
2820f2728fe8SHeiher 
2821f2728fe8SHeiher /*
2822f2728fe8SHeiher  *        t0    t1
2823f2728fe8SHeiher  *     (ew) \  / (p)
2824f2728fe8SHeiher  *           e0
2825f2728fe8SHeiher  *     (lt) /  \ (lt)
2826f2728fe8SHeiher  *        e1    e2
2827f2728fe8SHeiher  *    (lt) |     | (lt)
2828f2728fe8SHeiher  *        s0    s2
2829f2728fe8SHeiher  */
TEST(epoll55)2830f2728fe8SHeiher TEST(epoll55)
2831f2728fe8SHeiher {
2832f2728fe8SHeiher 	pthread_t emitter;
2833f2728fe8SHeiher 	struct epoll_event e;
2834f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2835f2728fe8SHeiher 
2836f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2837f2728fe8SHeiher 
2838f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
2839f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
2840f2728fe8SHeiher 
2841f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2842f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2843f2728fe8SHeiher 
2844f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2845f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2846f2728fe8SHeiher 
2847f2728fe8SHeiher 	ctx.efd[2] = epoll_create(1);
2848f2728fe8SHeiher 	ASSERT_GE(ctx.efd[2], 0);
2849f2728fe8SHeiher 
2850f2728fe8SHeiher 	e.events = EPOLLIN;
2851f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2852f2728fe8SHeiher 
2853f2728fe8SHeiher 	e.events = EPOLLIN;
2854f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
2855f2728fe8SHeiher 
2856f2728fe8SHeiher 	e.events = EPOLLIN;
2857f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2858f2728fe8SHeiher 
2859f2728fe8SHeiher 	e.events = EPOLLIN;
2860f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
2861f2728fe8SHeiher 
2862f2728fe8SHeiher 	ctx.main = pthread_self();
2863f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
2864f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
2865f2728fe8SHeiher 
2866f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
2867f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
2868f2728fe8SHeiher 
2869f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2870f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
2871f2728fe8SHeiher 
2872f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2873f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2874f2728fe8SHeiher 		pthread_join(emitter, NULL);
2875f2728fe8SHeiher 	}
2876f2728fe8SHeiher 
2877f2728fe8SHeiher 	close(ctx.efd[0]);
2878f2728fe8SHeiher 	close(ctx.efd[1]);
2879f2728fe8SHeiher 	close(ctx.efd[2]);
2880f2728fe8SHeiher 	close(ctx.sfd[0]);
2881f2728fe8SHeiher 	close(ctx.sfd[1]);
2882f2728fe8SHeiher 	close(ctx.sfd[2]);
2883f2728fe8SHeiher 	close(ctx.sfd[3]);
2884f2728fe8SHeiher }
2885f2728fe8SHeiher 
2886f2728fe8SHeiher /*
2887f2728fe8SHeiher  *        t0    t1
2888f2728fe8SHeiher  *     (ew) \  / (p)
2889f2728fe8SHeiher  *           e0
2890f2728fe8SHeiher  *     (et) /  \ (et)
2891f2728fe8SHeiher  *        e1    e2
2892f2728fe8SHeiher  *    (lt) |     | (lt)
2893f2728fe8SHeiher  *        s0    s2
2894f2728fe8SHeiher  */
TEST(epoll56)2895f2728fe8SHeiher TEST(epoll56)
2896f2728fe8SHeiher {
2897f2728fe8SHeiher 	pthread_t emitter;
2898f2728fe8SHeiher 	struct epoll_event e;
2899f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2900f2728fe8SHeiher 
2901f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2902f2728fe8SHeiher 
2903f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
2904f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
2905f2728fe8SHeiher 
2906f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2907f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2908f2728fe8SHeiher 
2909f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2910f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2911f2728fe8SHeiher 
2912f2728fe8SHeiher 	ctx.efd[2] = epoll_create(1);
2913f2728fe8SHeiher 	ASSERT_GE(ctx.efd[2], 0);
2914f2728fe8SHeiher 
2915f2728fe8SHeiher 	e.events = EPOLLIN;
2916f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2917f2728fe8SHeiher 
2918f2728fe8SHeiher 	e.events = EPOLLIN;
2919f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
2920f2728fe8SHeiher 
2921f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2922f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2923f2728fe8SHeiher 
2924f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
2925f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
2926f2728fe8SHeiher 
2927f2728fe8SHeiher 	ctx.main = pthread_self();
2928f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
2929f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
2930f2728fe8SHeiher 
2931f2728fe8SHeiher 	if (epoll_wait(ctx.efd[0], &e, 1, -1) > 0)
2932f2728fe8SHeiher 		__sync_fetch_and_add(&ctx.count, 1);
2933f2728fe8SHeiher 
2934f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
2935f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
2936f2728fe8SHeiher 
2937f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
2938f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
2939f2728fe8SHeiher 		pthread_join(emitter, NULL);
2940f2728fe8SHeiher 	}
2941f2728fe8SHeiher 
2942f2728fe8SHeiher 	close(ctx.efd[0]);
2943f2728fe8SHeiher 	close(ctx.efd[1]);
2944f2728fe8SHeiher 	close(ctx.efd[2]);
2945f2728fe8SHeiher 	close(ctx.sfd[0]);
2946f2728fe8SHeiher 	close(ctx.sfd[1]);
2947f2728fe8SHeiher 	close(ctx.sfd[2]);
2948f2728fe8SHeiher 	close(ctx.sfd[3]);
2949f2728fe8SHeiher }
2950f2728fe8SHeiher 
2951f2728fe8SHeiher /*
2952f2728fe8SHeiher  *        t0    t1
2953f2728fe8SHeiher  *      (p) \  / (p)
2954f2728fe8SHeiher  *           e0
2955f2728fe8SHeiher  *     (lt) /  \ (lt)
2956f2728fe8SHeiher  *        e1    e2
2957f2728fe8SHeiher  *    (lt) |     | (lt)
2958f2728fe8SHeiher  *        s0    s2
2959f2728fe8SHeiher  */
TEST(epoll57)2960f2728fe8SHeiher TEST(epoll57)
2961f2728fe8SHeiher {
2962f2728fe8SHeiher 	pthread_t emitter;
2963f2728fe8SHeiher 	struct pollfd pfd;
2964f2728fe8SHeiher 	struct epoll_event e;
2965f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
2966f2728fe8SHeiher 
2967f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
2968f2728fe8SHeiher 
2969f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
2970f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
2971f2728fe8SHeiher 
2972f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
2973f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
2974f2728fe8SHeiher 
2975f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
2976f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
2977f2728fe8SHeiher 
2978f2728fe8SHeiher 	ctx.efd[2] = epoll_create(1);
2979f2728fe8SHeiher 	ASSERT_GE(ctx.efd[2], 0);
2980f2728fe8SHeiher 
2981f2728fe8SHeiher 	e.events = EPOLLIN;
2982f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
2983f2728fe8SHeiher 
2984f2728fe8SHeiher 	e.events = EPOLLIN;
2985f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
2986f2728fe8SHeiher 
2987f2728fe8SHeiher 	e.events = EPOLLIN;
2988f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
2989f2728fe8SHeiher 
2990f2728fe8SHeiher 	e.events = EPOLLIN;
2991f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
2992f2728fe8SHeiher 
2993f2728fe8SHeiher 	ctx.main = pthread_self();
2994f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
2995f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
2996f2728fe8SHeiher 
2997f2728fe8SHeiher 	pfd.fd = ctx.efd[0];
2998f2728fe8SHeiher 	pfd.events = POLLIN;
2999f2728fe8SHeiher 	if (poll(&pfd, 1, -1) > 0) {
3000f2728fe8SHeiher 		if (epoll_wait(ctx.efd[0], &e, 1, 0) > 0)
3001f2728fe8SHeiher 			__sync_fetch_and_add(&ctx.count, 1);
3002f2728fe8SHeiher 	}
3003f2728fe8SHeiher 
3004f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
3005f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
3006f2728fe8SHeiher 
3007f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
3008f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
3009f2728fe8SHeiher 		pthread_join(emitter, NULL);
3010f2728fe8SHeiher 	}
3011f2728fe8SHeiher 
3012f2728fe8SHeiher 	close(ctx.efd[0]);
3013f2728fe8SHeiher 	close(ctx.efd[1]);
3014f2728fe8SHeiher 	close(ctx.efd[2]);
3015f2728fe8SHeiher 	close(ctx.sfd[0]);
3016f2728fe8SHeiher 	close(ctx.sfd[1]);
3017f2728fe8SHeiher 	close(ctx.sfd[2]);
3018f2728fe8SHeiher 	close(ctx.sfd[3]);
3019f2728fe8SHeiher }
3020f2728fe8SHeiher 
3021f2728fe8SHeiher /*
3022f2728fe8SHeiher  *        t0    t1
3023f2728fe8SHeiher  *      (p) \  / (p)
3024f2728fe8SHeiher  *           e0
3025f2728fe8SHeiher  *     (et) /  \ (et)
3026f2728fe8SHeiher  *        e1    e2
3027f2728fe8SHeiher  *    (lt) |     | (lt)
3028f2728fe8SHeiher  *        s0    s2
3029f2728fe8SHeiher  */
TEST(epoll58)3030f2728fe8SHeiher TEST(epoll58)
3031f2728fe8SHeiher {
3032f2728fe8SHeiher 	pthread_t emitter;
3033f2728fe8SHeiher 	struct pollfd pfd;
3034f2728fe8SHeiher 	struct epoll_event e;
3035f2728fe8SHeiher 	struct epoll_mtcontext ctx = { 0 };
3036f2728fe8SHeiher 
3037f2728fe8SHeiher 	signal(SIGUSR1, signal_handler);
3038f2728fe8SHeiher 
3039f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[0]), 0);
3040f2728fe8SHeiher 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx.sfd[2]), 0);
3041f2728fe8SHeiher 
3042f2728fe8SHeiher 	ctx.efd[0] = epoll_create(1);
3043f2728fe8SHeiher 	ASSERT_GE(ctx.efd[0], 0);
3044f2728fe8SHeiher 
3045f2728fe8SHeiher 	ctx.efd[1] = epoll_create(1);
3046f2728fe8SHeiher 	ASSERT_GE(ctx.efd[1], 0);
3047f2728fe8SHeiher 
3048f2728fe8SHeiher 	ctx.efd[2] = epoll_create(1);
3049f2728fe8SHeiher 	ASSERT_GE(ctx.efd[2], 0);
3050f2728fe8SHeiher 
3051f2728fe8SHeiher 	e.events = EPOLLIN;
3052f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[1], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
3053f2728fe8SHeiher 
3054f2728fe8SHeiher 	e.events = EPOLLIN;
3055f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[2], EPOLL_CTL_ADD, ctx.sfd[2], &e), 0);
3056f2728fe8SHeiher 
3057f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
3058f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[1], &e), 0);
3059f2728fe8SHeiher 
3060f2728fe8SHeiher 	e.events = EPOLLIN | EPOLLET;
3061f2728fe8SHeiher 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.efd[2], &e), 0);
3062f2728fe8SHeiher 
3063f2728fe8SHeiher 	ctx.main = pthread_self();
3064f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&ctx.waiter, NULL, waiter_entry1ap, &ctx), 0);
3065f2728fe8SHeiher 	ASSERT_EQ(pthread_create(&emitter, NULL, emitter_entry2, &ctx), 0);
3066f2728fe8SHeiher 
3067f2728fe8SHeiher 	pfd.fd = ctx.efd[0];
3068f2728fe8SHeiher 	pfd.events = POLLIN;
3069f2728fe8SHeiher 	if (poll(&pfd, 1, -1) > 0) {
3070f2728fe8SHeiher 		if (epoll_wait(ctx.efd[0], &e, 1, 0) > 0)
3071f2728fe8SHeiher 			__sync_fetch_and_add(&ctx.count, 1);
3072f2728fe8SHeiher 	}
3073f2728fe8SHeiher 
3074f2728fe8SHeiher 	ASSERT_EQ(pthread_join(ctx.waiter, NULL), 0);
3075f2728fe8SHeiher 	EXPECT_EQ(ctx.count, 2);
3076f2728fe8SHeiher 
3077f2728fe8SHeiher 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
3078f2728fe8SHeiher 		pthread_kill(emitter, SIGUSR1);
3079f2728fe8SHeiher 		pthread_join(emitter, NULL);
3080f2728fe8SHeiher 	}
3081f2728fe8SHeiher 
3082f2728fe8SHeiher 	close(ctx.efd[0]);
3083f2728fe8SHeiher 	close(ctx.efd[1]);
3084f2728fe8SHeiher 	close(ctx.efd[2]);
3085f2728fe8SHeiher 	close(ctx.sfd[0]);
3086f2728fe8SHeiher 	close(ctx.sfd[1]);
3087f2728fe8SHeiher 	close(ctx.sfd[2]);
3088f2728fe8SHeiher 	close(ctx.sfd[3]);
3089f2728fe8SHeiher }
3090f2728fe8SHeiher 
epoll59_thread(void * ctx_)3091282144e0SRoman Penyaev static void *epoll59_thread(void *ctx_)
3092282144e0SRoman Penyaev {
3093282144e0SRoman Penyaev 	struct epoll_mtcontext *ctx = ctx_;
3094282144e0SRoman Penyaev 	struct epoll_event e;
3095282144e0SRoman Penyaev 	int i;
3096282144e0SRoman Penyaev 
3097282144e0SRoman Penyaev 	for (i = 0; i < 100000; i++) {
3098282144e0SRoman Penyaev 		while (ctx->count == 0)
3099282144e0SRoman Penyaev 			;
3100282144e0SRoman Penyaev 
3101282144e0SRoman Penyaev 		e.events = EPOLLIN | EPOLLERR | EPOLLET;
3102282144e0SRoman Penyaev 		epoll_ctl(ctx->efd[0], EPOLL_CTL_MOD, ctx->sfd[0], &e);
3103282144e0SRoman Penyaev 		ctx->count = 0;
3104282144e0SRoman Penyaev 	}
3105282144e0SRoman Penyaev 
3106282144e0SRoman Penyaev 	return NULL;
3107282144e0SRoman Penyaev }
3108282144e0SRoman Penyaev 
3109282144e0SRoman Penyaev /*
3110282144e0SRoman Penyaev  *        t0
3111282144e0SRoman Penyaev  *      (p) \
3112282144e0SRoman Penyaev  *           e0
3113282144e0SRoman Penyaev  *     (et) /
3114282144e0SRoman Penyaev  *        e0
3115282144e0SRoman Penyaev  *
3116282144e0SRoman Penyaev  * Based on https://bugzilla.kernel.org/show_bug.cgi?id=205933
3117282144e0SRoman Penyaev  */
TEST(epoll59)3118282144e0SRoman Penyaev TEST(epoll59)
3119282144e0SRoman Penyaev {
3120282144e0SRoman Penyaev 	pthread_t emitter;
3121282144e0SRoman Penyaev 	struct pollfd pfd;
3122282144e0SRoman Penyaev 	struct epoll_event e;
3123282144e0SRoman Penyaev 	struct epoll_mtcontext ctx = { 0 };
3124282144e0SRoman Penyaev 	int i, ret;
3125282144e0SRoman Penyaev 
3126282144e0SRoman Penyaev 	signal(SIGUSR1, signal_handler);
3127282144e0SRoman Penyaev 
3128282144e0SRoman Penyaev 	ctx.efd[0] = epoll_create1(0);
3129282144e0SRoman Penyaev 	ASSERT_GE(ctx.efd[0], 0);
3130282144e0SRoman Penyaev 
3131282144e0SRoman Penyaev 	ctx.sfd[0] = eventfd(1, 0);
3132282144e0SRoman Penyaev 	ASSERT_GE(ctx.sfd[0], 0);
3133282144e0SRoman Penyaev 
3134282144e0SRoman Penyaev 	e.events = EPOLLIN | EPOLLERR | EPOLLET;
3135282144e0SRoman Penyaev 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
3136282144e0SRoman Penyaev 
3137282144e0SRoman Penyaev 	ASSERT_EQ(pthread_create(&emitter, NULL, epoll59_thread, &ctx), 0);
3138282144e0SRoman Penyaev 
3139282144e0SRoman Penyaev 	for (i = 0; i < 100000; i++) {
3140282144e0SRoman Penyaev 		ret = epoll_wait(ctx.efd[0], &e, 1, 1000);
3141282144e0SRoman Penyaev 		ASSERT_GT(ret, 0);
3142282144e0SRoman Penyaev 
3143282144e0SRoman Penyaev 		while (ctx.count != 0)
3144282144e0SRoman Penyaev 			;
3145282144e0SRoman Penyaev 		ctx.count = 1;
3146282144e0SRoman Penyaev 	}
3147282144e0SRoman Penyaev 	if (pthread_tryjoin_np(emitter, NULL) < 0) {
3148282144e0SRoman Penyaev 		pthread_kill(emitter, SIGUSR1);
3149282144e0SRoman Penyaev 		pthread_join(emitter, NULL);
3150282144e0SRoman Penyaev 	}
3151282144e0SRoman Penyaev 	close(ctx.efd[0]);
3152282144e0SRoman Penyaev 	close(ctx.sfd[0]);
3153282144e0SRoman Penyaev }
3154282144e0SRoman Penyaev 
3155474328c0SRoman Penyaev enum {
3156474328c0SRoman Penyaev 	EPOLL60_EVENTS_NR = 10,
3157474328c0SRoman Penyaev };
3158474328c0SRoman Penyaev 
3159474328c0SRoman Penyaev struct epoll60_ctx {
3160474328c0SRoman Penyaev 	volatile int stopped;
3161474328c0SRoman Penyaev 	int ready;
3162474328c0SRoman Penyaev 	int waiters;
3163474328c0SRoman Penyaev 	int epfd;
3164474328c0SRoman Penyaev 	int evfd[EPOLL60_EVENTS_NR];
3165474328c0SRoman Penyaev };
3166474328c0SRoman Penyaev 
epoll60_wait_thread(void * ctx_)3167474328c0SRoman Penyaev static void *epoll60_wait_thread(void *ctx_)
3168474328c0SRoman Penyaev {
3169474328c0SRoman Penyaev 	struct epoll60_ctx *ctx = ctx_;
3170474328c0SRoman Penyaev 	struct epoll_event e;
3171474328c0SRoman Penyaev 	sigset_t sigmask;
3172474328c0SRoman Penyaev 	uint64_t v;
3173474328c0SRoman Penyaev 	int ret;
3174474328c0SRoman Penyaev 
3175474328c0SRoman Penyaev 	/* Block SIGUSR1 */
3176474328c0SRoman Penyaev 	sigemptyset(&sigmask);
3177474328c0SRoman Penyaev 	sigaddset(&sigmask, SIGUSR1);
3178474328c0SRoman Penyaev 	sigprocmask(SIG_SETMASK, &sigmask, NULL);
3179474328c0SRoman Penyaev 
3180474328c0SRoman Penyaev 	/* Prepare empty mask for epoll_pwait() */
3181474328c0SRoman Penyaev 	sigemptyset(&sigmask);
3182474328c0SRoman Penyaev 
3183474328c0SRoman Penyaev 	while (!ctx->stopped) {
3184474328c0SRoman Penyaev 		/* Mark we are ready */
3185474328c0SRoman Penyaev 		__atomic_fetch_add(&ctx->ready, 1, __ATOMIC_ACQUIRE);
3186474328c0SRoman Penyaev 
3187474328c0SRoman Penyaev 		/* Start when all are ready */
3188474328c0SRoman Penyaev 		while (__atomic_load_n(&ctx->ready, __ATOMIC_ACQUIRE) &&
3189474328c0SRoman Penyaev 		       !ctx->stopped);
3190474328c0SRoman Penyaev 
3191474328c0SRoman Penyaev 		/* Account this waiter */
3192474328c0SRoman Penyaev 		__atomic_fetch_add(&ctx->waiters, 1, __ATOMIC_ACQUIRE);
3193474328c0SRoman Penyaev 
3194474328c0SRoman Penyaev 		ret = epoll_pwait(ctx->epfd, &e, 1, 2000, &sigmask);
3195474328c0SRoman Penyaev 		if (ret != 1) {
3196474328c0SRoman Penyaev 			/* We expect only signal delivery on stop */
3197474328c0SRoman Penyaev 			assert(ret < 0 && errno == EINTR && "Lost wakeup!\n");
3198474328c0SRoman Penyaev 			assert(ctx->stopped);
3199474328c0SRoman Penyaev 			break;
3200474328c0SRoman Penyaev 		}
3201474328c0SRoman Penyaev 
3202474328c0SRoman Penyaev 		ret = read(e.data.fd, &v, sizeof(v));
3203474328c0SRoman Penyaev 		/* Since we are on ET mode, thus each thread gets its own fd. */
3204474328c0SRoman Penyaev 		assert(ret == sizeof(v));
3205474328c0SRoman Penyaev 
3206474328c0SRoman Penyaev 		__atomic_fetch_sub(&ctx->waiters, 1, __ATOMIC_RELEASE);
3207474328c0SRoman Penyaev 	}
3208474328c0SRoman Penyaev 
3209474328c0SRoman Penyaev 	return NULL;
3210474328c0SRoman Penyaev }
3211474328c0SRoman Penyaev 
msecs(void)3212474328c0SRoman Penyaev static inline unsigned long long msecs(void)
3213474328c0SRoman Penyaev {
3214474328c0SRoman Penyaev 	struct timespec ts;
3215474328c0SRoman Penyaev 	unsigned long long msecs;
3216474328c0SRoman Penyaev 
3217474328c0SRoman Penyaev 	clock_gettime(CLOCK_REALTIME, &ts);
3218474328c0SRoman Penyaev 	msecs = ts.tv_sec * 1000ull;
3219474328c0SRoman Penyaev 	msecs += ts.tv_nsec / 1000000ull;
3220474328c0SRoman Penyaev 
3221474328c0SRoman Penyaev 	return msecs;
3222474328c0SRoman Penyaev }
3223474328c0SRoman Penyaev 
count_waiters(struct epoll60_ctx * ctx)3224474328c0SRoman Penyaev static inline int count_waiters(struct epoll60_ctx *ctx)
3225474328c0SRoman Penyaev {
3226474328c0SRoman Penyaev 	return __atomic_load_n(&ctx->waiters, __ATOMIC_ACQUIRE);
3227474328c0SRoman Penyaev }
3228474328c0SRoman Penyaev 
TEST(epoll60)3229474328c0SRoman Penyaev TEST(epoll60)
3230474328c0SRoman Penyaev {
3231474328c0SRoman Penyaev 	struct epoll60_ctx ctx = { 0 };
3232474328c0SRoman Penyaev 	pthread_t waiters[ARRAY_SIZE(ctx.evfd)];
3233474328c0SRoman Penyaev 	struct epoll_event e;
3234474328c0SRoman Penyaev 	int i, n, ret;
3235474328c0SRoman Penyaev 
3236474328c0SRoman Penyaev 	signal(SIGUSR1, signal_handler);
3237474328c0SRoman Penyaev 
3238474328c0SRoman Penyaev 	ctx.epfd = epoll_create1(0);
3239474328c0SRoman Penyaev 	ASSERT_GE(ctx.epfd, 0);
3240474328c0SRoman Penyaev 
3241474328c0SRoman Penyaev 	/* Create event fds */
3242474328c0SRoman Penyaev 	for (i = 0; i < ARRAY_SIZE(ctx.evfd); i++) {
3243474328c0SRoman Penyaev 		ctx.evfd[i] = eventfd(0, EFD_NONBLOCK);
3244474328c0SRoman Penyaev 		ASSERT_GE(ctx.evfd[i], 0);
3245474328c0SRoman Penyaev 
3246474328c0SRoman Penyaev 		e.events = EPOLLIN | EPOLLET;
3247474328c0SRoman Penyaev 		e.data.fd = ctx.evfd[i];
3248474328c0SRoman Penyaev 		ASSERT_EQ(epoll_ctl(ctx.epfd, EPOLL_CTL_ADD, ctx.evfd[i], &e), 0);
3249474328c0SRoman Penyaev 	}
3250474328c0SRoman Penyaev 
3251474328c0SRoman Penyaev 	/* Create waiter threads */
3252474328c0SRoman Penyaev 	for (i = 0; i < ARRAY_SIZE(waiters); i++)
3253474328c0SRoman Penyaev 		ASSERT_EQ(pthread_create(&waiters[i], NULL,
3254474328c0SRoman Penyaev 					 epoll60_wait_thread, &ctx), 0);
3255474328c0SRoman Penyaev 
3256474328c0SRoman Penyaev 	for (i = 0; i < 300; i++) {
3257474328c0SRoman Penyaev 		uint64_t v = 1, ms;
3258474328c0SRoman Penyaev 
3259474328c0SRoman Penyaev 		/* Wait for all to be ready */
3260474328c0SRoman Penyaev 		while (__atomic_load_n(&ctx.ready, __ATOMIC_ACQUIRE) !=
3261474328c0SRoman Penyaev 		       ARRAY_SIZE(ctx.evfd))
3262474328c0SRoman Penyaev 			;
3263474328c0SRoman Penyaev 
3264474328c0SRoman Penyaev 		/* Steady, go */
3265474328c0SRoman Penyaev 		__atomic_fetch_sub(&ctx.ready, ARRAY_SIZE(ctx.evfd),
3266474328c0SRoman Penyaev 				   __ATOMIC_ACQUIRE);
3267474328c0SRoman Penyaev 
3268474328c0SRoman Penyaev 		/* Wait all have gone to kernel */
3269474328c0SRoman Penyaev 		while (count_waiters(&ctx) != ARRAY_SIZE(ctx.evfd))
3270474328c0SRoman Penyaev 			;
3271474328c0SRoman Penyaev 
3272474328c0SRoman Penyaev 		/* 1ms should be enough to schedule away */
3273474328c0SRoman Penyaev 		usleep(1000);
3274474328c0SRoman Penyaev 
3275474328c0SRoman Penyaev 		/* Quickly signal all handles at once */
3276474328c0SRoman Penyaev 		for (n = 0; n < ARRAY_SIZE(ctx.evfd); n++) {
3277474328c0SRoman Penyaev 			ret = write(ctx.evfd[n], &v, sizeof(v));
3278474328c0SRoman Penyaev 			ASSERT_EQ(ret, sizeof(v));
3279474328c0SRoman Penyaev 		}
3280474328c0SRoman Penyaev 
3281474328c0SRoman Penyaev 		/* Busy loop for 1s and wait for all waiters to wake up */
3282474328c0SRoman Penyaev 		ms = msecs();
3283474328c0SRoman Penyaev 		while (count_waiters(&ctx) && msecs() < ms + 1000)
3284474328c0SRoman Penyaev 			;
3285474328c0SRoman Penyaev 
3286474328c0SRoman Penyaev 		ASSERT_EQ(count_waiters(&ctx), 0);
3287474328c0SRoman Penyaev 	}
3288474328c0SRoman Penyaev 	ctx.stopped = 1;
3289474328c0SRoman Penyaev 	/* Stop waiters */
3290474328c0SRoman Penyaev 	for (i = 0; i < ARRAY_SIZE(waiters); i++)
3291474328c0SRoman Penyaev 		ret = pthread_kill(waiters[i], SIGUSR1);
3292474328c0SRoman Penyaev 	for (i = 0; i < ARRAY_SIZE(waiters); i++)
3293474328c0SRoman Penyaev 		pthread_join(waiters[i], NULL);
3294474328c0SRoman Penyaev 
3295474328c0SRoman Penyaev 	for (i = 0; i < ARRAY_SIZE(waiters); i++)
3296474328c0SRoman Penyaev 		close(ctx.evfd[i]);
3297474328c0SRoman Penyaev 	close(ctx.epfd);
3298474328c0SRoman Penyaev }
3299474328c0SRoman Penyaev 
3300afabdf33SSoheil Hassas Yeganeh struct epoll61_ctx {
3301afabdf33SSoheil Hassas Yeganeh 	int epfd;
3302afabdf33SSoheil Hassas Yeganeh 	int evfd;
3303afabdf33SSoheil Hassas Yeganeh };
3304afabdf33SSoheil Hassas Yeganeh 
epoll61_write_eventfd(void * ctx_)3305afabdf33SSoheil Hassas Yeganeh static void *epoll61_write_eventfd(void *ctx_)
3306afabdf33SSoheil Hassas Yeganeh {
3307afabdf33SSoheil Hassas Yeganeh 	struct epoll61_ctx *ctx = ctx_;
3308afabdf33SSoheil Hassas Yeganeh 	int64_t l = 1;
3309afabdf33SSoheil Hassas Yeganeh 
3310afabdf33SSoheil Hassas Yeganeh 	usleep(10950);
3311afabdf33SSoheil Hassas Yeganeh 	write(ctx->evfd, &l, sizeof(l));
3312afabdf33SSoheil Hassas Yeganeh 	return NULL;
3313afabdf33SSoheil Hassas Yeganeh }
3314afabdf33SSoheil Hassas Yeganeh 
epoll61_epoll_with_timeout(void * ctx_)3315afabdf33SSoheil Hassas Yeganeh static void *epoll61_epoll_with_timeout(void *ctx_)
3316afabdf33SSoheil Hassas Yeganeh {
3317afabdf33SSoheil Hassas Yeganeh 	struct epoll61_ctx *ctx = ctx_;
3318afabdf33SSoheil Hassas Yeganeh 	struct epoll_event events[1];
3319afabdf33SSoheil Hassas Yeganeh 	int n;
3320afabdf33SSoheil Hassas Yeganeh 
3321afabdf33SSoheil Hassas Yeganeh 	n = epoll_wait(ctx->epfd, events, 1, 11);
3322afabdf33SSoheil Hassas Yeganeh 	/*
3323afabdf33SSoheil Hassas Yeganeh 	 * If epoll returned the eventfd, write on the eventfd to wake up the
3324afabdf33SSoheil Hassas Yeganeh 	 * blocking poller.
3325afabdf33SSoheil Hassas Yeganeh 	 */
3326afabdf33SSoheil Hassas Yeganeh 	if (n == 1) {
3327afabdf33SSoheil Hassas Yeganeh 		int64_t l = 1;
3328afabdf33SSoheil Hassas Yeganeh 
3329afabdf33SSoheil Hassas Yeganeh 		write(ctx->evfd, &l, sizeof(l));
3330afabdf33SSoheil Hassas Yeganeh 	}
3331afabdf33SSoheil Hassas Yeganeh 	return NULL;
3332afabdf33SSoheil Hassas Yeganeh }
3333afabdf33SSoheil Hassas Yeganeh 
epoll61_blocking_epoll(void * ctx_)3334afabdf33SSoheil Hassas Yeganeh static void *epoll61_blocking_epoll(void *ctx_)
3335afabdf33SSoheil Hassas Yeganeh {
3336afabdf33SSoheil Hassas Yeganeh 	struct epoll61_ctx *ctx = ctx_;
3337afabdf33SSoheil Hassas Yeganeh 	struct epoll_event events[1];
3338afabdf33SSoheil Hassas Yeganeh 
3339afabdf33SSoheil Hassas Yeganeh 	epoll_wait(ctx->epfd, events, 1, -1);
3340afabdf33SSoheil Hassas Yeganeh 	return NULL;
3341afabdf33SSoheil Hassas Yeganeh }
3342afabdf33SSoheil Hassas Yeganeh 
TEST(epoll61)3343afabdf33SSoheil Hassas Yeganeh TEST(epoll61)
3344afabdf33SSoheil Hassas Yeganeh {
3345afabdf33SSoheil Hassas Yeganeh 	struct epoll61_ctx ctx;
3346afabdf33SSoheil Hassas Yeganeh 	struct epoll_event ev;
3347afabdf33SSoheil Hassas Yeganeh 	int i, r;
3348afabdf33SSoheil Hassas Yeganeh 
3349afabdf33SSoheil Hassas Yeganeh 	ctx.epfd = epoll_create1(0);
3350afabdf33SSoheil Hassas Yeganeh 	ASSERT_GE(ctx.epfd, 0);
3351afabdf33SSoheil Hassas Yeganeh 	ctx.evfd = eventfd(0, EFD_NONBLOCK);
3352afabdf33SSoheil Hassas Yeganeh 	ASSERT_GE(ctx.evfd, 0);
3353afabdf33SSoheil Hassas Yeganeh 
3354afabdf33SSoheil Hassas Yeganeh 	ev.events = EPOLLIN | EPOLLET | EPOLLERR | EPOLLHUP;
3355afabdf33SSoheil Hassas Yeganeh 	ev.data.ptr = NULL;
3356afabdf33SSoheil Hassas Yeganeh 	r = epoll_ctl(ctx.epfd, EPOLL_CTL_ADD, ctx.evfd, &ev);
3357afabdf33SSoheil Hassas Yeganeh 	ASSERT_EQ(r, 0);
3358afabdf33SSoheil Hassas Yeganeh 
3359afabdf33SSoheil Hassas Yeganeh 	/*
3360afabdf33SSoheil Hassas Yeganeh 	 * We are testing a race.  Repeat the test case 1000 times to make it
3361afabdf33SSoheil Hassas Yeganeh 	 * more likely to fail in case of a bug.
3362afabdf33SSoheil Hassas Yeganeh 	 */
3363afabdf33SSoheil Hassas Yeganeh 	for (i = 0; i < 1000; i++) {
3364afabdf33SSoheil Hassas Yeganeh 		pthread_t threads[3];
3365afabdf33SSoheil Hassas Yeganeh 		int n;
3366afabdf33SSoheil Hassas Yeganeh 
3367afabdf33SSoheil Hassas Yeganeh 		/*
3368afabdf33SSoheil Hassas Yeganeh 		 * Start 3 threads:
3369afabdf33SSoheil Hassas Yeganeh 		 * Thread 1 sleeps for 10.9ms and writes to the evenfd.
3370afabdf33SSoheil Hassas Yeganeh 		 * Thread 2 calls epoll with a timeout of 11ms.
3371afabdf33SSoheil Hassas Yeganeh 		 * Thread 3 calls epoll with a timeout of -1.
3372afabdf33SSoheil Hassas Yeganeh 		 *
3373afabdf33SSoheil Hassas Yeganeh 		 * The eventfd write by Thread 1 should either wakeup Thread 2
3374afabdf33SSoheil Hassas Yeganeh 		 * or Thread 3.  If it wakes up Thread 2, Thread 2 writes on the
3375afabdf33SSoheil Hassas Yeganeh 		 * eventfd to wake up Thread 3.
3376afabdf33SSoheil Hassas Yeganeh 		 *
3377afabdf33SSoheil Hassas Yeganeh 		 * If no events are missed, all three threads should eventually
3378afabdf33SSoheil Hassas Yeganeh 		 * be joinable.
3379afabdf33SSoheil Hassas Yeganeh 		 */
3380afabdf33SSoheil Hassas Yeganeh 		ASSERT_EQ(pthread_create(&threads[0], NULL,
3381afabdf33SSoheil Hassas Yeganeh 					 epoll61_write_eventfd, &ctx), 0);
3382afabdf33SSoheil Hassas Yeganeh 		ASSERT_EQ(pthread_create(&threads[1], NULL,
3383afabdf33SSoheil Hassas Yeganeh 					 epoll61_epoll_with_timeout, &ctx), 0);
3384afabdf33SSoheil Hassas Yeganeh 		ASSERT_EQ(pthread_create(&threads[2], NULL,
3385afabdf33SSoheil Hassas Yeganeh 					 epoll61_blocking_epoll, &ctx), 0);
3386afabdf33SSoheil Hassas Yeganeh 
3387afabdf33SSoheil Hassas Yeganeh 		for (n = 0; n < ARRAY_SIZE(threads); ++n)
3388afabdf33SSoheil Hassas Yeganeh 			ASSERT_EQ(pthread_join(threads[n], NULL), 0);
3389afabdf33SSoheil Hassas Yeganeh 	}
3390afabdf33SSoheil Hassas Yeganeh 
3391afabdf33SSoheil Hassas Yeganeh 	close(ctx.epfd);
3392afabdf33SSoheil Hassas Yeganeh 	close(ctx.evfd);
3393afabdf33SSoheil Hassas Yeganeh }
3394afabdf33SSoheil Hassas Yeganeh 
3395e9ce39b5SWillem de Bruijn /* Equivalent to basic test epoll1, but exercising epoll_pwait2. */
TEST(epoll62)3396e9ce39b5SWillem de Bruijn TEST(epoll62)
3397e9ce39b5SWillem de Bruijn {
3398e9ce39b5SWillem de Bruijn 	int efd;
3399e9ce39b5SWillem de Bruijn 	int sfd[2];
3400e9ce39b5SWillem de Bruijn 	struct epoll_event e;
3401e9ce39b5SWillem de Bruijn 
3402e9ce39b5SWillem de Bruijn 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
3403e9ce39b5SWillem de Bruijn 
3404e9ce39b5SWillem de Bruijn 	efd = epoll_create(1);
3405e9ce39b5SWillem de Bruijn 	ASSERT_GE(efd, 0);
3406e9ce39b5SWillem de Bruijn 
3407e9ce39b5SWillem de Bruijn 	e.events = EPOLLIN;
3408e9ce39b5SWillem de Bruijn 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e), 0);
3409e9ce39b5SWillem de Bruijn 
3410e9ce39b5SWillem de Bruijn 	ASSERT_EQ(write(sfd[1], "w", 1), 1);
3411e9ce39b5SWillem de Bruijn 
3412e9ce39b5SWillem de Bruijn 	EXPECT_EQ(sys_epoll_pwait2(efd, &e, 1, NULL, NULL, 0), 1);
3413e9ce39b5SWillem de Bruijn 	EXPECT_EQ(sys_epoll_pwait2(efd, &e, 1, NULL, NULL, 0), 1);
3414e9ce39b5SWillem de Bruijn 
3415e9ce39b5SWillem de Bruijn 	close(efd);
3416e9ce39b5SWillem de Bruijn 	close(sfd[0]);
3417e9ce39b5SWillem de Bruijn 	close(sfd[1]);
3418e9ce39b5SWillem de Bruijn }
3419e9ce39b5SWillem de Bruijn 
3420e9ce39b5SWillem de Bruijn /* Epoll_pwait2 basic timeout test. */
TEST(epoll63)3421e9ce39b5SWillem de Bruijn TEST(epoll63)
3422e9ce39b5SWillem de Bruijn {
3423e9ce39b5SWillem de Bruijn 	const int cfg_delay_ms = 10;
3424e9ce39b5SWillem de Bruijn 	unsigned long long tdiff;
3425e9ce39b5SWillem de Bruijn 	struct __kernel_timespec ts;
3426e9ce39b5SWillem de Bruijn 	int efd;
3427e9ce39b5SWillem de Bruijn 	int sfd[2];
3428e9ce39b5SWillem de Bruijn 	struct epoll_event e;
3429e9ce39b5SWillem de Bruijn 
3430e9ce39b5SWillem de Bruijn 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sfd), 0);
3431e9ce39b5SWillem de Bruijn 
3432e9ce39b5SWillem de Bruijn 	efd = epoll_create(1);
3433e9ce39b5SWillem de Bruijn 	ASSERT_GE(efd, 0);
3434e9ce39b5SWillem de Bruijn 
3435e9ce39b5SWillem de Bruijn 	e.events = EPOLLIN;
3436e9ce39b5SWillem de Bruijn 	ASSERT_EQ(epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e), 0);
3437e9ce39b5SWillem de Bruijn 
3438e9ce39b5SWillem de Bruijn 	ts.tv_sec = 0;
3439e9ce39b5SWillem de Bruijn 	ts.tv_nsec = cfg_delay_ms * 1000 * 1000;
3440e9ce39b5SWillem de Bruijn 
3441e9ce39b5SWillem de Bruijn 	tdiff = msecs();
3442e9ce39b5SWillem de Bruijn 	EXPECT_EQ(sys_epoll_pwait2(efd, &e, 1, &ts, NULL, 0), 0);
3443e9ce39b5SWillem de Bruijn 	tdiff = msecs() - tdiff;
3444e9ce39b5SWillem de Bruijn 
3445e9ce39b5SWillem de Bruijn 	EXPECT_GE(tdiff, cfg_delay_ms);
3446e9ce39b5SWillem de Bruijn 
3447e9ce39b5SWillem de Bruijn 	close(efd);
3448e9ce39b5SWillem de Bruijn 	close(sfd[0]);
3449e9ce39b5SWillem de Bruijn 	close(sfd[1]);
3450e9ce39b5SWillem de Bruijn }
3451e9ce39b5SWillem de Bruijn 
3452*1e3b918dSDavidlohr Bueso /*
3453*1e3b918dSDavidlohr Bueso  *        t0    t1
3454*1e3b918dSDavidlohr Bueso  *     (ew) \  / (ew)
3455*1e3b918dSDavidlohr Bueso  *           e0
3456*1e3b918dSDavidlohr Bueso  *            | (lt)
3457*1e3b918dSDavidlohr Bueso  *           s0
3458*1e3b918dSDavidlohr Bueso  */
TEST(epoll64)3459*1e3b918dSDavidlohr Bueso TEST(epoll64)
3460*1e3b918dSDavidlohr Bueso {
3461*1e3b918dSDavidlohr Bueso 	pthread_t waiter[2];
3462*1e3b918dSDavidlohr Bueso 	struct epoll_event e;
3463*1e3b918dSDavidlohr Bueso 	struct epoll_mtcontext ctx = { 0 };
3464*1e3b918dSDavidlohr Bueso 
3465*1e3b918dSDavidlohr Bueso 	signal(SIGUSR1, signal_handler);
3466*1e3b918dSDavidlohr Bueso 
3467*1e3b918dSDavidlohr Bueso 	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx.sfd), 0);
3468*1e3b918dSDavidlohr Bueso 
3469*1e3b918dSDavidlohr Bueso 	ctx.efd[0] = epoll_create(1);
3470*1e3b918dSDavidlohr Bueso 	ASSERT_GE(ctx.efd[0], 0);
3471*1e3b918dSDavidlohr Bueso 
3472*1e3b918dSDavidlohr Bueso 	e.events = EPOLLIN;
3473*1e3b918dSDavidlohr Bueso 	ASSERT_EQ(epoll_ctl(ctx.efd[0], EPOLL_CTL_ADD, ctx.sfd[0], &e), 0);
3474*1e3b918dSDavidlohr Bueso 
3475*1e3b918dSDavidlohr Bueso 	/*
3476*1e3b918dSDavidlohr Bueso 	 * main will act as the emitter once both waiter threads are
3477*1e3b918dSDavidlohr Bueso 	 * blocked and expects to both be awoken upon the ready event.
3478*1e3b918dSDavidlohr Bueso 	 */
3479*1e3b918dSDavidlohr Bueso 	ctx.main = pthread_self();
3480*1e3b918dSDavidlohr Bueso 	ASSERT_EQ(pthread_create(&waiter[0], NULL, waiter_entry1a, &ctx), 0);
3481*1e3b918dSDavidlohr Bueso 	ASSERT_EQ(pthread_create(&waiter[1], NULL, waiter_entry1a, &ctx), 0);
3482*1e3b918dSDavidlohr Bueso 
3483*1e3b918dSDavidlohr Bueso 	usleep(100000);
3484*1e3b918dSDavidlohr Bueso 	ASSERT_EQ(write(ctx.sfd[1], "w", 1), 1);
3485*1e3b918dSDavidlohr Bueso 
3486*1e3b918dSDavidlohr Bueso 	ASSERT_EQ(pthread_join(waiter[0], NULL), 0);
3487*1e3b918dSDavidlohr Bueso 	ASSERT_EQ(pthread_join(waiter[1], NULL), 0);
3488*1e3b918dSDavidlohr Bueso 
3489*1e3b918dSDavidlohr Bueso 	EXPECT_EQ(ctx.count, 2);
3490*1e3b918dSDavidlohr Bueso 
3491*1e3b918dSDavidlohr Bueso 	close(ctx.efd[0]);
3492*1e3b918dSDavidlohr Bueso 	close(ctx.sfd[0]);
3493*1e3b918dSDavidlohr Bueso 	close(ctx.sfd[1]);
3494*1e3b918dSDavidlohr Bueso }
3495*1e3b918dSDavidlohr Bueso 
3496f2728fe8SHeiher TEST_HARNESS_MAIN
3497