master
c 289 lines 7.52 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 EventFd.c
8
9 Abstract:
10
11 This file is a eventfd test.
12
13 --*/
14
15 #include "lxtcommon.h"
16 #include "unittests.h"
17 #include <sys/types.h>
18 #include <sys/wait.h>
19 #include <sys/epoll.h>
20 #include <sys/eventfd.h>
21
22 #define LXT_NAME "EventFd"
23
24 #define DEFAULT_USLEEP 5000
25
26 int EventFdVariationReadWrite(PLXT_ARGS Args);
27
28 //
29 // Global constants
30 //
31
32 static const LXT_VARIATION g_LxtVariations[] = {{"EventFdVariation - read, write", EventFdVariationReadWrite}};
33
34 int EventfdTestEntry(int Argc, char* Argv[])
35
36 /*++
37 --*/
38
39 {
40
41 LXT_ARGS Args;
42 int Result;
43
44 LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
45 LXT_SYNCHRONIZATION_POINT_INIT();
46 LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
47
48 ErrorExit:
49 LXT_SYNCHRONIZATION_POINT_DESTROY();
50 LxtUninitialize();
51 return !LXT_SUCCESS(Result);
52 }
53
54 int EventFdVariationReadWrite(PLXT_ARGS Args)
55
56 /*++
57 --*/
58
59 {
60
61 pid_t ChildPid;
62 struct epoll_event EpollEvent;
63 int EpollFd;
64 int Fd;
65 int Index;
66 fd_set ReadFds;
67 int Result;
68 ssize_t Size;
69 int Status;
70 struct timeval Timeout;
71 uint64_t Value;
72 uint64_t Values[] = {1, 2, 10, 0xFFFFFFFF, 0xFFFFFFFFFFFFFFFE};
73 struct
74 {
75 uint64_t Value;
76 char Buffer[32];
77 } LargeValue;
78
79 EpollFd = -1;
80 LXT_SYNCHRONIZATION_POINT_START();
81
82 //
83 // FIXME: Add 0 variation
84 //
85
86 //
87 // Write the values to the event and read them back out single threaded.
88 //
89
90 LxtCheckErrno(Fd = eventfd(0, 0));
91 for (Index = 0; Index < LXT_COUNT_OF(Values); Index += 1)
92 {
93
94 //
95 // Verify that the event is not ready for read (value is zero).
96 //
97
98 memset(&Timeout, 0, sizeof(Timeout));
99 FD_ZERO(&ReadFds);
100 FD_SET(Fd, &ReadFds);
101 LxtCheckErrno(select((Fd + 1), &ReadFds, NULL, NULL, &Timeout));
102 LxtCheckEqual(Result, 0, "%d");
103
104 Value = Values[Index];
105 Size = write(Fd, &Value, sizeof(Value));
106 LxtCheckEqual(Size, sizeof(Value), "%lld");
107 LxtCheckEqual(Value, Values[Index], "%llu");
108
109 //
110 // Verify that the event is ready for read (value is NOT zero).
111 //
112
113 memset(&Timeout, 0, sizeof(Timeout));
114 FD_ZERO(&ReadFds);
115 FD_SET(Fd, &ReadFds);
116 LxtCheckErrno(select((Fd + 1), &ReadFds, NULL, NULL, &Timeout));
117 LxtCheckEqual(Result, 1, "%d");
118
119 //
120 // Check again to verify nothing has changed.
121 //
122
123 memset(&Timeout, 0, sizeof(Timeout));
124 FD_ZERO(&ReadFds);
125 FD_SET(Fd, &ReadFds);
126 LxtCheckErrno(select((Fd + 1), &ReadFds, NULL, NULL, &Timeout));
127 LxtCheckEqual(Result, 1, "%d");
128
129 Value = 0;
130 Size = read(Fd, &Value, sizeof(Value));
131 LxtCheckEqual(Size, sizeof(Value), "%lld");
132 LxtCheckEqual(Value, Values[Index], "%llu");
133 }
134
135 //
136 // Verify that the event is not ready for read (value is zero).
137 //
138
139 memset(&Timeout, 0, sizeof(Timeout));
140 FD_ZERO(&ReadFds);
141 FD_SET(Fd, &ReadFds);
142 LxtCheckErrno(select((Fd + 1), &ReadFds, NULL, NULL, &Timeout));
143 LxtCheckEqual(Result, 0, "%d");
144
145 //
146 // Write the values to the event and read them back out on another thread.
147 //
148
149 LxtCheckErrno(ChildPid = fork());
150 if (ChildPid == 0)
151 {
152 LxtCheckErrno(EpollFd = epoll_create(1));
153 EpollEvent.events = EPOLLIN | EPOLLET;
154 EpollEvent.data.fd = Fd;
155 LxtCheckErrno(epoll_ctl(EpollFd, EPOLL_CTL_ADD, Fd, &EpollEvent));
156 }
157
158 LXT_SYNCHRONIZATION_POINT();
159 for (Index = 0; Index < LXT_COUNT_OF(Values); Index += 1)
160 {
161 if (ChildPid == 0)
162 {
163
164 //
165 // Ignore the first value completely and don't read the second
166 // value to verify that epoll edge-triggered behavior is working as
167 // expected.
168 //
169
170 if (Index > 0)
171 {
172 if (Index == 1)
173 {
174
175 //
176 // Since the first write was ignored, need to make sure
177 // that the second has completed so that the edge-triggered
178 // epoll logic works as expected instead of racing with the
179 // next write.
180 //
181
182 LXT_SYNCHRONIZATION_POINT();
183 }
184
185 LxtLogInfo("Waiting from child thread...");
186 LxtCheckErrno(epoll_wait(EpollFd, &EpollEvent, 1, -1));
187 LxtCheckEqual(Result, 1, "%d") LxtCheckEqual(EpollEvent.data.fd, Fd, "%d");
188
189 //
190 // The epoll should be blocked.
191 //
192
193 LxtCheckErrno(epoll_wait(EpollFd, &EpollEvent, 1, 0));
194 LxtCheckEqual(Result, 0, "%d");
195
196 //
197 // Skip the first two values to verify epoll edge-triggered
198 // behavior and then start verifying the value data.
199 //
200
201 if (Index > 1)
202 {
203 Value = 0;
204 Size = read(Fd, &Value, sizeof(Value));
205 LxtCheckEqual(Size, sizeof(Value), "%lld");
206 if (Index == 2)
207 {
208 LxtCheckEqual(Value, (Values[0] + Values[1] + Values[2]), "%llu");
209 }
210 else
211 {
212 LxtCheckEqual(Value, Values[Index], "%llu");
213 }
214 }
215
216 //
217 // The epoll should still be blocked.
218 //
219
220 LxtCheckErrno(epoll_wait(EpollFd, &EpollEvent, 1, 0));
221 LxtCheckEqual(Result, 0, "%d")
222 }
223 }
224 else
225 {
226 LxtLogInfo("Writing 0x%llx from parent thread...", Values[Index]);
227 Value = Values[Index];
228 Size = write(Fd, &Value, sizeof(Value));
229 LxtCheckEqual(Size, sizeof(Value), "%lld");
230 LxtCheckEqual(Value, Values[Index], "%llu");
231 if (Index == 1)
232 {
233 LXT_SYNCHRONIZATION_POINT();
234 }
235 }
236
237 LXT_SYNCHRONIZATION_POINT();
238 }
239
240 if (ChildPid == 0)
241 {
242 goto ErrorExit;
243 }
244
245 //
246 // Read and write out with a buffer larger than the default.
247 //
248
249 memset(&LargeValue, 0, sizeof(LargeValue));
250 LargeValue.Value = 1;
251 Size = write(Fd, &LargeValue, sizeof(LargeValue.Value));
252 LxtCheckEqual(Size, sizeof(LargeValue.Value), "%lld");
253 LxtCheckEqual(LargeValue.Value, 1, "%llu");
254
255 LargeValue.Value = 0;
256 Size = read(Fd, &LargeValue, sizeof(LargeValue.Value));
257 LxtCheckEqual(Size, sizeof(LargeValue.Value), "%lld");
258 LxtCheckEqual(LargeValue.Value, 1, "%llu");
259
260 //
261 // Check the error code for writing the maximum value.
262 //
263
264 Value = 0xFFFFFFFFFFFFFFFF;
265 LxtCheckErrnoFailure(write(Fd, &Value, sizeof(Value)), EINVAL);
266
267 //
268 // Check the error code for reading and writing a size of 0.
269 //
270
271 LxtCheckErrnoFailure(read(Fd, &Value, 0), EINVAL);
272 LxtCheckErrnoFailure(write(Fd, &Value, 0), EINVAL);
273
274 Result = LXT_RESULT_SUCCESS;
275
276 ErrorExit:
277 if (Fd > 0)
278 {
279 close(Fd);
280 }
281
282 if (EpollFd > 0)
283 {
284 close(EpollFd);
285 }
286
287 LXT_SYNCHRONIZATION_POINT_END();
288 return Result;
289 }