VirtualBox

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

Last change on this file since 93115 was 93115, checked in by vboxsync, 3 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.3 KB
Line 
1/* $Id: tstRTPoll.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * IPRT Testcase - RTPoll.
4 */
5
6/*
7 * Copyright (C) 2010-2022 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 char achBuf[128];
143 size_t cbRead;
144 for (uint32_t i = 0; i < 2; i++)
145 {
146 RTTHREAD hThread;
147 RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstRTPoll3SockWriteThread, hSocketW, 0,
148 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test3sock"), VINF_SUCCESS);
149
150 uint32_t fEvents = 0;
151 idReady = 0;
152 uint64_t msStart = RTTimeSystemMilliTS();
153 RTTESTI_CHECK_RC(RTPoll(hSet, 5 * RT_MS_1SEC, &fEvents, &idReady), VINF_SUCCESS);
154 uint32_t msElapsed = RTTimeSystemMilliTS() - msStart;
155 RTTESTI_CHECK_MSG(msElapsed >= 250 && msElapsed < 4500, ("msElapsed=%RU64\n", msElapsed));
156 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
157 RTTESTI_CHECK(idReady == 12);
158
159 RTThreadWait(hThread, 5 * RT_MS_1SEC, NULL);
160
161 /* Drain the socket. */
162 cbRead = 0;
163 RTTESTI_CHECK_RC(RTTcpReadNB(hSocketR, achBuf, sizeof(achBuf), &cbRead), VINF_SUCCESS);
164 RTTESTI_CHECK(cbRead == sizeof(g_szHello) - 1 && memcmp(achBuf, g_szHello, sizeof(g_szHello) - 1) == 0);
165
166 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VERR_TIMEOUT);
167 RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL, NULL), VERR_TIMEOUT);
168 }
169
170 /*
171 * Kick off a thread that writes to the pipe after 1 second.
172 * This will check that we can wait and wake up.
173 */
174 for (uint32_t i = 0; i < 2; i++)
175 {
176 RTTHREAD hThread;
177 RTTESTI_CHECK_RC(RTThreadCreate(&hThread, tstRTPoll3PipeWriteThread, hPipeW, 0,
178 RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test3pipe"), VINF_SUCCESS);
179
180 uint32_t fEvents = 0;
181 idReady = 0;
182 uint64_t msStart = RTTimeSystemMilliTS();
183 RTTESTI_CHECK_RC(RTPoll(hSet, 5 * RT_MS_1SEC, &fEvents, &idReady), VINF_SUCCESS);
184 uint32_t msElapsed = RTTimeSystemMilliTS() - msStart;
185 RTTESTI_CHECK_MSG(msElapsed >= 250 && msElapsed < 4500, ("msElapsed=%RU64\n", msElapsed));
186 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
187 RTTESTI_CHECK(idReady == 11);
188
189 RTThreadWait(hThread, 5 * RT_MS_1SEC, NULL);
190
191 /* Drain the socket. */
192 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 RTTESTI_CHECK_RC(RTTcpReadNB(hSocketR, achBuf, sizeof(achBuf), &cbRead), VINF_SUCCESS);
217 RTTESTI_CHECK(cbRead == 0);
218
219 RTTESTI_CHECK_RC(RTTcpRead(hSocketR, achBuf, 1, &cbRead), VINF_SUCCESS);
220 RTTESTI_CHECK(cbRead == 0);
221
222 RTSocketClose(hSocketR);
223
224 /*
225 * Ditto for the pipe end.
226 */
227 RTPipeClose(hPipeW);
228
229 idReady = fEvents = 0;
230 RTTESTI_CHECK_RC(RTPoll(hSet, 0, &fEvents, &idReady), VINF_SUCCESS);
231 RTTESTI_CHECK_MSG(idReady == 1 || idReady == 11, ("idReady=%u\n", idReady));
232 RTTESTI_CHECK_MSG(fEvents & RTPOLL_EVT_ERROR, ("fEvents=%#x\n", fEvents));
233
234 cbRead = 0;
235 RTTESTI_CHECK_RC(RTPipeRead(hPipeR, achBuf, sizeof(achBuf), &cbRead), VERR_BROKEN_PIPE);
236 RTTESTI_CHECK(cbRead == 0);
237
238 RTPipeClose(hPipeR);
239
240 RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
241}
242
243
244static void tstRTPoll2(void)
245{
246 RTTestISub("Negative");
247
248 /*
249 * Bad set pointer and handle values.
250 */
251 RTTESTI_CHECK_RC(RTPollSetCreate(NULL), VERR_INVALID_POINTER);
252 RTPOLLSET hSetInvl = (RTPOLLSET)(intptr_t)-3;
253 RTTESTI_CHECK_RC(RTPollSetDestroy(hSetInvl), VERR_INVALID_HANDLE);
254 RTHANDLE Handle;
255 Handle.enmType = RTHANDLETYPE_PIPE;
256 Handle.u.hPipe = NIL_RTPIPE;
257 RTTESTI_CHECK_RC(RTPollSetAdd(hSetInvl, &Handle, RTPOLL_EVT_ERROR, 1), VERR_INVALID_HANDLE);
258 RTTESTI_CHECK_RC(RTPollSetRemove(hSetInvl, 1), VERR_INVALID_HANDLE);
259 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSetInvl, 1, NULL), VERR_INVALID_HANDLE);
260 RTTESTI_CHECK(RTPollSetGetCount(hSetInvl) == UINT32_MAX);
261 RTTESTI_CHECK_RC(RTPoll(hSetInvl, 0, NULL, NULL), VERR_INVALID_HANDLE);
262 RTTESTI_CHECK_RC(RTPollNoResume(hSetInvl, 0, NULL, NULL), VERR_INVALID_HANDLE);
263
264 /*
265 * Invalid arguments and other stuff.
266 */
267 RTPOLLSET hSet = NIL_RTPOLLSET;
268 RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
269
270 RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, NULL, NULL), VERR_DEADLOCK);
271 RTTESTI_CHECK_RC(RTPollNoResume(hSet, RT_INDEFINITE_WAIT, NULL, NULL), VERR_DEADLOCK);
272
273 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, UINT32_MAX), VERR_INVALID_PARAMETER);
274 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
275
276 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 1), VERR_POLL_HANDLE_ID_NOT_FOUND);
277
278 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, NULL, RTPOLL_EVT_ERROR, 1), VINF_SUCCESS);
279 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, RTPOLL_EVT_ERROR, UINT32_MAX), VERR_INVALID_PARAMETER);
280 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, UINT32_MAX, 3), VERR_INVALID_PARAMETER);
281 Handle.enmType = RTHANDLETYPE_INVALID;
282 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, RTPOLL_EVT_ERROR, 3), VERR_INVALID_PARAMETER);
283 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, NULL, RTPOLL_EVT_ERROR, UINT32_MAX), VERR_INVALID_PARAMETER);
284
285 /* duplicate id */
286 RTPIPE hPipeR;
287 RTPIPE hPipeW;
288 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0/*fFlags*/), VINF_SUCCESS);
289 RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_ERROR, 0), VINF_SUCCESS);
290 RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_ERROR, 0), VERR_POLL_HANDLE_ID_EXISTS);
291 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 0), VINF_SUCCESS);
292 RTPipeClose(hPipeR);
293 RTPipeClose(hPipeW);
294
295 /* non-pollable handle */
296 RTFILE hBitBucket;
297 RTTESTI_CHECK_RC_RETV(RTFileOpenBitBucket(&hBitBucket, RTFILE_O_WRITE), VINF_SUCCESS);
298 Handle.enmType = RTHANDLETYPE_FILE;
299 Handle.u.hFile = hBitBucket;
300 RTTESTI_CHECK_RC(RTPollSetAdd(hSet, &Handle, RTPOLL_EVT_WRITE, 10), VERR_POLL_HANDLE_NOT_POLLABLE);
301 RTFileClose(hBitBucket);
302
303 RTTESTI_CHECK_RC_RETV(RTPollSetDestroy(hSet), VINF_SUCCESS);
304}
305
306
307static void tstRTPoll1(void)
308{
309 RTTestISub("Basics");
310
311 /* create and destroy. */
312 RTPOLLSET hSet = NIL_RTPOLLSET;
313 RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
314 RTTESTI_CHECK_RETV(hSet != NIL_RTPOLLSET);
315 RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
316 RTTESTI_CHECK_RC(RTPollSetDestroy(NIL_RTPOLLSET), VINF_SUCCESS);
317
318 /* empty set, adding a NIL handle. */
319 hSet = NIL_RTPOLLSET;
320 RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
321 RTTESTI_CHECK_RETV(hSet != NIL_RTPOLLSET);
322
323 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 0);
324 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 0, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
325
326 RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, NIL_RTPIPE, RTPOLL_EVT_READ, 1 /*id*/), VINF_SUCCESS);
327 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 0);
328 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
329 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 0), VERR_POLL_HANDLE_ID_NOT_FOUND);
330 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 0);
331
332 RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
333
334 /*
335 * Set with pipes
336 */
337 RTPIPE hPipeR;
338 RTPIPE hPipeW;
339 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0/*fFlags*/), VINF_SUCCESS);
340
341 hSet = NIL_RTPOLLSET;
342 RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
343 RTTESTI_CHECK_RETV(hSet != NIL_RTPOLLSET);
344
345 /* add the read pipe */
346 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_READ, 1 /*id*/), VINF_SUCCESS);
347 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);
348 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VINF_SUCCESS);
349 RTHANDLE Handle;
350 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 1 /*id*/, &Handle), VINF_SUCCESS);
351 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
352 RTTESTI_CHECK(Handle.u.hPipe == hPipeR);
353
354 /* poll on the set, should time out. */
355 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VERR_TIMEOUT);
356 RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL, NULL), VERR_TIMEOUT);
357
358 /* add the write pipe with error detection only, check that poll still times out. remove it again. */
359 RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeW, RTPOLL_EVT_ERROR, 11 /*id*/), VINF_SUCCESS);
360 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 2);
361 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 11 /*id*/, NULL), VINF_SUCCESS);
362
363 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VERR_TIMEOUT);
364 RTTESTI_CHECK_RC(RTPoll(hSet, 1, NULL, NULL), VERR_TIMEOUT);
365
366 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 11), VINF_SUCCESS);
367 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);
368
369 /* add the write pipe */
370 RTTESTI_CHECK_RC(RTPollSetAddPipe(hSet, hPipeW, RTPOLL_EVT_WRITE, 10 /*id*/), VINF_SUCCESS);
371 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 2);
372 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 10 /*id*/, NULL), VINF_SUCCESS);
373
374 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
375 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
376 RTTESTI_CHECK(Handle.u.hPipe == hPipeW);
377
378 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 1 /*id*/, &Handle), VINF_SUCCESS);
379 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
380 RTTESTI_CHECK(Handle.u.hPipe == hPipeR);
381
382 /* poll on the set again, now it should indicate hPipeW is ready. */
383 int rc;
384 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VINF_SUCCESS);
385 RTTESTI_CHECK_RC(rc = RTPoll(hSet, 100, NULL, NULL), VINF_SUCCESS);
386 if (RT_SUCCESS(rc))
387 RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, NULL, NULL), VINF_SUCCESS);
388
389 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 0, NULL, NULL), VINF_SUCCESS);
390 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 100, NULL, NULL), VINF_SUCCESS);
391 if (RT_SUCCESS(rc))
392 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, RT_INDEFINITE_WAIT, NULL, NULL), VINF_SUCCESS);
393
394 uint32_t fEvents = UINT32_MAX;
395 uint32_t id = UINT32_MAX;
396 RTTESTI_CHECK_RC(RTPoll(hSet, 0, &fEvents, &id), VINF_SUCCESS);
397 RTTESTI_CHECK(id == 10);
398 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
399
400 fEvents = UINT32_MAX;
401 id = UINT32_MAX;
402 RTTESTI_CHECK_RC(rc = RTPoll(hSet, 250, &fEvents, &id), VINF_SUCCESS);
403 RTTESTI_CHECK(id == 10);
404 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
405
406 if (RT_SUCCESS(rc))
407 {
408 fEvents = UINT32_MAX;
409 id = UINT32_MAX;
410 RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
411 RTTESTI_CHECK(id == 10);
412 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
413 }
414
415 fEvents = UINT32_MAX;
416 id = UINT32_MAX;
417 RTTESTI_CHECK_RC(RTPollNoResume(hSet, 0, &fEvents, &id), VINF_SUCCESS);
418 RTTESTI_CHECK(id == 10);
419 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
420
421 fEvents = UINT32_MAX;
422 id = UINT32_MAX;
423 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 100, &fEvents, &id), VINF_SUCCESS);
424 RTTESTI_CHECK(id == 10);
425 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
426
427 if (RT_SUCCESS(rc))
428 {
429 fEvents = UINT32_MAX;
430 id = UINT32_MAX;
431 RTTESTI_CHECK_RC(RTPollNoResume(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
432 RTTESTI_CHECK(id == 10);
433 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
434 }
435
436 /* Write to the pipe. Currently ASSUMING we'll get the read ready now... Good idea? */
437 RTTESTI_CHECK_RC(rc = RTPipeWriteBlocking(hPipeW, "hello", 5, NULL), VINF_SUCCESS);
438 if (RT_SUCCESS(rc))
439 {
440 fEvents = UINT32_MAX;
441 id = UINT32_MAX;
442 RTTESTI_CHECK_RC(RTPoll(hSet, 0, &fEvents, &id), VINF_SUCCESS);
443 RTTESTI_CHECK(id == 1);
444 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
445
446 fEvents = UINT32_MAX;
447 id = UINT32_MAX;
448 RTTESTI_CHECK_RC(rc = RTPoll(hSet, 256, &fEvents, &id), VINF_SUCCESS);
449 RTTESTI_CHECK(id == 1);
450 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
451
452 if (RT_SUCCESS(rc))
453 {
454 fEvents = UINT32_MAX;
455 id = UINT32_MAX;
456 RTTESTI_CHECK_RC(RTPoll(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
457 RTTESTI_CHECK(id == 1);
458 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
459 }
460
461 fEvents = UINT32_MAX;
462 id = UINT32_MAX;
463 RTTESTI_CHECK_RC(RTPollNoResume(hSet, 0, &fEvents, &id), VINF_SUCCESS);
464 RTTESTI_CHECK(id == 1);
465 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
466
467 fEvents = UINT32_MAX;
468 id = UINT32_MAX;
469 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 383, &fEvents, &id), VINF_SUCCESS);
470 RTTESTI_CHECK(id == 1);
471 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
472
473 if (RT_SUCCESS(rc))
474 {
475 fEvents = UINT32_MAX;
476 id = UINT32_MAX;
477 RTTESTI_CHECK_RC(RTPollNoResume(hSet, RT_INDEFINITE_WAIT, &fEvents, &id), VINF_SUCCESS);
478 RTTESTI_CHECK(id == 1);
479 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
480 }
481 }
482
483 /* Remove the read pipe, do a quick poll check. */
484 RTTESTI_CHECK_RC_RETV(RTPollSetRemove(hSet, 1), VINF_SUCCESS);
485 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);
486 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
487 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
488 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
489 RTTESTI_CHECK(Handle.u.hPipe == hPipeW);
490
491 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VINF_SUCCESS);
492
493 /* Add it back and check that we now get the write handle when polling.
494 (Is this FIFOing a good idea?) */
495 RTTESTI_CHECK_RC_RETV(RTPoll(hSet, 0, NULL, NULL), VINF_SUCCESS);
496
497 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_READ, 1 /*id*/), VINF_SUCCESS);
498 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 2);
499 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VINF_SUCCESS);
500
501 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 1 /*id*/, &Handle), VINF_SUCCESS);
502 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
503 RTTESTI_CHECK(Handle.u.hPipe == hPipeR);
504
505 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
506 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
507 RTTESTI_CHECK(Handle.u.hPipe == hPipeW);
508
509 fEvents = UINT32_MAX;
510 id = UINT32_MAX;
511 RTTESTI_CHECK_RC(rc = RTPollNoResume(hSet, 555, &fEvents, &id), VINF_SUCCESS);
512 RTTESTI_CHECK(id == 10);
513 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
514
515 /* Remove it again and break the pipe by closing the read end. */
516 RTTESTI_CHECK_RC_RETV(RTPollSetRemove(hSet, 1), VINF_SUCCESS);
517 RTTESTI_CHECK_RETV(RTPollSetGetCount(hSet) == 1);
518 RTTESTI_CHECK_RC(RTPollSetQueryHandle(hSet, 1 /*id*/, NULL), VERR_POLL_HANDLE_ID_NOT_FOUND);
519 RTTESTI_CHECK_RC_RETV(RTPollSetQueryHandle(hSet, 10 /*id*/, &Handle), VINF_SUCCESS);
520 RTTESTI_CHECK(Handle.enmType == RTHANDLETYPE_PIPE);
521 RTTESTI_CHECK(Handle.u.hPipe == hPipeW);
522
523 RTTESTI_CHECK_RC(RTPoll(hSet, 0, NULL, NULL), VINF_SUCCESS);
524
525 RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
526
527 fEvents = UINT32_MAX;
528 id = UINT32_MAX;
529 RTTESTI_CHECK_RC(RTPollNoResume(hSet, 0, &fEvents, &id), VINF_SUCCESS);
530 RTTESTI_CHECK(id == 10);
531 RTTESTI_CHECK_MSG( fEvents == RTPOLL_EVT_ERROR \
532 || fEvents == (RTPOLL_EVT_ERROR | RTPOLL_EVT_WRITE), ("%#x\n", fEvents));
533
534 RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
535 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
536
537 /*
538 * Check FIFO order when removing and adding.
539 *
540 * Note! FIFO order is not guaranteed when a handle has more than one entry
541 * in the set.
542 */
543 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0/*fFlags*/), VINF_SUCCESS);
544 RTPIPE hPipeR2, hPipeW2;
545 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR2, &hPipeW2, 0/*fFlags*/), VINF_SUCCESS);
546 RTPIPE hPipeR3, hPipeW3;
547 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR3, &hPipeW3, 0/*fFlags*/), VINF_SUCCESS);
548 RTTESTI_CHECK_RC_RETV(RTPollSetCreate(&hSet), VINF_SUCCESS);
549 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR, RTPOLL_EVT_READ, 1 /*id*/), VINF_SUCCESS);
550 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeW, RTPOLL_EVT_WRITE, 2 /*id*/), VINF_SUCCESS);
551 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR2, RTPOLL_EVT_READ, 3 /*id*/), VINF_SUCCESS);
552 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeW2, RTPOLL_EVT_WRITE, 4 /*id*/), VINF_SUCCESS);
553 RTTESTI_CHECK_RC_RETV(RTPollSetAddPipe(hSet, hPipeR3, RTPOLL_EVT_READ, 5 /*id*/), VINF_SUCCESS);
554
555 id = UINT32_MAX; fEvents = UINT32_MAX;
556 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
557 RTTESTI_CHECK(id == 2);
558 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
559
560 RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW, "hello", 5, NULL), VINF_SUCCESS);
561 RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW2, "hello", 5, NULL), VINF_SUCCESS);
562 RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW3, "hello", 5, NULL), VINF_SUCCESS);
563 id = UINT32_MAX; fEvents = UINT32_MAX;
564 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
565 RTTESTI_CHECK(id == 1);
566 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
567
568 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 1), VINF_SUCCESS);
569 id = UINT32_MAX; fEvents = UINT32_MAX;
570 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
571 RTTESTI_CHECK(id == 2);
572 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
573
574 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 2), VINF_SUCCESS);
575 id = UINT32_MAX; fEvents = UINT32_MAX;
576 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
577 RTTESTI_CHECK(id == 3);
578 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
579
580 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 3), VINF_SUCCESS);
581 id = UINT32_MAX; fEvents = UINT32_MAX;
582 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
583 RTTESTI_CHECK(id == 4);
584 RTTESTI_CHECK(fEvents == RTPOLL_EVT_WRITE);
585
586 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 4), VINF_SUCCESS);
587 id = UINT32_MAX; fEvents = UINT32_MAX;
588 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VINF_SUCCESS);
589 RTTESTI_CHECK(id == 5);
590 RTTESTI_CHECK(fEvents == RTPOLL_EVT_READ);
591
592 RTTESTI_CHECK_RC(RTPollSetRemove(hSet, 5), VINF_SUCCESS);
593 id = UINT32_MAX; fEvents = UINT32_MAX;
594 RTTESTI_CHECK_RC(RTPoll(hSet, 5, &fEvents, &id), VERR_TIMEOUT);
595
596 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
597 RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
598 RTTESTI_CHECK_RC(RTPipeClose(hPipeW2), VINF_SUCCESS);
599 RTTESTI_CHECK_RC(RTPipeClose(hPipeR2), VINF_SUCCESS);
600 RTTESTI_CHECK_RC(RTPipeClose(hPipeW3), VINF_SUCCESS);
601 RTTESTI_CHECK_RC(RTPipeClose(hPipeR3), VINF_SUCCESS);
602 RTTESTI_CHECK_RC(RTPollSetDestroy(hSet), VINF_SUCCESS);
603
604}
605
606int main()
607{
608 RTTEST hTest;
609 int rc = RTTestInitAndCreate("tstRTPoll", &hTest);
610 if (rc)
611 return rc;
612 RTTestBanner(hTest);
613
614 /*
615 * The tests.
616 */
617 tstRTPoll1();
618 if (RTTestErrorCount(hTest) == 0)
619 {
620 bool fMayPanic = RTAssertMayPanic();
621 bool fQuiet = RTAssertAreQuiet();
622 RTAssertSetMayPanic(false);
623 RTAssertSetQuiet(true);
624 tstRTPoll2();
625 RTAssertSetQuiet(fQuiet);
626 RTAssertSetMayPanic(fMayPanic);
627
628 tstRTPoll3();
629 }
630
631 /*
632 * Summary.
633 */
634 return RTTestSummaryAndDestroy(hTest);
635}
636
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette