|
|
1.1 root 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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.