VirtualBox

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

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

iprt/req.h: Added RTReqIsBusy.

  • Property eol-style set to native
File size: 13.6 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 * The arguments must be of integer or pointer type and
212 * not bigger in size than uintptr_t. Do not try pass
213 * 64-bit integers directly in portable code.
214 * @param ... Function arguments.
215 */
216RTDECL(int) RTReqCall(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, PFNRT pfnFunction, unsigned cArgs, ...);
217
218
219/**
220 * Allocate and queue a call request to a void function.
221 *
222 * If it's desired to poll on the completion of the request set cMillies
223 * to 0 and use RTReqWait() to check for completation. In the other case
224 * use RT_INDEFINITE_WAIT.
225 * The returned request packet must be freed using RTReqFree().
226 *
227 * @returns iprt status code.
228 * Will not return VERR_INTERRUPTED.
229 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
230 *
231 * @param pQueue The request queue.
232 * @param ppReq Where to store the pointer to the request.
233 * This will be NULL or a valid request pointer not matter what happends.
234 * @param cMillies Number of milliseconds to wait for the request to
235 * be completed. Use RT_INDEFINITE_WAIT to only
236 * wait till it's completed.
237 * @param pfnFunction Pointer to the function to call.
238 * @param cArgs Number of arguments following in the ellipsis.
239 * The arguments must be of integer or pointer type and
240 * not bigger in size than uintptr_t. Do not try pass
241 * 64-bit integers directly in portable code.
242 * @param ... Function arguments.
243 */
244RTDECL(int) RTReqCallVoid(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, PFNRT pfnFunction, unsigned cArgs, ...);
245
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 completation. 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 pQueue 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 happends, 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 * The arguments must be of integer or pointer type and
270 * not bigger in size than uintptr_t. Do not try pass
271 * 64-bit integers directly in portable code.
272 * @param ... Function arguments.
273 */
274RTDECL(int) RTReqCallEx(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
275
276
277/**
278 * Allocate and queue a call request.
279 *
280 * If it's desired to poll on the completion of the request set cMillies
281 * to 0 and use RTReqWait() to check for completation. In the other case
282 * use RT_INDEFINITE_WAIT.
283 * The returned request packet must be freed using RTReqFree().
284 *
285 * @returns iprt status code.
286 * Will not return VERR_INTERRUPTED.
287 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
288 *
289 * @param pQueue The request queue.
290 * @param ppReq Where to store the pointer to the request.
291 * This will be NULL or a valid request pointer not matter what happends, unless fFlags
292 * contains RTREQFLAGS_NO_WAIT when it will be optional and always NULL.
293 * @param cMillies Number of milliseconds to wait for the request to
294 * be completed. Use RT_INDEFINITE_WAIT to only
295 * wait till it's completed.
296 * @param fFlags A combination of the RTREQFLAGS values.
297 * @param pfnFunction Pointer to the function to call.
298 * @param cArgs Number of arguments following in the ellipsis.
299 * The arguments must be of integer or pointer type and
300 * not bigger in size than uintptr_t. Do not try pass
301 * 64-bit integers directly in portable code.
302 * @param Args Variable argument vector.
303 */
304RTDECL(int) RTReqCallV(PRTREQQUEUE pQueue, PRTREQ *ppReq, unsigned cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
305
306
307/**
308 * Allocates a request packet.
309 *
310 * The caller allocates a request packet, fills in the request data
311 * union and queues the request.
312 *
313 * @returns iprt status code.
314 *
315 * @param pQueue The request queue.
316 * @param ppReq Where to store the pointer to the allocated packet.
317 * @param enmType Package type.
318 */
319RTDECL(int) RTReqAlloc(PRTREQQUEUE pQueue, PRTREQ *ppReq, RTREQTYPE enmType);
320
321
322/**
323 * Free a request packet.
324 *
325 * @returns iprt status code.
326 *
327 * @param pReq Package to free.
328 * @remark The request packet must be in allocated or completed state!
329 */
330RTDECL(int) RTReqFree(PRTREQ pReq);
331
332
333/**
334 * Queue a request.
335 *
336 * The quest must be allocated using RTReqAlloc() and contain
337 * all the required data.
338 * If it's disired to poll on the completion of the request set cMillies
339 * to 0 and use RTReqWait() to check for completation. In the other case
340 * use RT_INDEFINITE_WAIT.
341 *
342 * @returns iprt status code.
343 * Will not return VERR_INTERRUPTED.
344 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
345 *
346 * @param pReq The request to queue.
347 * @param cMillies Number of milliseconds to wait for the request to
348 * be completed. Use RT_INDEFINITE_WAIT to only
349 * wait till it's completed.
350 */
351RTDECL(int) RTReqQueue(PRTREQ pReq, unsigned cMillies);
352
353
354/**
355 * Wait for a request to be completed.
356 *
357 * @returns iprt status code.
358 * Will not return VERR_INTERRUPTED.
359 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
360 *
361 * @param pReq The request to wait for.
362 * @param cMillies Number of milliseconds to wait.
363 * Use RT_INDEFINITE_WAIT to only wait till it's completed.
364 */
365RTDECL(int) RTReqWait(PRTREQ pReq, unsigned cMillies);
366
367/**
368 * Checks if the queue is busy or not.
369 *
370 * The caller is responsible for dealing with any concurrent submitts.
371 *
372 * @returns true if busy, false if idle.
373 * @param pQueue The queue.
374 */
375RTDECL(bool) RTReqIsBusy(PRTREQQUEUE pQueue);
376
377#endif /* IN_RING3 */
378
379
380/** @} */
381
382RT_C_DECLS_END
383
384#endif
385
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