VirtualBox

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

Last change on this file since 25401 was 24468, checked in by vboxsync, 15 years ago

iprt/req.h: Document RTReqCall* caveats better.

  • Property eol-style set to native
File size: 13.3 KB
Line 
1/** @file
2 * IPRT - Request packets
3 */
4
5/*
6 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26 * Clara, CA 95054 USA or visit http://www.sun.com if you need
27 * additional information or have any questions.
28 */
29
30#ifndef ___iprt_req_h
31#define ___iprt_req_h
32
33#include <iprt/cdefs.h>
34#include <iprt/types.h>
35
36#include <iprt/stdarg.h>
37
38RT_C_DECLS_BEGIN
39
40/** @defgroup grp_rt_req RTReq - Request Packet Management
41 * @ingroup grp_rt
42 * @{
43 */
44
45/**
46 * Request type.
47 */
48typedef enum RTREQTYPE
49{
50 /** Invalid request. */
51 RTREQTYPE_INVALID = 0,
52 /** RT: Internal. */
53 RTREQTYPE_INTERNAL,
54 /** Maximum request type (exclusive). Used for validation. */
55 RTREQTYPE_MAX
56} RTREQTYPE;
57
58/**
59 * Request state.
60 */
61typedef enum RTREQSTATE
62{
63 /** The state is invalid. */
64 RTREQSTATE_INVALID = 0,
65 /** The request have been allocated and is in the process of being filed. */
66 RTREQSTATE_ALLOCATED,
67 /** The request is queued by the requester. */
68 RTREQSTATE_QUEUED,
69 /** The request is begin processed. */
70 RTREQSTATE_PROCESSING,
71 /** The request is completed, the requester is begin notified. */
72 RTREQSTATE_COMPLETED,
73 /** The request packet is in the free chain. (The requester */
74 RTREQSTATE_FREE
75} RTREQSTATE;
76
77/**
78 * Request flags.
79 */
80typedef enum RTREQFLAGS
81{
82 /** The request returns a iprt status code. */
83 RTREQFLAGS_IPRT_STATUS = 0,
84 /** The request is a void request and have no status code. */
85 RTREQFLAGS_VOID = 1,
86 /** Return type mask. */
87 RTREQFLAGS_RETURN_MASK = 1,
88 /** Caller does not wait on the packet, Queue process thread will free it. */
89 RTREQFLAGS_NO_WAIT = 2
90} RTREQFLAGS;
91
92/** Pointer to a request queue. */
93typedef struct RTREQQUEUE *PRTREQQUEUE;
94
95/**
96 * RT Request packet.
97 *
98 * This is used to request an action in the queue handler thread.
99 */
100typedef struct RTREQ
101{
102 /** Pointer to the next request in the chain. */
103 struct RTREQ * volatile pNext;
104 /** Pointer to the queue this packet belongs to. */
105 PRTREQQUEUE pQueue;
106 /** Request state. */
107 volatile RTREQSTATE enmState;
108 /** iprt status code for the completed request. */
109 volatile int iStatus;
110 /** Requester event sem.
111 * The request can use this event semaphore to wait/poll for completion
112 * of the request.
113 */
114 RTSEMEVENT EventSem;
115 /** Set if the event semaphore is clear. */
116 volatile bool fEventSemClear;
117 /** Flags, RTREQ_FLAGS_*. */
118 unsigned fFlags;
119 /** Request type. */
120 RTREQTYPE enmType;
121 /** Request specific data. */
122 union RTREQ_U
123 {
124 /** RTREQTYPE_INTERNAL. */
125 struct
126 {
127 /** Pointer to the function to be called. */
128 PFNRT pfn;
129 /** Number of arguments. */
130 unsigned cArgs;
131 /** Array of arguments. */
132 uintptr_t aArgs[64];
133 } Internal;
134 } u;
135} RTREQ;
136/** Pointer to an RT request packet. */
137typedef RTREQ *PRTREQ;
138
139/** @todo hide this */
140typedef struct RTREQQUEUE
141{
142 /** Head of the request queue. Atomic. */
143 volatile PRTREQ pReqs;
144 /** The last index used during alloc/free. */
145 volatile uint32_t iReqFree;
146 /** Number of free request packets. */
147 volatile uint32_t cReqFree;
148 /** Array of pointers to lists of free request packets. Atomic. */
149 volatile PRTREQ apReqFree[9];
150 /** Requester event sem.
151 * The request can use this event semaphore to wait/poll for new requests.
152 */
153 RTSEMEVENT EventSem;
154 /** Set if busy (pending or processing requests). */
155 bool volatile fBusy;
156} RTREQQUEUE;
157
158#ifdef IN_RING3
159
160/**
161 * Create a request packet queueu
162 *
163 * @returns iprt status code.
164 * @param ppQueue Where to store the request queue pointer.
165 */
166RTDECL(int) RTReqCreateQueue(PRTREQQUEUE *ppQueue);
167
168
169/**
170 * Destroy a request packet queueu
171 *
172 * @returns iprt status code.
173 * @param pQueue The request queue.
174 */
175RTDECL(int) RTReqDestroyQueue(PRTREQQUEUE pQueue);
176
177
178/**
179 * Process one or more request packets
180 *
181 * @returns iprt status code.
182 * @returns VERR_TIMEOUT if cMillies was reached without the packet being added.
183 *
184 * @param pQueue The request queue.
185 * @param cMillies Number of milliseconds to wait for a pending request.
186 * Use RT_INDEFINITE_WAIT to only wait till one is added.
187 */
188RTDECL(int) RTReqProcess(PRTREQQUEUE pQueue, unsigned cMillies);
189
190
191/**
192 * Allocate and queue a call request.
193 *
194 * If it's desired to poll on the completion of the request set cMillies
195 * to 0 and use RTReqWait() to check for completation. In the other case
196 * use RT_INDEFINITE_WAIT.
197 * The returned request packet must be freed using RTReqFree().
198 *
199 * @returns iprt statuscode.
200 * Will not return VERR_INTERRUPTED.
201 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
202 *
203 * @param pQueue The request queue.
204 * @param ppReq Where to store the pointer to the request.
205 * This will be NULL or a valid request pointer not matter what happends.
206 * @param cMillies Number of milliseconds to wait for the request to
207 * be completed. Use RT_INDEFINITE_WAIT to only
208 * wait till it's completed.
209 * @param pfnFunction Pointer to the function to call.
210 * @param cArgs Number of arguments following in the ellipsis.
211 * @param ... Function arguments.
212 *
213 * @remarks See remarks on RTReqCallV.
214 */
215RTDECL(int) RTReqCall(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, PFNRT pfnFunction, unsigned cArgs, ...);
216
217
218/**
219 * Allocate and queue a call request to a void function.
220 *
221 * If it's desired to poll on the completion of the request set cMillies
222 * to 0 and use RTReqWait() to check for completation. In the other case
223 * use RT_INDEFINITE_WAIT.
224 * The returned request packet must be freed using RTReqFree().
225 *
226 * @returns iprt status code.
227 * Will not return VERR_INTERRUPTED.
228 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
229 *
230 * @param pQueue The request queue.
231 * @param ppReq Where to store the pointer to the request.
232 * This will be NULL or a valid request pointer not matter what happends.
233 * @param cMillies Number of milliseconds to wait for the request to
234 * be completed. Use RT_INDEFINITE_WAIT to only
235 * wait till it's completed.
236 * @param pfnFunction Pointer to the function to call.
237 * @param cArgs Number of arguments following in the ellipsis.
238 * @param ... Function arguments.
239 *
240 * @remarks See remarks on RTReqCallV.
241 */
242RTDECL(int) RTReqCallVoid(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, PFNRT pfnFunction, unsigned cArgs, ...);
243
244
245/**
246 * Allocate and queue a call request to a void function.
247 *
248 * If it's desired to poll on the completion of the request set cMillies
249 * to 0 and use RTReqWait() to check for completation. In the other case
250 * use RT_INDEFINITE_WAIT.
251 * The returned request packet must be freed using RTReqFree().
252 *
253 * @returns iprt status code.
254 * Will not return VERR_INTERRUPTED.
255 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
256 *
257 * @param pQueue The request queue.
258 * @param ppReq Where to store the pointer to the request.
259 * This will be NULL or a valid request pointer not matter what happends, unless fFlags
260 * contains RTREQFLAGS_NO_WAIT when it will be optional and always NULL.
261 * @param cMillies Number of milliseconds to wait for the request to
262 * be completed. Use RT_INDEFINITE_WAIT to only
263 * wait till it's completed.
264 * @param fFlags A combination of the RTREQFLAGS values.
265 * @param pfnFunction Pointer to the function to call.
266 * @param cArgs Number of arguments following in the ellipsis.
267 * @param ... Function arguments.
268 *
269 * @remarks See remarks on RTReqCallV.
270 */
271RTDECL(int) RTReqCallEx(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
272
273
274/**
275 * Allocate and queue a call request.
276 *
277 * If it's desired to poll on the completion of the request set cMillies
278 * to 0 and use RTReqWait() to check for completation. In the other case
279 * use RT_INDEFINITE_WAIT.
280 * The returned request packet must be freed using RTReqFree().
281 *
282 * @returns iprt status code.
283 * Will not return VERR_INTERRUPTED.
284 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
285 *
286 * @param pQueue The request queue.
287 * @param ppReq Where to store the pointer to the request.
288 * This will be NULL or a valid request pointer not matter what happends, unless fFlags
289 * contains RTREQFLAGS_NO_WAIT when it will be optional and always NULL.
290 * @param cMillies Number of milliseconds to wait for the request to
291 * be completed. Use RT_INDEFINITE_WAIT to only
292 * wait till it's completed.
293 * @param fFlags A combination of the RTREQFLAGS values.
294 * @param pfnFunction Pointer to the function to call.
295 * @param cArgs Number of arguments following in the ellipsis.
296 * @param Args Variable argument vector.
297 *
298 * @remarks Caveats:
299 * - Do not pass anything which is larger than an uintptr_t.
300 * - 64-bit integers are larger than uintptr_t on 32-bit hosts.
301 * Pass integers > 32-bit by reference (pointers).
302 * - Don't use NULL since it should be the integer 0 in C++ and may
303 * therefore end up with garbage in the bits 63:32 on 64-bit
304 * hosts because 'int' is 32-bit.
305 * Use (void *)NULL or (uintptr_t)0 instead of NULL.
306 */
307RTDECL(int) RTReqCallV(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
308
309
310/**
311 * Allocates a request packet.
312 *
313 * The caller allocates a request packet, fills in the request data
314 * union and queues the request.
315 *
316 * @returns iprt status code.
317 *
318 * @param pQueue The request queue.
319 * @param ppReq Where to store the pointer to the allocated packet.
320 * @param enmType Package type.
321 */
322RTDECL(int) RTReqAlloc(PRTREQQUEUE pQueue, PRTREQ *ppReq, RTREQTYPE enmType);
323
324
325/**
326 * Free a request packet.
327 *
328 * @returns iprt status code.
329 *
330 * @param pReq Package to free.
331 * @remark The request packet must be in allocated or completed state!
332 */
333RTDECL(int) RTReqFree(PRTREQ pReq);
334
335
336/**
337 * Queue a request.
338 *
339 * The quest must be allocated using RTReqAlloc() and contain
340 * all the required data.
341 * If it's disired to poll on the completion of the request set cMillies
342 * to 0 and use RTReqWait() to check for completation. In the other case
343 * use RT_INDEFINITE_WAIT.
344 *
345 * @returns iprt status code.
346 * Will not return VERR_INTERRUPTED.
347 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
348 *
349 * @param pReq The request to queue.
350 * @param cMillies Number of milliseconds to wait for the request to
351 * be completed. Use RT_INDEFINITE_WAIT to only
352 * wait till it's completed.
353 */
354RTDECL(int) RTReqQueue(PRTREQ pReq, unsigned cMillies);
355
356
357/**
358 * Wait for a request to be completed.
359 *
360 * @returns iprt status code.
361 * Will not return VERR_INTERRUPTED.
362 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
363 *
364 * @param pReq The request to wait for.
365 * @param cMillies Number of milliseconds to wait.
366 * Use RT_INDEFINITE_WAIT to only wait till it's completed.
367 */
368RTDECL(int) RTReqWait(PRTREQ pReq, unsigned cMillies);
369
370/**
371 * Checks if the queue is busy or not.
372 *
373 * The caller is responsible for dealing with any concurrent submitts.
374 *
375 * @returns true if busy, false if idle.
376 * @param pQueue The queue.
377 */
378RTDECL(bool) RTReqIsBusy(PRTREQQUEUE pQueue);
379
380#endif /* IN_RING3 */
381
382
383/** @} */
384
385RT_C_DECLS_END
386
387#endif
388
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