VirtualBox

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

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

Biggest check-in ever. New source code headers for all (C) innotek files.

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