VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTPoll.cpp@ 76553

Last change on this file since 76553 was 76553, checked in by vboxsync, 5 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.0 KB
Line 
1/* $Id: tstRTPoll.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * IPRT Testcase - RTPoll.
4 */
5
6/*
7 * Copyright (C) 2010-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/poll.h>
32
33#include <iprt/err.h>
34#include <iprt/file.h>
35#include <iprt/log.h>
36#include <iprt/mem.h>
37#include <iprt/pipe.h>
38#include <iprt/socket.h>
39#include <iprt/string.h>
40#include <iprt/tcp.h>
41#include <iprt/test.h>
42
43
44/*********************************************************************************************************************************
45* Global Variables *
46*********************************************************************************************************************************/
47/** What we write from the threads in test 3. */
48static char g_szHello[] = "hello!";
49
50
51static DECLCALLBACK(int) tstRTPoll3PipeWriteThread(RTTHREAD hSelf, void *pvUser)
52{
53 RT_NOREF_PV(hSelf);
54 RTPIPE hPipe = (RTPIPE)pvUser;
55 RTThreadSleep(RT_MS_1SEC);
56 return RTPipeWriteBlocking(hPipe, g_szHello, sizeof(g_szHello) - 1, NULL);
57}
58
59
60static DECLCALLBACK(int) tstRTPoll3SockWriteThread(RTTHREAD hSelf, void *pvUser)
61{
62 RT_NOREF_PV(hSelf);
63 RTSOCKET hSocket = (RTSOCKET)pvUser;
64 RTThreadSleep(RT_MS_1SEC);
65 return RTTcpWrite(hSocket, g_szHello, sizeof(g_szHello) - 1);
66}
67
68
69static void tstRTPoll3(void)
70{
71 RTTestISub("Pipe & Sockets");
72
73 /*
74 * Create a set and a pair of pipes and a pair of sockets.
75 */
76 RTPOLLSET hSet = NIL_RTPOLLSET;
77 RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
78 RTTESTI_CHECK_RETV(hSet != NIL_RTPOLLSET);
79
80 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 0);
81 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 0, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
82
83 RTPIPE hPipeR;
84 RTPIPE hPipeW;
85 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0/*fFlags*/), VINF_SUCCESS);
86
87 RTSOCKET hSocketR;
88 RTSOCKET hSocketW;
89 RTTESTI_CHECK_RC_RETV(RTTcpCreatePair(&hSocketR, &hSocketW, 0/*fFlags*/), VINF_SUCCESS);
90
91 /*
92 * Add them for error checking. These must be added first if want we their IDs
93 * to show up when disconnecting.
94 */
95 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_ERROR, 1 /*id*/), VINF_SUCCESS);
96 RTTESTI_CHECK_RC_RETV(RTPollSetAddSocket(hSet, hSocketR, RTPOLL_EVT_ERROR, 2 /*id*/), VINF_SUCCESS);
97 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 2);
98
99 /*
100 * Add the read ends. Polling should time out.
101 */
102 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_READ, 11 /*id*/), VINF_SUCCESS);
103 RTTESTI_CHECK_RC_RETV(RTPollSetAddSocket(hSet, hSocketR, RTPOLL_EVT_READ, 12 /*id*/), VINF_SUCCESS);
104
105 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 4);
106
107 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 11 /*id*/, NULL), VINF_SUCCESS);
108 RTHANDLE Handle;
109 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 11 /*id*/, &Handle), VINF_SUCCESS);
110 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
111 RTTESTI_CHECK(Handle.u.hPipe == hPipeR);
112
113 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 12 /*id*/, NULL), VINF_SUCCESS);
114 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 12 /*id*/, &Handle), VINF_SUCCESS);
115 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_SOCKET);
116 RTTESTI_CHECK(Handle.u.hSocket == hSocketR);
117
118 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VERR_TIMEOUT);
119 RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL, NULL), VERR_TIMEOUT);
120
121 /*
122 * Add the write ends. Should indicate that the first one is ready for writing.
123 */
124 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeW, RTPOLL_EVT_WRITE, 21 /*id*/), VINF_SUCCESS);
125 RTTESTI_CHECK_RC_RETV(RTPollSetAddSocket(hSet, hSocketW, RTPOLL_EVT_WRITE, 22 /*id*/), VINF_SUCCESS);
126
127 uint32_t idReady = UINT32_MAX;
128 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, &idReady), VINF_SUCCESS);
129 RTTESTI_CHECK(idReady == 21 || idReady == 22);
130
131 /*
132 * Remove the write ends again.
133 */
134 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 21), VINF_SUCCESS);
135 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 22), VINF_SUCCESS);
136 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VERR_TIMEOUT);
137
138 /*
139 * Kick off a thread that writes to the socket after 1 second.
140 * This will check that we can wait and wake up.
141 */
142 for (uint32_t i = 0; i < 2; i++)
143 {
144 RTTHREAD hThread;
145 RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstRTPoll3SockWriteThread, hSocketW, 0,
146 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test3sock"), VINF_SUCCESS);
147
148 uint32_t fEvents = 0;
149 idReady = 0;
150 uint64_t msStart = RTTimeSystemMilliTS();
151 RTTESTI_CHECK_RC(RTPoll(hSet, 5 * RT_MS_1SEC, &fEvents, &idReady), VINF_SUCCESS);
152 uint32_t msElapsed = RTTimeSystemMilliTS() - msStart;
153 RTTESTI_CHECK_MSG(msElapsed >= 250 && msElapsed < 4500, ("msElapsed=%RU64\n", msElapsed));
154 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
155 RTTESTI_CHECK(idReady == 12);
156
157 RTThreadWait(hThread, 5 * RT_MS_1SEC, NULL);
158
159 /* Drain the socket. */
160 char achBuf[128];
161 size_t cbRead = 0;
162 RTTESTI_CHECK_RC(RTTcpReadNB(hSocketR, achBuf, sizeof(achBuf), &cbRead), VINF_SUCCESS);
163 RTTESTI_CHECK(cbRead == sizeof(g_szHello) - 1 && memcmp(achBuf, g_szHello, sizeof(g_szHello) - 1) == 0);
164
165 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VERR_TIMEOUT);
166 RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL, NULL), VERR_TIMEOUT);
167 }
168
169 /*
170 * Kick off a thread that writes to the pipe after 1 second.
171 * This will check that we can wait and wake up.
172 */
173 for (uint32_t i = 0; i < 2; i++)
174 {
175 RTTHREAD hThread;
176 RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstRTPoll3PipeWriteThread, hPipeW, 0,
177 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test3pipe"), VINF_SUCCESS);
178
179 uint32_t fEvents = 0;
180 idReady = 0;
181 uint64_t msStart = RTTimeSystemMilliTS();
182 RTTESTI_CHECK_RC(RTPoll(hSet, 5 * RT_MS_1SEC, &fEvents, &idReady), VINF_SUCCESS);
183 uint32_t msElapsed = RTTimeSystemMilliTS() - msStart;
184 RTTESTI_CHECK_MSG(msElapsed >= 250 && msElapsed < 4500, ("msElapsed=%RU64\n", msElapsed));
185 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
186 RTTESTI_CHECK(idReady == 11);
187
188 RTThreadWait(hThread, 5 * RT_MS_1SEC, NULL);
189
190 /* Drain the socket. */
191 char achBuf[128];
192 size_t cbRead = 0;
193 RTTESTI_CHECK_RC(RTPipeRead(hPipeR, achBuf, sizeof(achBuf), &cbRead), VINF_SUCCESS);
194 RTTESTI_CHECK(cbRead == sizeof(g_szHello) - 1 && memcmp(achBuf, g_szHello, sizeof(g_szHello) - 1) == 0);
195
196 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VERR_TIMEOUT);
197 RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL, NULL), VERR_TIMEOUT);
198 }
199
200
201 /*
202 * Close the write socket, checking that we get error returns.
203 */
204 RTSocketShutdown(hSocketW, true, true);
205 RTSocketClose(hSocketW);
206
207 uint32_t fEvents = 0;
208 idReady = 0;
209 RTTESTI_CHECK_RC(RTPoll(hSet, 0, &fEvents, &idReady), VINF_SUCCESS);
210 RTTESTI_CHECK_MSG(idReady == 2 || idReady == 12, ("idReady=%u\n", idReady));
211 RTTESTI_CHECK_MSG(fEvents & RTPOLL_EVT_ERROR, ("fEvents=%#x\n", fEvents));
212
213 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 2), VINF_SUCCESS);
214 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 12), VINF_SUCCESS);
215
216 RTSocketClose(hSocketR);
217
218 /*
219 * Ditto for the pipe end.
220 */
221 RTPipeClose(hPipeW);
222
223 idReady = fEvents = 0;
224 RTTESTI_CHECK_RC(RTPoll(hSet, 0, &fEvents, &idReady), VINF_SUCCESS);
225 RTTESTI_CHECK_MSG(idReady == 1 || idReady == 11, ("idReady=%u\n", idReady));
226 RTTESTI_CHECK_MSG(fEvents & RTPOLL_EVT_ERROR, ("fEvents=%#x\n", fEvents));
227
228 RTPipeClose(hPipeR);
229
230 RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
231}
232
233
234static void tstRTPoll2(void)
235{
236 RTTestISub("Negative");
237
238 /*
239 * Bad set pointer and handle values.
240 */
241 RTTESTI_CHECK_RC(RTPollSetCreate(NULL), VERR_INVALID_POINTER);
242 RTPOLLSET hSetInvl = (RTPOLLSET)(intptr_t)-3;
243 RTTESTI_CHECK_RC(RTPollSetDestroy(hSetInvl), VERR_INVALID_HANDLE);
244 RTHANDLE Handle;
245 Handle.enmType = RTHANDLETYPE_PIPE;
246 Handle.u.hPipe = NIL_RTPIPE;
247 RTTESTI_CHECK_RC(RTPollSetAdd(hSetInvl, &Handle, RTPOLL_EVT_ERROR, 1), VERR_INVALID_HANDLE);
248 RTTESTI_CHECK_RC(RTPollSetRemove(hSetInvl, 1), VERR_INVALID_HANDLE);
249 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSetInvl, 1, NULL), VERR_INVALID_HANDLE);
250 RTTESTI_CHECK(RTPollSetGetCount(hSetInvl) == UINT32_MAX);
251 RTTESTI_CHECK_RC(RTPoll(hSetInvl, 0, NULL, NULL), VERR_INVALID_HANDLE);
252 RTTESTI_CHECK_RC(RTPollNoResume(hSetInvl, 0, NULL, NULL), VERR_INVALID_HANDLE);
253
254 /*
255 * Invalid arguments and other stuff.
256 */
257 RTPOLLSET hSet = NIL_RTPOLLSET;
258 RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
259
260 RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, NULL, NULL), VERR_DEADLOCK);
261 RTTESTI_CHECK_RC(RTPollNoResume(hSet, RT_INDEFINITE_WAIT, NULL, NULL), VERR_DEADLOCK);
262
263 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, UINT32_MAX), VERR_INVALID_PARAMETER);
264 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
265
266 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 1), VERR_POLL_HANDLE_ID_NOT_FOUND);
267
268 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, NULL, RTPOLL_EVT_ERROR, 1), VINF_SUCCESS);
269 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, RTPOLL_EVT_ERROR, UINT32_MAX), VERR_INVALID_PARAMETER);
270 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, UINT32_MAX, 3), VERR_INVALID_PARAMETER);
271 Handle.enmType = RTHANDLETYPE_INVALID;
272 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, RTPOLL_EVT_ERROR, 3), VERR_INVALID_PARAMETER);
273 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, NULL, RTPOLL_EVT_ERROR, UINT32_MAX), VERR_INVALID_PARAMETER);
274
275 /* duplicate id */
276 RTPIPE hPipeR;
277 RTPIPE hPipeW;
278 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0/*fFlags*/), VINF_SUCCESS);
279 RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_ERROR, 0), VINF_SUCCESS);
280 RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_ERROR, 0), VERR_POLL_HANDLE_ID_EXISTS);
281 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 0), VINF_SUCCESS);
282 RTPipeClose(hPipeR);
283 RTPipeClose(hPipeW);
284
285 /* non-pollable handle */
286 RTFILE hBitBucket;
287 RTTESTI_CHECK_RC_RETV(RTFileOpenBitBucket(&hBitBucket, RTFILE_O_WRITE), VINF_SUCCESS);
288 Handle.enmType = RTHANDLETYPE_FILE;
289 Handle.u.hFile = hBitBucket;
290 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, RTPOLL_EVT_WRITE, 10), VERR_POLL_HANDLE_NOT_POLLABLE);
291 RTFileClose(hBitBucket);
292
293 RTTESTI_CHECK_RC_RETV(RTPollSetDestroy(hSet), VINF_SUCCESS);
294}
295
296
297static void tstRTPoll1(void)
298{
299 RTTestISub("Basics");
300
301 /* create and destroy. */
302 RTPOLLSET hSet = NIL_RTPOLLSET;
303 RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
304 RTTESTI_CHECK_RETV(hSet != NIL_RTPOLLSET);
305 RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
306 RTTESTI_CHECK_RC(RTPollSetDestroy(NIL_RTPOLLSET), VINF_SUCCESS);
307
308 /* empty set, adding a NIL handle. */
309 hSet = NIL_RTPOLLSET;
310 RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
311 RTTESTI_CHECK_RETV(hSet != NIL_RTPOLLSET);
312
313 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 0);
314 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 0, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
315
316 RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, NIL_RTPIPE, RTPOLL_EVT_READ, 1 /*id*/), VINF_SUCCESS);
317 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 0);
318 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
319 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 0), VERR_POLL_HANDLE_ID_NOT_FOUND);
320 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 0);
321
322 RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
323
324 /*
325 * Set with pipes
326 */
327 RTPIPE hPipeR;
328 RTPIPE hPipeW;
329 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0/*fFlags*/), VINF_SUCCESS);
330
331 hSet = NIL_RTPOLLSET;
332 RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
333 RTTESTI_CHECK_RETV(hSet != NIL_RTPOLLSET);
334
335 /* add the read pipe */
336 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_READ, 1 /*id*/), VINF_SUCCESS);
337 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);
338 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VINF_SUCCESS);
339 RTHANDLE Handle;
340 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 1 /*id*/, &Handle), VINF_SUCCESS);
341 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
342 RTTESTI_CHECK(Handle.u.hPipe == hPipeR);
343
344 /* poll on the set, should time out. */
345 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VERR_TIMEOUT);
346 RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL, NULL), VERR_TIMEOUT);
347
348 /* add the write pipe with error detection only, check that poll still times out. remove it again. */
349 RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeW, RTPOLL_EVT_ERROR, 11 /*id*/), VINF_SUCCESS);
350 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 2);
351 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 11 /*id*/, NULL), VINF_SUCCESS);
352
353 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VERR_TIMEOUT);
354 RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL, NULL), VERR_TIMEOUT);
355
356 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 11), VINF_SUCCESS);
357 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);
358
359 /* add the write pipe */
360 RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeW, RTPOLL_EVT_WRITE, 10 /*id*/), VINF_SUCCESS);
361 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 2);
362 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 10 /*id*/, NULL), VINF_SUCCESS);
363
364 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
365 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
366 RTTESTI_CHECK(Handle.u.hPipe == hPipeW);
367
368 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 1 /*id*/, &Handle), VINF_SUCCESS);
369 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
370 RTTESTI_CHECK(Handle.u.hPipe == hPipeR);
371
372 /* poll on the set again, now it should indicate hPipeW is ready. */
373 int rc;
374 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VINF_SUCCESS);
375 RTTESTI_CHECK_RC(rc = RTPoll(hSet, 100, NULL, NULL), VINF_SUCCESS);
376 if (RT_SUCCESS(rc))
377 RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, NULL, NULL), VINF_SUCCESS);
378
379 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 0, NULL, NULL), VINF_SUCCESS);
380 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 100, NULL, NULL), VINF_SUCCESS);
381 if (RT_SUCCESS(rc))
382 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, RT_INDEFINITE_WAIT, NULL, NULL), VINF_SUCCESS);
383
384 uint32_t fEvents = UINT32_MAX;
385 uint32_t id = UINT32_MAX;
386 RTTESTI_CHECK_RC(RTPoll(hSet, 0, &fEvents, &id), VINF_SUCCESS);
387 RTTESTI_CHECK(id == 10);
388 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
389
390 fEvents = UINT32_MAX;
391 id = UINT32_MAX;
392 RTTESTI_CHECK_RC(rc = RTPoll(hSet, 250, &fEvents, &id), VINF_SUCCESS);
393 RTTESTI_CHECK(id == 10);
394 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
395
396 if (RT_SUCCESS(rc))
397 {
398 fEvents = UINT32_MAX;
399 id = UINT32_MAX;
400 RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
401 RTTESTI_CHECK(id == 10);
402 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
403 }
404
405 fEvents = UINT32_MAX;
406 id = UINT32_MAX;
407 RTTESTI_CHECK_RC(RTPollNoResume(hSet, 0, &fEvents, &id), VINF_SUCCESS);
408 RTTESTI_CHECK(id == 10);
409 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
410
411 fEvents = UINT32_MAX;
412 id = UINT32_MAX;
413 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 100, &fEvents, &id), VINF_SUCCESS);
414 RTTESTI_CHECK(id == 10);
415 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
416
417 if (RT_SUCCESS(rc))
418 {
419 fEvents = UINT32_MAX;
420 id = UINT32_MAX;
421 RTTESTI_CHECK_RC(RTPollNoResume(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
422 RTTESTI_CHECK(id == 10);
423 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
424 }
425
426 /* Write to the pipe. Currently ASSUMING we'll get the read ready now... Good idea? */
427 RTTESTI_CHECK_RC(rc = RTPipeWriteBlocking(hPipeW, "hello", 5, NULL), VINF_SUCCESS);
428 if (RT_SUCCESS(rc))
429 {
430 fEvents = UINT32_MAX;
431 id = UINT32_MAX;
432 RTTESTI_CHECK_RC(RTPoll(hSet, 0, &fEvents, &id), VINF_SUCCESS);
433 RTTESTI_CHECK(id == 1);
434 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
435
436 fEvents = UINT32_MAX;
437 id = UINT32_MAX;
438 RTTESTI_CHECK_RC(rc = RTPoll(hSet, 256, &fEvents, &id), VINF_SUCCESS);
439 RTTESTI_CHECK(id == 1);
440 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
441
442 if (RT_SUCCESS(rc))
443 {
444 fEvents = UINT32_MAX;
445 id = UINT32_MAX;
446 RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
447 RTTESTI_CHECK(id == 1);
448 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
449 }
450
451 fEvents = UINT32_MAX;
452 id = UINT32_MAX;
453 RTTESTI_CHECK_RC(RTPollNoResume(hSet, 0, &fEvents, &id), VINF_SUCCESS);
454 RTTESTI_CHECK(id == 1);
455 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
456
457 fEvents = UINT32_MAX;
458 id = UINT32_MAX;
459 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 383, &fEvents, &id), VINF_SUCCESS);
460 RTTESTI_CHECK(id == 1);
461 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
462
463 if (RT_SUCCESS(rc))
464 {
465 fEvents = UINT32_MAX;
466 id = UINT32_MAX;
467 RTTESTI_CHECK_RC(RTPollNoResume(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
468 RTTESTI_CHECK(id == 1);
469 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
470 }
471 }
472
473 /* Remove the read pipe, do a quick poll check. */
474 RTTESTI_CHECK_RC_RETV(RTPollSetRemove(hSet, 1), VINF_SUCCESS);
475 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);
476 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
477 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
478 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
479 RTTESTI_CHECK(Handle.u.hPipe == hPipeW);
480
481 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VINF_SUCCESS);
482
483 /* Add it back and check that we now get the write handle when polling.
484 (Is this FIFOing a good idea?) */
485 RTTESTI_CHECK_RC_RETV(RTPoll(hSet, 0, NULL, NULL), VINF_SUCCESS);
486
487 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_READ, 1 /*id*/), VINF_SUCCESS);
488 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 2);
489 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VINF_SUCCESS);
490
491 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 1 /*id*/, &Handle), VINF_SUCCESS);
492 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
493 RTTESTI_CHECK(Handle.u.hPipe == hPipeR);
494
495 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
496 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
497 RTTESTI_CHECK(Handle.u.hPipe == hPipeW);
498
499 fEvents = UINT32_MAX;
500 id = UINT32_MAX;
501 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 555, &fEvents, &id), VINF_SUCCESS);
502 RTTESTI_CHECK(id == 10);
503 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
504
505 /* Remove it again and break the pipe by closing the read end. */
506 RTTESTI_CHECK_RC_RETV(RTPollSetRemove(hSet, 1), VINF_SUCCESS);
507 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);
508 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
509 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
510 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
511 RTTESTI_CHECK(Handle.u.hPipe == hPipeW);
512
513 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VINF_SUCCESS);
514
515 RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
516
517 fEvents = UINT32_MAX;
518 id = UINT32_MAX;
519 RTTESTI_CHECK_RC(RTPollNoResume(hSet, 0, &fEvents, &id), VINF_SUCCESS);
520 RTTESTI_CHECK(id == 10);
521 RTTESTI_CHECK_MSG( fEvents == RTPOLL_EVT_ERROR \
522 || fEvents == (RTPOLL_EVT_ERROR | RTPOLL_EVT_WRITE), ("%#x\n", fEvents));
523
524 RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
525 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
526
527 /*
528 * Check FIFO order when removing and adding.
529 *
530 * Note! FIFO order is not guaranteed when a handle has more than one entry
531 * in the set.
532 */
533 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0/*fFlags*/), VINF_SUCCESS);
534 RTPIPE hPipeR2, hPipeW2;
535 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR2, &hPipeW2, 0/*fFlags*/), VINF_SUCCESS);
536 RTPIPE hPipeR3, hPipeW3;
537 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR3, &hPipeW3, 0/*fFlags*/), VINF_SUCCESS);
538 RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
539 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_READ, 1 /*id*/), VINF_SUCCESS);
540 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeW, RTPOLL_EVT_WRITE, 2 /*id*/), VINF_SUCCESS);
541 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR2, RTPOLL_EVT_READ, 3 /*id*/), VINF_SUCCESS);
542 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeW2, RTPOLL_EVT_WRITE, 4 /*id*/), VINF_SUCCESS);
543 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR3, RTPOLL_EVT_READ, 5 /*id*/), VINF_SUCCESS);
544
545 id = UINT32_MAX; fEvents = UINT32_MAX;
546 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
547 RTTESTI_CHECK(id == 2);
548 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
549
550 RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW, "hello", 5, NULL), VINF_SUCCESS);
551 RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW2, "hello", 5, NULL), VINF_SUCCESS);
552 RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW3, "hello", 5, NULL), VINF_SUCCESS);
553 id = UINT32_MAX; fEvents = UINT32_MAX;
554 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
555 RTTESTI_CHECK(id == 1);
556 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
557
558 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 1), VINF_SUCCESS);
559 id = UINT32_MAX; fEvents = UINT32_MAX;
560 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
561 RTTESTI_CHECK(id == 2);
562 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
563
564 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 2), VINF_SUCCESS);
565 id = UINT32_MAX; fEvents = UINT32_MAX;
566 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
567 RTTESTI_CHECK(id == 3);
568 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
569
570 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 3), VINF_SUCCESS);
571 id = UINT32_MAX; fEvents = UINT32_MAX;
572 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
573 RTTESTI_CHECK(id == 4);
574 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
575
576 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 4), VINF_SUCCESS);
577 id = UINT32_MAX; fEvents = UINT32_MAX;
578 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
579 RTTESTI_CHECK(id == 5);
580 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
581
582 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 5), VINF_SUCCESS);
583 id = UINT32_MAX; fEvents = UINT32_MAX;
584 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VERR_TIMEOUT);
585
586 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
587 RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
588 RTTESTI_CHECK_RC(RTPipeClose(hPipeW2), VINF_SUCCESS);
589 RTTESTI_CHECK_RC(RTPipeClose(hPipeR2), VINF_SUCCESS);
590 RTTESTI_CHECK_RC(RTPipeClose(hPipeW3), VINF_SUCCESS);
591 RTTESTI_CHECK_RC(RTPipeClose(hPipeR3), VINF_SUCCESS);
592 RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
593
594}
595
596int main()
597{
598 RTTEST hTest;
599 int rc = RTTestInitAndCreate("tstRTPoll", &hTest);
600 if (rc)
601 return rc;
602 RTTestBanner(hTest);
603
604 /*
605 * The tests.
606 */
607 tstRTPoll1();
608 if (RTTestErrorCount(hTest) == 0)
609 {
610 bool fMayPanic = RTAssertMayPanic();
611 bool fQuiet = RTAssertAreQuiet();
612 RTAssertSetMayPanic(false);
613 RTAssertSetQuiet(true);
614 tstRTPoll2();
615 RTAssertSetQuiet(fQuiet);
616 RTAssertSetMayPanic(fMayPanic);
617
618 tstRTPoll3();
619 }
620
621 /*
622 * Summary.
623 */
624 return RTTestSummaryAndDestroy(hTest);
625}
626
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use