1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
|
/** @file
* IPRT - Polling I/O Handles.
*/
/*
* Copyright (C) 2010-2019 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
#ifndef IPRT_INCLUDED_poll_h
#define IPRT_INCLUDED_poll_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif
#include <iprt/cdefs.h>
#include <iprt/types.h>
RT_C_DECLS_BEGIN
/** @defgroup grp_rt_poll RTPoll - Polling I/O Handles
* @ingroup grp_rt
* @{
*/
/** @name Poll events
* @{ */
/** Readable without blocking. */
#define RTPOLL_EVT_READ RT_BIT_32(0)
/** Writable without blocking. */
#define RTPOLL_EVT_WRITE RT_BIT_32(1)
/** Error condition, hangup, exception or similar. */
#define RTPOLL_EVT_ERROR RT_BIT_32(2)
/** Mask of the valid bits. */
#define RTPOLL_EVT_VALID_MASK UINT32_C(0x00000007)
/** @} */
/**
* Polls on the specified poll set until an event occurs on one of the handles
* or the timeout expires.
*
* @returns IPRT status code.
* @retval VINF_SUCCESS if an event occurred on a handle. Note that these
* @retval VERR_INVALID_HANDLE if @a hPollSet is invalid.
* @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
* user is responsible for ensuring single threaded access.
* @retval VERR_TIMEOUT if @a cMillies ellapsed without any events.
* @retval VERR_DEADLOCK if @a cMillies is set to RT_INDEFINITE_WAIT and there
* are no valid handles in the set.
*
* @param hPollSet The set to poll on.
* @param cMillies Number of milliseconds to wait. Use
* RT_INDEFINITE_WAIT to wait for ever.
* @param pfEvents Where to return details about the events that
* occurred. Optional.
* @param pid Where to return the ID associated with the
* handle when calling RTPollSetAdd. Optional.
*
* @sa RTPollNoResume
*
* @remarks The caller is responsible for ensuring
*/
RTDECL(int) RTPoll(RTPOLLSET hPollSet, RTMSINTERVAL cMillies, uint32_t *pfEvents, uint32_t *pid);
/**
* Same as RTPoll except that it will return when interrupted.
*
* @returns IPRT status code.
* @retval VINF_SUCCESS if an event occurred on a handle. Note that these
* @retval VERR_INVALID_HANDLE if @a hPollSet is invalid.
* @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
* user is responsible for ensuring single threaded access.
* @retval VERR_TIMEOUT if @a cMillies ellapsed without any events.
* @retval VERR_DEADLOCK if @a cMillies is set to RT_INDEFINITE_WAIT and there
* are no valid handles in the set.
* @retval VERR_INTERRUPTED if a signal or other asynchronous event interrupted
* the polling.
*
* @param hPollSet The set to poll on.
* @param cMillies Number of milliseconds to wait. Use
* RT_INDEFINITE_WAIT to wait for ever.
* @param pfEvents Where to return details about the events that
* occurred. Optional.
* @param pid Where to return the ID associated with the
* handle when calling RTPollSetAdd. Optional.
*/
RTDECL(int) RTPollNoResume(RTPOLLSET hPollSet, RTMSINTERVAL cMillies, uint32_t *pfEvents, uint32_t *pid);
/**
* Creates a poll set with no members.
*
* @returns IPRT status code.
* @param phPollSet Where to return the poll set handle.
*/
RTDECL(int) RTPollSetCreate(PRTPOLLSET phPollSet);
/**
* Destroys a poll set.
*
* @returns IPRT status code.
* @param hPollSet The poll set to destroy. NIL_POLLSET is quietly
* ignored (VINF_SUCCESS).
*/
RTDECL(int) RTPollSetDestroy(RTPOLLSET hPollSet);
/**
* Adds a generic handle to the poll set.
*
* If a handle is entered more than once, it is recommended to add the one with
* RTPOLL_EVT_ERROR first to ensure that you get the right ID back when an error
* actually occurs. On some hosts it is possible that polling for
* RTPOLL_EVT_READ on a socket may cause it to return error conditions because
* the two cannot so easily be distinguished.
*
* Also note that RTPOLL_EVT_ERROR may be returned by RTPoll even if not asked
* for.
*
* @returns IPRT status code
* @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
* user is responsible for ensuring single threaded access.
* @retval VERR_POLL_HANDLE_NOT_POLLABLE if the specified handle is not
* pollable.
* @retval VERR_POLL_HANDLE_ID_EXISTS if the handle ID is already in use in the
* set.
*
* @param hPollSet The poll set to modify.
* @param pHandle The handle to add. NIL handles are quietly
* ignored.
* @param fEvents Which events to poll for.
* @param id The handle ID.
*/
RTDECL(int) RTPollSetAdd(RTPOLLSET hPollSet, PCRTHANDLE pHandle, uint32_t fEvents, uint32_t id);
/**
* Removes a generic handle from the poll set.
*
* @returns IPRT status code
* @retval VERR_INVALID_HANDLE if @a hPollSet not valid.
* @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
* user is responsible for ensuring single threaded access.
* @retval VERR_POLL_HANDLE_ID_NOT_FOUND if @a id doesn't resolve to a valid
* handle.
*
* @param hPollSet The poll set to modify.
* @param id The handle ID of the handle that should be
* removed.
*/
RTDECL(int) RTPollSetRemove(RTPOLLSET hPollSet, uint32_t id);
/**
* Query a handle in the poll set by it's ID.
*
* @returns IPRT status code
* @retval VINF_SUCCESS if the handle was found. @a *pHandle is set.
* @retval VERR_INVALID_HANDLE if @a hPollSet is invalid.
* @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
* user is responsible for ensuring single threaded access.
* @retval VERR_POLL_HANDLE_ID_NOT_FOUND if there is no handle with that ID.
*
* @param hPollSet The poll set to query.
* @param id The ID of the handle.
* @param pHandle Where to return the handle details. Optional.
*/
RTDECL(int) RTPollSetQueryHandle(RTPOLLSET hPollSet, uint32_t id, PRTHANDLE pHandle);
/**
* Gets the number of handles in the set.
*
* @retval The handle count.
* @retval UINT32_MAX if @a hPollSet is invalid or there is concurrent access.
*
* @param hPollSet The poll set.
*/
RTDECL(uint32_t) RTPollSetGetCount(RTPOLLSET hPollSet);
/**
* Modifies the events to poll for for the given id.
*
* @returns IPRT status code.
* @retval VERR_INVALID_HANDLE if @a hPollSet not valid.
* @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
* user is responsible for ensuring single threaded access.
* @retval VERR_POLL_HANDLE_ID_NOT_FOUND if @a id doesn't resolve to a valid
* handle.
*
* @param hPollSet The poll set to modify.
* @param id The handle ID to change the events for.
* @param fEvents Which events to poll for.
*/
RTDECL(int) RTPollSetEventsChange(RTPOLLSET hPollSet, uint32_t id, uint32_t fEvents);
/**
* Adds a pipe handle to the set.
*
* @returns See RTPollSetAdd.
*
* @param hPollSet The poll set.
* @param hPipe The pipe handle.
* @param fEvents Which events to poll for.
* @param id The handle ID.
*
* @todo Maybe we could figure out what to poll for depending on the kind of
* pipe we're dealing with.
*/
DECLINLINE(int) RTPollSetAddPipe(RTPOLLSET hPollSet, RTPIPE hPipe, uint32_t fEvents, uint32_t id)
{
RTHANDLE Handle;
Handle.enmType = RTHANDLETYPE_PIPE;
Handle.u.uInt = 0;
Handle.u.hPipe = hPipe;
return RTPollSetAdd(hPollSet, &Handle, fEvents, id);
}
/**
* Adds a socket handle to the set.
*
* @returns See RTPollSetAdd.
*
* @param hPollSet The poll set.
* @param hSocket The socket handle.
* @param fEvents Which events to poll for.
* @param id The handle ID.
*/
DECLINLINE(int) RTPollSetAddSocket(RTPOLLSET hPollSet, RTSOCKET hSocket, uint32_t fEvents, uint32_t id)
{
RTHANDLE Handle;
Handle.enmType = RTHANDLETYPE_SOCKET;
Handle.u.uInt = 0;
Handle.u.hSocket = hSocket;
return RTPollSetAdd(hPollSet, &Handle, fEvents, id);
}
/** @} */
RT_C_DECLS_END
#endif /* !IPRT_INCLUDED_poll_h */
|