VirtualBox

source: vbox/trunk/include/iprt/req.h@ 39503

Last change on this file since 39503 was 39503, checked in by vboxsync, 13 years ago

RTReq: Bugfix and some more refactoring.

  • Property eol-style set to native
  • Property svn:eol-style set to native
File size: 13.5 KB
Line 
1/** @file
2 * IPRT - Request Queue & Pool.
3 */
4
5/*
6 * Copyright (C) 2006-2011 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_req_h
27#define ___iprt_req_h
28
29#include <iprt/cdefs.h>
30#include <iprt/types.h>
31
32#include <iprt/stdarg.h>
33
34RT_C_DECLS_BEGIN
35
36/** @defgroup grp_rt_req RTReq - Request Queue & Pool.
37 * @ingroup grp_rt
38 * @{
39 */
40
41/** Request queue handle. */
42typedef struct RTREQQUEUEINT *RTREQQUEUE;
43/** Pointer to a request queue handle. */
44typedef RTREQQUEUE *PRTREQQUEUE;
45/** NIL request queue handle. */
46#define NIL_RTREQQUEUE ((RTREQQUEUE)0)
47
48/** Request thread pool handle. */
49typedef struct RTREQPOOLINT *RTREQPOOL;
50/** Poiner to a request thread pool handle. */
51typedef RTREQPOOL *PRTREQPOOL;
52/** NIL request pool handle. */
53#define NIL_RTREQPOOL ((RTREQPOOL)0)
54
55
56/**
57 * Request type.
58 */
59typedef enum RTREQTYPE
60{
61 /** Invalid request. */
62 RTREQTYPE_INVALID = 0,
63 /** RT: Internal. */
64 RTREQTYPE_INTERNAL,
65 /** Maximum request type (exclusive). Used for validation. */
66 RTREQTYPE_MAX
67} RTREQTYPE;
68
69/**
70 * Request state.
71 */
72typedef enum RTREQSTATE
73{
74 /** The state is invalid. */
75 RTREQSTATE_INVALID = 0,
76 /** The request have been allocated and is in the process of being filed. */
77 RTREQSTATE_ALLOCATED,
78 /** The request is queued by the requester. */
79 RTREQSTATE_QUEUED,
80 /** The request is begin processed. */
81 RTREQSTATE_PROCESSING,
82 /** The request is completed, the requester is begin notified. */
83 RTREQSTATE_COMPLETED,
84 /** The request packet is in the free chain. (The requester */
85 RTREQSTATE_FREE
86} RTREQSTATE;
87
88/**
89 * Request flags.
90 */
91typedef enum RTREQFLAGS
92{
93 /** The request returns a iprt status code. */
94 RTREQFLAGS_IPRT_STATUS = 0,
95 /** The request is a void request and have no status code. */
96 RTREQFLAGS_VOID = 1,
97 /** Return type mask. */
98 RTREQFLAGS_RETURN_MASK = 1,
99 /** Caller does not wait on the packet, Queue process thread will free it. */
100 RTREQFLAGS_NO_WAIT = 2
101} RTREQFLAGS;
102
103
104/**
105 * RT Request packet.
106 *
107 * This is used to request an action in the queue handler thread.
108 */
109#if defined(IN_RT) || defined(IN_RT_R3) || defined(IN_RT_R0) || defined(IN_RT_RC)
110typedef struct RTREQ
111{
112 /** Magic number (RTREQ_MAGIC). */
113 uint32_t u32Magic;
114 /** Set if the event semaphore is clear. */
115 volatile bool fEventSemClear;
116 /** Set if pool, clear if queue. */
117 volatile bool fPoolOrQueue;
118 /** IPRT status code for the completed request. */
119 volatile int32_t iStatusX;
120 /** Request state. */
121 volatile RTREQSTATE enmState;
122
123 /** Pointer to the next request in the chain. */
124 struct RTREQ * volatile pNext;
125
126 union
127 {
128 /** Pointer to the pool this packet belongs to. */
129 RTREQPOOL hPool;
130 /** Pointer to the queue this packet belongs to. */
131 RTREQQUEUE hQueue;
132 } uOwner;
133
134 /** Requester event sem.
135 * The request can use this event semaphore to wait/poll for completion
136 * of the request.
137 */
138 RTSEMEVENT EventSem;
139 /** Flags, RTREQ_FLAGS_*. */
140 uint32_t fFlags;
141 /** Request type. */
142 RTREQTYPE enmType;
143 /** Request specific data. */
144 union RTREQ_U
145 {
146 /** RTREQTYPE_INTERNAL. */
147 struct
148 {
149 /** Pointer to the function to be called. */
150 PFNRT pfn;
151 /** Number of arguments. */
152 uint32_t cArgs;
153 /** Array of arguments. */
154 uintptr_t aArgs[64];
155 } Internal;
156 } u;
157} RTREQ;
158#else
159typedef struct RTREQ RTREQ;
160#endif
161/** Pointer to an RT request packet. */
162typedef RTREQ *PRTREQ;
163
164
165#ifdef IN_RING3
166
167/**
168 * Create a request packet queue
169 *
170 * @returns iprt status code.
171 * @param phQueue Where to store the request queue handle.
172 */
173RTDECL(int) RTReqQueueCreate(PRTREQQUEUE phQueue);
174
175/**
176 * Destroy a request packet queue
177 *
178 * @returns iprt status code.
179 * @param hQueue The request queue.
180 */
181RTDECL(int) RTReqQueueDestroy(RTREQQUEUE hQueue);
182
183/**
184 * Process one or more request packets
185 *
186 * @returns iprt status code.
187 * @returns VERR_TIMEOUT if cMillies was reached without the packet being added.
188 *
189 * @param hQueue The request queue.
190 * @param cMillies Number of milliseconds to wait for a pending request.
191 * Use RT_INDEFINITE_WAIT to only wait till one is added.
192 */
193RTDECL(int) RTReqQueueProcess(RTREQQUEUE hQueue, RTMSINTERVAL cMillies);
194
195/**
196 * Allocate and queue a call request.
197 *
198 * If it's desired to poll on the completion of the request set cMillies
199 * to 0 and use RTReqWait() to check for completion. In the other case
200 * use RT_INDEFINITE_WAIT.
201 * The returned request packet must be freed using RTReqFree().
202 *
203 * @returns iprt statuscode.
204 * Will not return VERR_INTERRUPTED.
205 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
206 *
207 * @param hQueue The request queue.
208 * @param ppReq Where to store the pointer to the request.
209 * This will be NULL or a valid request pointer not matter what happens.
210 * @param cMillies Number of milliseconds to wait for the request to
211 * be completed. Use RT_INDEFINITE_WAIT to only
212 * wait till it's completed.
213 * @param pfnFunction Pointer to the function to call.
214 * @param cArgs Number of arguments following in the ellipsis.
215 * @param ... Function arguments.
216 *
217 * @remarks See remarks on RTReqQueueCallV.
218 */
219RTDECL(int) RTReqQueueCall(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, PFNRT pfnFunction, unsigned cArgs, ...);
220
221/**
222 * Allocate and queue a call request to a void function.
223 *
224 * If it's desired to poll on the completion of the request set cMillies
225 * to 0 and use RTReqWait() to check for completion. In the other case
226 * use RT_INDEFINITE_WAIT.
227 * The returned request packet must be freed using RTReqFree().
228 *
229 * @returns iprt status code.
230 * Will not return VERR_INTERRUPTED.
231 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
232 *
233 * @param hQueue The request queue.
234 * @param ppReq Where to store the pointer to the request.
235 * This will be NULL or a valid request pointer not matter what happens.
236 * @param cMillies Number of milliseconds to wait for the request to
237 * be completed. Use RT_INDEFINITE_WAIT to only
238 * wait till it's completed.
239 * @param pfnFunction Pointer to the function to call.
240 * @param cArgs Number of arguments following in the ellipsis.
241 * @param ... Function arguments.
242 *
243 * @remarks See remarks on RTReqQueueCallV.
244 */
245RTDECL(int) RTReqQueueCallVoid(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, PFNRT pfnFunction, unsigned cArgs, ...);
246
247/**
248 * Allocate and queue a call request to a void function.
249 *
250 * If it's desired to poll on the completion of the request set cMillies
251 * to 0 and use RTReqWait() to check for completion. In the other case
252 * use RT_INDEFINITE_WAIT.
253 * The returned request packet must be freed using RTReqFree().
254 *
255 * @returns iprt status code.
256 * Will not return VERR_INTERRUPTED.
257 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
258 *
259 * @param hQueue The request queue.
260 * @param ppReq Where to store the pointer to the request.
261 * This will be NULL or a valid request pointer not matter what happens, unless fFlags
262 * contains RTREQFLAGS_NO_WAIT when it will be optional and always NULL.
263 * @param cMillies Number of milliseconds to wait for the request to
264 * be completed. Use RT_INDEFINITE_WAIT to only
265 * wait till it's completed.
266 * @param fFlags A combination of the RTREQFLAGS values.
267 * @param pfnFunction Pointer to the function to call.
268 * @param cArgs Number of arguments following in the ellipsis.
269 * @param ... Function arguments.
270 *
271 * @remarks See remarks on RTReqQueueCallV.
272 */
273RTDECL(int) RTReqQueueCallEx(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
274
275/**
276 * Allocate and queue a call request.
277 *
278 * If it's desired to poll on the completion of the request set cMillies
279 * to 0 and use RTReqWait() to check for completion. In the other case
280 * use RT_INDEFINITE_WAIT.
281 * The returned request packet must be freed using RTReqFree().
282 *
283 * @returns iprt status code.
284 * Will not return VERR_INTERRUPTED.
285 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
286 *
287 * @param hQueue The request queue.
288 * @param ppReq Where to store the pointer to the request.
289 * This will be NULL or a valid request pointer not matter what happens, unless fFlags
290 * contains RTREQFLAGS_NO_WAIT when it will be optional and always NULL.
291 * @param cMillies Number of milliseconds to wait for the request to
292 * be completed. Use RT_INDEFINITE_WAIT to only
293 * wait till it's completed.
294 * @param fFlags A combination of the RTREQFLAGS values.
295 * @param pfnFunction Pointer to the function to call.
296 * @param cArgs Number of arguments following in the ellipsis.
297 * @param Args Variable argument vector.
298 *
299 * @remarks Caveats:
300 * - Do not pass anything which is larger than an uintptr_t.
301 * - 64-bit integers are larger than uintptr_t on 32-bit hosts.
302 * Pass integers > 32-bit by reference (pointers).
303 * - Don't use NULL since it should be the integer 0 in C++ and may
304 * therefore end up with garbage in the bits 63:32 on 64-bit
305 * hosts because 'int' is 32-bit.
306 * Use (void *)NULL or (uintptr_t)0 instead of NULL.
307 */
308RTDECL(int) RTReqQueueCallV(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
309
310/**
311 * Checks if the queue is busy or not.
312 *
313 * The caller is responsible for dealing with any concurrent submitts.
314 *
315 * @returns true if busy, false if idle.
316 * @param hQueue The queue.
317 */
318RTDECL(bool) RTReqQueueIsBusy(RTREQQUEUE hQueue);
319
320/**
321 * Allocates a request packet.
322 *
323 * The caller allocates a request packet, fills in the request data
324 * union and queues the request.
325 *
326 * @returns iprt status code.
327 *
328 * @param hQueue The request queue.
329 * @param ppReq Where to store the pointer to the allocated packet.
330 * @param enmType Package type.
331 */
332RTDECL(int) RTReqQueueAlloc(RTREQQUEUE hQueue, PRTREQ *ppReq, RTREQTYPE enmType);
333
334
335/**
336 * Free a request packet.
337 *
338 * @returns iprt status code.
339 *
340 * @param pReq Package to free.
341 * @remark The request packet must be in allocated or completed state!
342 */
343RTDECL(int) RTReqFree(PRTREQ pReq);
344
345
346/**
347 * Queue a request.
348 *
349 * The quest must be allocated using RTReqQueueAlloc() or RTReqPoolAlloc() and
350 * contain all the required data.
351 *
352 * If it's desired to poll on the completion of the request set cMillies
353 * to 0 and use RTReqWait() to check for completion. In the other case
354 * use RT_INDEFINITE_WAIT.
355 *
356 * @returns iprt status code.
357 * Will not return VERR_INTERRUPTED.
358 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
359 *
360 * @param pReq The request to queue.
361 * @param cMillies Number of milliseconds to wait for the request to
362 * be completed. Use RT_INDEFINITE_WAIT to only
363 * wait till it's completed.
364 */
365RTDECL(int) RTReqSubmit(PRTREQ pReq, RTMSINTERVAL cMillies);
366
367
368/**
369 * Wait for a request to be completed.
370 *
371 * @returns iprt status code.
372 * Will not return VERR_INTERRUPTED.
373 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
374 *
375 * @param pReq The request to wait for.
376 * @param cMillies Number of milliseconds to wait.
377 * Use RT_INDEFINITE_WAIT to only wait till it's completed.
378 */
379RTDECL(int) RTReqWait(PRTREQ pReq, RTMSINTERVAL cMillies);
380
381/**
382 * Get the status of the request.
383 *
384 * @returns Status code in the IPRT tradition.
385 *
386 * @param pReq The request.
387 */
388RTDECL(int) RTReqGetStatus(PRTREQ pReq);
389
390#endif /* IN_RING3 */
391
392
393/** @} */
394
395RT_C_DECLS_END
396
397#endif
398
Note: See TracBrowser for help on using the repository browser.

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