Line data Source code
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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 */
|