VirtualBox

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

Last change on this file since 96781 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

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