1 /*
2  * Copyright (c) 2020 Tobias Svehagen
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "_main.h"
8 
reopen(int * fd,int initval,int flags)9 void reopen(int *fd, int initval, int flags)
10 {
11 	zassert_not_null(fd);
12 	zassert_ok(close(*fd));
13 	*fd = eventfd(initval, flags);
14 	zassert_true(*fd >= 0, "eventfd(%d, %d) failed: %d", initval, flags, errno);
15 }
16 
is_blocked(int fd,short * event)17 int is_blocked(int fd, short *event)
18 {
19 	struct pollfd pfd;
20 	int ret;
21 
22 	pfd.fd = fd;
23 	pfd.events = *event;
24 
25 	ret = poll(&pfd, 1, 0);
26 	zassert_true(ret >= 0, "poll failed %d", ret);
27 
28 	*event = pfd.revents;
29 
30 	return ret == 0;
31 }
32 
eventfd_poll_unset_common(int fd)33 void eventfd_poll_unset_common(int fd)
34 {
35 	eventfd_t val = 0;
36 	short event;
37 	int ret;
38 
39 	event = POLLIN;
40 	ret = is_blocked(fd, &event);
41 	zassert_equal(ret, 1, "eventfd not blocked with initval == 0");
42 
43 	ret = eventfd_write(fd, TESTVAL);
44 	zassert_equal(ret, 0, "write ret %d", ret);
45 
46 	event = POLLIN;
47 	ret = is_blocked(fd, &event);
48 	zassert_equal(ret, 0, "eventfd blocked after write");
49 	zassert_equal(event, POLLIN, "POLLIN not set");
50 
51 	ret = eventfd_write(fd, TESTVAL);
52 	zassert_equal(ret, 0, "write ret %d", ret);
53 
54 	ret = eventfd_read(fd, &val);
55 	zassert_equal(ret, 0, "read ret %d", ret);
56 	zassert_equal(val, 2*TESTVAL, "val == %d, expected %d", val, TESTVAL);
57 
58 	/* eventfd shall block on subsequent reads */
59 
60 	event = POLLIN;
61 	ret = is_blocked(fd, &event);
62 	zassert_equal(ret, 1, "eventfd not blocked after read");
63 }
64 
eventfd_poll_set_common(int fd)65 void eventfd_poll_set_common(int fd)
66 {
67 	eventfd_t val = 0;
68 	short event;
69 	int ret;
70 
71 	event = POLLIN;
72 	ret = is_blocked(fd, &event);
73 	zassert_equal(ret, 0, "eventfd is blocked with initval != 0");
74 
75 	ret = eventfd_read(fd, &val);
76 	zassert_equal(ret, 0, "read ret %d", ret);
77 	zassert_equal(val, TESTVAL, "val == %d", val);
78 
79 	event = POLLIN;
80 	ret = is_blocked(fd, &event);
81 	zassert_equal(ret, 1, "eventfd is not blocked after read");
82 }
83 
84 static struct eventfd_fixture efd_fixture;
85 
setup(void)86 static void *setup(void)
87 {
88 	efd_fixture.fd = -1;
89 	return &efd_fixture;
90 }
91 
before(void * arg)92 static void before(void *arg)
93 {
94 	struct eventfd_fixture *fixture = arg;
95 
96 	fixture->fd = eventfd(0, 0);
97 	zassert_true(fixture->fd >= 0, "eventfd(0, 0) failed: %d", errno);
98 }
99 
after(void * arg)100 static void after(void *arg)
101 {
102 	struct eventfd_fixture *fixture = arg;
103 
104 	close(fixture->fd);
105 	fixture->fd = -1;
106 }
107 
108 ZTEST_SUITE(eventfd, NULL, setup, before, after, NULL);
109