VirtualBox

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

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

RTReq: More refactoring.

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

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