|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #if defined(_PRMWAIT_H) |
|
7 #else |
|
8 #define _PRMWAIT_H |
|
9 |
|
10 #include "prio.h" |
|
11 #include "prtypes.h" |
|
12 #include "prclist.h" |
|
13 |
|
14 PR_BEGIN_EXTERN_C |
|
15 |
|
16 /********************************************************************************/ |
|
17 /********************************************************************************/ |
|
18 /********************************************************************************/ |
|
19 /****************************** WARNING ****************************/ |
|
20 /********************************************************************************/ |
|
21 /**************************** This is work in progress. *************************/ |
|
22 /************************** Do not make any assumptions *************************/ |
|
23 /************************** about the stability of this *************************/ |
|
24 /************************** API or the underlying imple- ************************/ |
|
25 /************************** mentation. ************************/ |
|
26 /********************************************************************************/ |
|
27 /********************************************************************************/ |
|
28 |
|
29 /* |
|
30 ** STRUCTURE: PRWaitGroup |
|
31 ** DESCRIPTION: |
|
32 ** The client may define several wait groups in order to semantically |
|
33 ** tie a collection of file descriptors for a single purpose. This allows |
|
34 ** easier dispatching of threads that returned with active file descriptors |
|
35 ** from the wait function. |
|
36 */ |
|
37 typedef struct PRWaitGroup PRWaitGroup; |
|
38 |
|
39 /* |
|
40 ** ENUMERATION: PRMWStatus |
|
41 ** DESCRIPTION: |
|
42 ** This enumeration is used to indicate the completion status of |
|
43 ** a receive wait object. Generally stated, a positive value indicates |
|
44 ** that the operation is not yet complete. A zero value indicates |
|
45 ** success (similar to PR_SUCCESS) and any negative value is an |
|
46 ** indication of failure. The reason for the failure can be retrieved |
|
47 ** by calling PR_GetError(). |
|
48 ** |
|
49 ** PR_MW_PENDING The operation is still pending. None of the other |
|
50 ** fields of the object are currently valid. |
|
51 ** PR_MW_SUCCESS The operation is complete and it was successful. |
|
52 ** PR_MW_FAILURE The operation failed. The reason for the failure |
|
53 ** can be retrieved by calling PR_GetError(). |
|
54 ** PR_MW_TIMEOUT The amount of time allowed for by the object's |
|
55 ** 'timeout' field has expired w/o the operation |
|
56 ** otherwise coming to closure. |
|
57 ** PR_MW_INTERRUPT The operation was cancelled, either by the client |
|
58 ** calling PR_CancelWaitFileDesc() or destroying the |
|
59 ** entire wait group (PR_DestroyWaitGroup()). |
|
60 */ |
|
61 typedef enum PRMWStatus |
|
62 { |
|
63 PR_MW_PENDING = 1, |
|
64 PR_MW_SUCCESS = 0, |
|
65 PR_MW_FAILURE = -1, |
|
66 PR_MW_TIMEOUT = -2, |
|
67 PR_MW_INTERRUPT = -3 |
|
68 } PRMWStatus; |
|
69 |
|
70 /* |
|
71 ** STRUCTURE: PRMemoryDescriptor |
|
72 ** DESCRIPTION: |
|
73 ** THis is a descriptor for an interval of memory. It contains a |
|
74 ** pointer to the first byte of that memory and the length (in |
|
75 ** bytes) of the interval. |
|
76 */ |
|
77 typedef struct PRMemoryDescriptor |
|
78 { |
|
79 void *start; /* pointer to first byte of memory */ |
|
80 PRSize length; /* length (in bytes) of memory interval */ |
|
81 } PRMemoryDescriptor; |
|
82 |
|
83 /* |
|
84 ** STRUCTURE: PRMWaitClientData |
|
85 ** DESCRIPTION: |
|
86 ** An opague stucture for which a client MAY give provide a concrete |
|
87 ** definition and associate with a receive descriptor. The NSPR runtime |
|
88 ** does not manage this field. It is completely up to the client. |
|
89 */ |
|
90 typedef struct PRMWaitClientData PRMWaitClientData; |
|
91 |
|
92 /* |
|
93 ** STRUCTURE: PRRecvWait |
|
94 ** DESCRIPTION: |
|
95 ** A receive wait object contains the file descriptor that is subject |
|
96 ** to the wait and the amount of time (beginning epoch established |
|
97 ** when the object is presented to the runtime) the the channel should |
|
98 ** block before abandoning the process. |
|
99 ** |
|
100 ** The success of the wait operation will be noted in the object's |
|
101 ** 'outcome' field. The fields are not valid when the NSPR runtime |
|
102 ** is in possession of the object. |
|
103 ** |
|
104 ** The memory descriptor describes an interval of writable memory |
|
105 ** in the caller's address space where data from an initial read |
|
106 ** can be placed. The description may indicate a null interval. |
|
107 */ |
|
108 typedef struct PRRecvWait |
|
109 { |
|
110 PRCList internal; /* internal runtime linkages */ |
|
111 |
|
112 PRFileDesc *fd; /* file descriptor associated w/ object */ |
|
113 PRMWStatus outcome; /* outcome of the current/last operation */ |
|
114 PRIntervalTime timeout; /* time allowed for entire operation */ |
|
115 |
|
116 PRInt32 bytesRecv; /* number of bytes transferred into buffer */ |
|
117 PRMemoryDescriptor buffer; /* where to store first segment of input data */ |
|
118 PRMWaitClientData *client; /* pointer to arbitrary client defined data */ |
|
119 } PRRecvWait; |
|
120 |
|
121 /* |
|
122 ** STRUCTURE: PRMWaitEnumerator |
|
123 ** DESCRIPTION: |
|
124 ** An enumeration object is used to store the state of an existing |
|
125 ** enumeration over a wait group. The opaque object must be allocated |
|
126 ** by the client and the reference presented on each call to the |
|
127 ** pseudo-stateless enumerator. The enumeration objects are sharable |
|
128 ** only in serial fashion. |
|
129 */ |
|
130 typedef struct PRMWaitEnumerator PRMWaitEnumerator; |
|
131 |
|
132 |
|
133 /* |
|
134 ** FUNCTION: PR_AddWaitFileDesc |
|
135 ** DESCRIPTION: |
|
136 ** This function will effectively add a file descriptor to the |
|
137 ** list of those waiting for network receive. The new descriptor |
|
138 ** will be semantically tied to the wait group specified. |
|
139 ** |
|
140 ** The ownership for the storage pointed to by 'desc' is temporarily |
|
141 ** passed over the the NSPR runtime. It will be handed back by the |
|
142 ** function PR_WaitRecvReady(). |
|
143 ** |
|
144 ** INPUTS |
|
145 ** group A reference to a PRWaitGroup or NULL. Wait groups are |
|
146 ** created by calling PR_CreateWaitGroup() and are used |
|
147 ** to semantically group various file descriptors by the |
|
148 ** client's application. |
|
149 ** desc A reference to a valid PRRecvWait. The object of the |
|
150 ** reference must be preserved and not be modified |
|
151 ** until its ownership is returned to the client. |
|
152 ** RETURN |
|
153 ** PRStatus An indication of success. If equal to PR_FAILUE details |
|
154 ** of the failure are avaiable via PR_GetError(). |
|
155 ** |
|
156 ** ERRORS |
|
157 ** PR_INVALID_ARGUMENT_ERROR |
|
158 ** Invalid 'group' identifier or duplicate 'desc' object. |
|
159 ** PR_OUT_OF_MEMORY_ERROR |
|
160 ** Insuffient memory for internal data structures. |
|
161 ** PR_INVALID_STATE_ERROR |
|
162 ** The group is being destroyed. |
|
163 */ |
|
164 NSPR_API(PRStatus) PR_AddWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc); |
|
165 |
|
166 /* |
|
167 ** FUNCTION: PR_WaitRecvReady |
|
168 ** DESCRIPTION: |
|
169 ** PR_WaitRecvReady will block the calling thread until one of the |
|
170 ** file descriptors that have been added via PR_AddWaitFileDesc is |
|
171 ** available for input I/O. |
|
172 ** INPUT |
|
173 ** group A pointer to a valid PRWaitGroup or NULL (the null |
|
174 ** group. The function will block the caller until a |
|
175 ** channel from the wait group becomes ready for receive |
|
176 ** or there is some sort of error. |
|
177 ** RETURN |
|
178 ** PRReciveWait |
|
179 ** When the caller is resumed it is either returned a |
|
180 ** valid pointer to a previously added receive wait or |
|
181 ** a NULL. If the latter, the function has terminated |
|
182 ** for a reason that can be determined by calling |
|
183 ** PR_GetError(). |
|
184 ** If a valid pointer is returned, the reference is to the |
|
185 ** file descriptor contained in the receive wait object. |
|
186 ** The outcome of the wait operation may still fail, and |
|
187 ** if it has, that fact will be noted in the object's |
|
188 ** outcome field. Details can be retrieved from PR_GetError(). |
|
189 ** |
|
190 ** ERRORS |
|
191 ** PR_INVALID_ARGUMENT_ERROR |
|
192 ** The 'group' is not known by the runtime. |
|
193 ** PR_PENDING_INTERRUPT_ERROR |
|
194 The thread was interrupted. |
|
195 ** PR_INVALID_STATE_ERROR |
|
196 ** The group is being destroyed. |
|
197 */ |
|
198 NSPR_API(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group); |
|
199 |
|
200 /* |
|
201 ** FUNCTION: PR_CancelWaitFileDesc |
|
202 ** DESCRIPTION: |
|
203 ** PR_CancelWaitFileDesc is provided as a means for cancelling operations |
|
204 ** on objects previously submitted by use of PR_AddWaitFileDesc(). If |
|
205 ** the runtime knows of the object, it will be marked as having failed |
|
206 ** because it was interrupted (similar to PR_Interrupt()). The first |
|
207 ** available thread waiting on the group will be made to return the |
|
208 ** PRRecvWait object with the outcome noted. |
|
209 ** |
|
210 ** INPUTS |
|
211 ** group The wait group under which the wait receive object was |
|
212 ** added. |
|
213 ** desc A pointer to the wait receive object that is to be |
|
214 ** cancelled. |
|
215 ** RETURN |
|
216 ** PRStatus If the wait receive object was located and associated |
|
217 ** with the specified wait group, the status returned will |
|
218 ** be PR_SUCCESS. There is still a race condition that would |
|
219 ** permit the offected object to complete normally, but it |
|
220 ** is assured that it will complete in the near future. |
|
221 ** If the receive object or wait group are invalid, the |
|
222 ** function will return with a status of PR_FAILURE. |
|
223 ** |
|
224 ** ERRORS |
|
225 ** PR_INVALID_ARGUMENT_ERROR |
|
226 ** The 'group' argument is not recognized as a valid group. |
|
227 ** PR_COLLECTION_EMPTY_ERROR |
|
228 ** There are no more receive wait objects in the group's |
|
229 ** collection. |
|
230 ** PR_INVALID_STATE_ERROR |
|
231 ** The group is being destroyed. |
|
232 */ |
|
233 NSPR_API(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc); |
|
234 |
|
235 /* |
|
236 ** FUNCTION: PR_CancelWaitGroup |
|
237 ** DESCRIPTION: |
|
238 ** PR_CancelWaitGroup is provided as a means for cancelling operations |
|
239 ** on objects previously submitted by use of PR_AddWaitFileDesc(). Each |
|
240 ** successive call will return a pointer to a PRRecvWait object that |
|
241 ** was previously registered via PR_AddWaitFileDesc(). If no wait |
|
242 ** objects are associated with the wait group, a NULL will be returned. |
|
243 ** This function should be called in a loop until a NULL is returned |
|
244 ** to reclaim all the wait objects prior to calling PR_DestroyWaitGroup(). |
|
245 ** |
|
246 ** INPUTS |
|
247 ** group The wait group under which the wait receive object was |
|
248 ** added. |
|
249 ** RETURN |
|
250 ** PRRecvWait* If the wait group is valid and at least one receive wait |
|
251 ** object is present in the group, that object will be |
|
252 ** marked as PR_MW_INTERRUPT'd and removed from the group's |
|
253 ** queues. Otherwise a NULL will be returned and the reason |
|
254 ** for the NULL may be retrieved by calling PR_GetError(). |
|
255 ** |
|
256 ** ERRORS |
|
257 ** PR_INVALID_ARGUMENT_ERROR |
|
258 ** PR_GROUP_EMPTY_ERROR |
|
259 */ |
|
260 NSPR_API(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group); |
|
261 |
|
262 /* |
|
263 ** FUNCTION: PR_CreateWaitGroup |
|
264 ** DESCRIPTION: |
|
265 ** A wait group is an opaque object that a client may create in order |
|
266 ** to semantically group various wait requests. Each wait group is |
|
267 ** unique, including the default wait group (NULL). A wait request |
|
268 ** that was added under a wait group will only be serviced by a caller |
|
269 ** that specified the same wait group. |
|
270 ** |
|
271 ** INPUT |
|
272 ** size The size of the hash table to be used to contain the |
|
273 ** receive wait objects. This is just the initial size. |
|
274 ** It will grow as it needs to, but to avoid that hassle |
|
275 ** one can suggest a suitable size initially. It should |
|
276 ** be ~30% larger than the maximum number of receive wait |
|
277 ** objects expected. |
|
278 ** RETURN |
|
279 ** PRWaitGroup If successful, the function will return a pointer to an |
|
280 ** object that was allocated by and owned by the runtime. |
|
281 ** The reference remains valid until it is explicitly destroyed |
|
282 ** by calling PR_DestroyWaitGroup(). |
|
283 ** |
|
284 ** ERRORS |
|
285 ** PR_OUT_OF_MEMORY_ERROR |
|
286 */ |
|
287 NSPR_API(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size); |
|
288 |
|
289 /* |
|
290 ** FUNCTION: PR_DestroyWaitGroup |
|
291 ** DESCRIPTION: |
|
292 ** Undo the effects of PR_CreateWaitGroup(). Any receive wait operations |
|
293 ** on the group will be treated as if the each had been the target of a |
|
294 ** PR_CancelWaitFileDesc(). |
|
295 ** |
|
296 ** INPUT |
|
297 ** group Reference to a wait group previously allocated using |
|
298 ** PR_CreateWaitGroup(). |
|
299 ** RETURN |
|
300 ** PRStatus Will be PR_SUCCESS if the wait group was valid and there |
|
301 ** are no receive wait objects in that group. Otherwise |
|
302 ** will indicate PR_FAILURE. |
|
303 ** |
|
304 ** ERRORS |
|
305 ** PR_INVALID_ARGUMENT_ERROR |
|
306 ** The 'group' argument does not reference a known object. |
|
307 ** PR_INVALID_STATE_ERROR |
|
308 ** The group still contains receive wait objects. |
|
309 */ |
|
310 NSPR_API(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group); |
|
311 |
|
312 /* |
|
313 ** FUNCTION: PR_CreateMWaitEnumerator |
|
314 ** DESCRIPTION: |
|
315 ** The PR_CreateMWaitEnumerator() function returns a reference to an |
|
316 ** opaque PRMWaitEnumerator object. The enumerator object is required |
|
317 ** as an argument for each successive call in the stateless enumeration |
|
318 ** of the indicated wait group. |
|
319 ** |
|
320 ** group The wait group that the enumeration is intended to |
|
321 ** process. It may be be the default wait group (NULL). |
|
322 ** RETURN |
|
323 ** PRMWaitEnumerator* group |
|
324 ** A reference to an object that will be used to store |
|
325 ** intermediate state of enumerations. |
|
326 ** ERRORS |
|
327 ** Errors are indicated by the function returning a NULL. |
|
328 ** PR_INVALID_ARGUMENT_ERROR |
|
329 ** The 'group' argument does not reference a known object. |
|
330 ** PR_OUT_OF_MEMORY_ERROR |
|
331 */ |
|
332 NSPR_API(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group); |
|
333 |
|
334 /* |
|
335 ** FUNCTION: PR_DestroyMWaitEnumerator |
|
336 ** DESCRIPTION: |
|
337 ** Destroys the object created by PR_CreateMWaitEnumerator(). The reference |
|
338 ** used as an argument becomes invalid. |
|
339 ** |
|
340 ** INPUT |
|
341 ** PRMWaitEnumerator* enumerator |
|
342 ** The PRMWaitEnumerator object to destroy. |
|
343 ** RETURN |
|
344 ** PRStatus |
|
345 ** PR_SUCCESS if successful, PR_FAILURE otherwise. |
|
346 ** ERRORS |
|
347 ** PR_INVALID_ARGUMENT_ERROR |
|
348 ** The enumerator is invalid. |
|
349 */ |
|
350 NSPR_API(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator); |
|
351 |
|
352 /* |
|
353 ** FUNCTION: PR_EnumerateWaitGroup |
|
354 ** DESCRIPTION: |
|
355 ** PR_EnumerateWaitGroup is a thread safe enumerator over a wait group. |
|
356 ** Each call to the enumerator must present a valid PRMWaitEnumerator |
|
357 ** rererence and a pointer to the "previous" element returned from the |
|
358 ** enumeration process or a NULL. |
|
359 ** |
|
360 ** An enumeration is started by passing a NULL as the "previous" value. |
|
361 ** Subsequent calls to the enumerator must pass in the result of the |
|
362 ** previous call. The enumeration end is signaled by the runtime returning |
|
363 ** a NULL as the result. |
|
364 ** |
|
365 ** Modifications to the content of the wait group are allowed during |
|
366 ** an enumeration. The effect is that the enumeration may have to be |
|
367 ** "reset" and that may result in duplicates being returned from the |
|
368 ** enumeration. |
|
369 ** |
|
370 ** An enumeration may be abandoned at any time. The runtime is not |
|
371 ** keeping any state, so there are no issues in that regard. |
|
372 */ |
|
373 NSPR_API(PRRecvWait*) PR_EnumerateWaitGroup( |
|
374 PRMWaitEnumerator *enumerator, const PRRecvWait *previous); |
|
375 |
|
376 PR_END_EXTERN_C |
|
377 |
|
378 #endif /* defined(_PRMWAIT_H) */ |
|
379 |
|
380 /* prmwait.h */ |