VirtualBox

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

Last change on this file since 6175 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

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