VirtualBox

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

最後變更 在這個檔案從39498是 39498,由 vboxsync 提交於 13 年 前

RTReq refactoring.

  • 屬性 eol-style 設為 native
  • 屬性 svn:eol-style 設為 native
檔案大小: 12.9 KB
 
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.alldomusa.eu.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 */
109typedef struct RTREQ
110{
111 /** Pointer to the next request in the chain. */
112 struct RTREQ * volatile pNext;
113 /** Pointer to the queue this packet belongs to. */
114 RTREQQUEUE hQueue;
115 /** Request state. */
116 volatile RTREQSTATE enmState;
117 /** iprt status code for the completed request. */
118 volatile int iStatus;
119 /** Requester event sem.
120 * The request can use this event semaphore to wait/poll for completion
121 * of the request.
122 */
123 RTSEMEVENT EventSem;
124 /** Set if the event semaphore is clear. */
125 volatile bool fEventSemClear;
126 /** Flags, RTREQ_FLAGS_*. */
127 unsigned fFlags;
128 /** Request type. */
129 RTREQTYPE enmType;
130 /** Request specific data. */
131 union RTREQ_U
132 {
133 /** RTREQTYPE_INTERNAL. */
134 struct
135 {
136 /** Pointer to the function to be called. */
137 PFNRT pfn;
138 /** Number of arguments. */
139 unsigned cArgs;
140 /** Array of arguments. */
141 uintptr_t aArgs[64];
142 } Internal;
143 } u;
144} RTREQ;
145/** Pointer to an RT request packet. */
146typedef RTREQ *PRTREQ;
147
148
149#ifdef IN_RING3
150
151/**
152 * Create a request packet queue
153 *
154 * @returns iprt status code.
155 * @param phQueue Where to store the request queue handle.
156 */
157RTDECL(int) RTReqQueueCreate(PRTREQQUEUE phQueue);
158
159/**
160 * Destroy a request packet queue
161 *
162 * @returns iprt status code.
163 * @param hQueue The request queue.
164 */
165RTDECL(int) RTReqQueueDestroy(RTREQQUEUE hQueue);
166
167/**
168 * Process one or more request packets
169 *
170 * @returns iprt status code.
171 * @returns VERR_TIMEOUT if cMillies was reached without the packet being added.
172 *
173 * @param hQueue The request queue.
174 * @param cMillies Number of milliseconds to wait for a pending request.
175 * Use RT_INDEFINITE_WAIT to only wait till one is added.
176 */
177RTDECL(int) RTReqQueueProcess(RTREQQUEUE hQueue, RTMSINTERVAL cMillies);
178
179/**
180 * Allocate and queue a call request.
181 *
182 * If it's desired to poll on the completion of the request set cMillies
183 * to 0 and use RTReqWait() to check for completion. In the other case
184 * use RT_INDEFINITE_WAIT.
185 * The returned request packet must be freed using RTReqFree().
186 *
187 * @returns iprt statuscode.
188 * Will not return VERR_INTERRUPTED.
189 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
190 *
191 * @param hQueue The request queue.
192 * @param ppReq Where to store the pointer to the request.
193 * This will be NULL or a valid request pointer not matter what happens.
194 * @param cMillies Number of milliseconds to wait for the request to
195 * be completed. Use RT_INDEFINITE_WAIT to only
196 * wait till it's completed.
197 * @param pfnFunction Pointer to the function to call.
198 * @param cArgs Number of arguments following in the ellipsis.
199 * @param ... Function arguments.
200 *
201 * @remarks See remarks on RTReqQueueCallV.
202 */
203RTDECL(int) RTReqQueueCall(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, PFNRT pfnFunction, unsigned cArgs, ...);
204
205/**
206 * Allocate and queue a call request to a void function.
207 *
208 * If it's desired to poll on the completion of the request set cMillies
209 * to 0 and use RTReqWait() to check for completion. In the other case
210 * use RT_INDEFINITE_WAIT.
211 * The returned request packet must be freed using RTReqFree().
212 *
213 * @returns iprt status code.
214 * Will not return VERR_INTERRUPTED.
215 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
216 *
217 * @param hQueue The request queue.
218 * @param ppReq Where to store the pointer to the request.
219 * This will be NULL or a valid request pointer not matter what happens.
220 * @param cMillies Number of milliseconds to wait for the request to
221 * be completed. Use RT_INDEFINITE_WAIT to only
222 * wait till it's completed.
223 * @param pfnFunction Pointer to the function to call.
224 * @param cArgs Number of arguments following in the ellipsis.
225 * @param ... Function arguments.
226 *
227 * @remarks See remarks on RTReqQueueCallV.
228 */
229RTDECL(int) RTReqQueueCallVoid(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, PFNRT pfnFunction, unsigned cArgs, ...);
230
231/**
232 * Allocate and queue a call request to a void function.
233 *
234 * If it's desired to poll on the completion of the request set cMillies
235 * to 0 and use RTReqWait() to check for completion. In the other case
236 * use RT_INDEFINITE_WAIT.
237 * The returned request packet must be freed using RTReqFree().
238 *
239 * @returns iprt status code.
240 * Will not return VERR_INTERRUPTED.
241 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
242 *
243 * @param hQueue The request queue.
244 * @param ppReq Where to store the pointer to the request.
245 * This will be NULL or a valid request pointer not matter what happens, unless fFlags
246 * contains RTREQFLAGS_NO_WAIT when it will be optional and always NULL.
247 * @param cMillies Number of milliseconds to wait for the request to
248 * be completed. Use RT_INDEFINITE_WAIT to only
249 * wait till it's completed.
250 * @param fFlags A combination of the RTREQFLAGS values.
251 * @param pfnFunction Pointer to the function to call.
252 * @param cArgs Number of arguments following in the ellipsis.
253 * @param ... Function arguments.
254 *
255 * @remarks See remarks on RTReqQueueCallV.
256 */
257RTDECL(int) RTReqQueueCallEx(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
258
259/**
260 * Allocate and queue a call request.
261 *
262 * If it's desired to poll on the completion of the request set cMillies
263 * to 0 and use RTReqWait() to check for completion. In the other case
264 * use RT_INDEFINITE_WAIT.
265 * The returned request packet must be freed using RTReqFree().
266 *
267 * @returns iprt status code.
268 * Will not return VERR_INTERRUPTED.
269 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
270 *
271 * @param hQueue The request queue.
272 * @param ppReq Where to store the pointer to the request.
273 * This will be NULL or a valid request pointer not matter what happens, unless fFlags
274 * contains RTREQFLAGS_NO_WAIT when it will be optional and always NULL.
275 * @param cMillies Number of milliseconds to wait for the request to
276 * be completed. Use RT_INDEFINITE_WAIT to only
277 * wait till it's completed.
278 * @param fFlags A combination of the RTREQFLAGS values.
279 * @param pfnFunction Pointer to the function to call.
280 * @param cArgs Number of arguments following in the ellipsis.
281 * @param Args Variable argument vector.
282 *
283 * @remarks Caveats:
284 * - Do not pass anything which is larger than an uintptr_t.
285 * - 64-bit integers are larger than uintptr_t on 32-bit hosts.
286 * Pass integers > 32-bit by reference (pointers).
287 * - Don't use NULL since it should be the integer 0 in C++ and may
288 * therefore end up with garbage in the bits 63:32 on 64-bit
289 * hosts because 'int' is 32-bit.
290 * Use (void *)NULL or (uintptr_t)0 instead of NULL.
291 */
292RTDECL(int) RTReqQueueCallV(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
293
294/**
295 * Checks if the queue is busy or not.
296 *
297 * The caller is responsible for dealing with any concurrent submitts.
298 *
299 * @returns true if busy, false if idle.
300 * @param hQueue The queue.
301 */
302RTDECL(bool) RTReqQueueIsBusy(RTREQQUEUE hQueue);
303
304/**
305 * Allocates a request packet.
306 *
307 * The caller allocates a request packet, fills in the request data
308 * union and queues the request.
309 *
310 * @returns iprt status code.
311 *
312 * @param hQueue The request queue.
313 * @param ppReq Where to store the pointer to the allocated packet.
314 * @param enmType Package type.
315 */
316RTDECL(int) RTReqQueueAlloc(RTREQQUEUE hQueue, PRTREQ *ppReq, RTREQTYPE enmType);
317
318
319/**
320 * Free a request packet.
321 *
322 * @returns iprt status code.
323 *
324 * @param pReq Package to free.
325 * @remark The request packet must be in allocated or completed state!
326 */
327RTDECL(int) RTReqFree(PRTREQ pReq);
328
329
330/**
331 * Queue a request.
332 *
333 * The quest must be allocated using RTReqQueueAlloc() or RTReqPoolAlloc() and
334 * contain all the required data.
335 *
336 * If it's desired to poll on the completion of the request set cMillies
337 * to 0 and use RTReqWait() to check for completion. In the other case
338 * use RT_INDEFINITE_WAIT.
339 *
340 * @returns iprt status code.
341 * Will not return VERR_INTERRUPTED.
342 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
343 *
344 * @param pReq The request to queue.
345 * @param cMillies Number of milliseconds to wait for the request to
346 * be completed. Use RT_INDEFINITE_WAIT to only
347 * wait till it's completed.
348 */
349RTDECL(int) RTReqSubmit(PRTREQ pReq, RTMSINTERVAL cMillies);
350
351
352/**
353 * Wait for a request to be completed.
354 *
355 * @returns iprt status code.
356 * Will not return VERR_INTERRUPTED.
357 * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
358 *
359 * @param pReq The request to wait for.
360 * @param cMillies Number of milliseconds to wait.
361 * Use RT_INDEFINITE_WAIT to only wait till it's completed.
362 */
363RTDECL(int) RTReqWait(PRTREQ pReq, RTMSINTERVAL cMillies);
364
365
366#endif /* IN_RING3 */
367
368
369/** @} */
370
371RT_C_DECLS_END
372
373#endif
374
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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