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