summaryrefslogtreecommitdiff
path: root/pr/include/prmwait.h
blob: e4cabda408fb09878459bf7a3f9fa97f67b1a784 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Netscape Portable Runtime (NSPR).
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#if defined(_PRMWAIT_H)
#else
#define _PRMWAIT_H

#include "prio.h"
#include "prtypes.h"
#include "prclist.h"

PR_BEGIN_EXTERN_C

/********************************************************************************/
/********************************************************************************/
/********************************************************************************/
/******************************       WARNING        ****************************/
/********************************************************************************/
/**************************** This is work in progress. *************************/
/************************** Do not make any assumptions *************************/
/************************** about the stability of this *************************/
/************************** API or the underlying imple- ************************/
/************************** mentation.                   ************************/
/********************************************************************************/
/********************************************************************************/

/*
** STRUCTURE:   PRWaitGroup
** DESCRIPTION:
**      The client may define several wait groups in order to semantically
**      tie a collection of file descriptors for a single purpose. This allows
**      easier dispatching of threads that returned with active file descriptors
**      from the wait function.
*/
typedef struct PRWaitGroup PRWaitGroup;

/*
** ENUMERATION: PRMWStatus
** DESCRIPTION:
**      This enumeration is used to indicate the completion status of
**      a receive wait object. Generally stated, a positive value indicates
**      that the operation is not yet complete. A zero value indicates
**      success (similar to PR_SUCCESS) and any negative value is an
**      indication of failure. The reason for the failure can be retrieved
**      by calling PR_GetError().
**
**  PR_MW_PENDING       The operation is still pending. None of the other
**                      fields of the object are currently valid.
**  PR_MW_SUCCESS       The operation is complete and it was successful.
**  PR_MW_FAILURE       The operation failed. The reason for the failure
**                      can be retrieved by calling PR_GetError().
**  PR_MW_TIMEOUT       The amount of time allowed for by the object's
**                      'timeout' field has expired w/o the operation
**                      otherwise coming to closure.
**  PR_MW_INTERRUPT     The operation was cancelled, either by the client
**                      calling PR_CancelWaitFileDesc() or destroying the
**                      entire wait group (PR_DestroyWaitGroup()).
*/
typedef enum PRMWStatus
{
    PR_MW_PENDING = 1,
    PR_MW_SUCCESS = 0,
    PR_MW_FAILURE = -1,
    PR_MW_TIMEOUT = -2,
    PR_MW_INTERRUPT = -3
} PRMWStatus;

/*
** STRUCTURE:   PRMemoryDescriptor
** DESCRIPTION:
**      THis is a descriptor for an interval of memory. It contains a
**      pointer to the first byte of that memory and the length (in
**      bytes) of the interval.
*/
typedef struct PRMemoryDescriptor
{
    void *start;                /* pointer to first byte of memory */
    PRSize length;              /* length (in bytes) of memory interval */
} PRMemoryDescriptor;

/*
** STRUCTURE:   PRMWaitClientData
** DESCRIPTION:
**      An opague stucture for which a client MAY give provide a concrete
**      definition and associate with a receive descriptor. The NSPR runtime
**      does not manage this field. It is completely up to the client.
*/
typedef struct PRMWaitClientData PRMWaitClientData;

/*
** STRUCTURE:   PRRecvWait
** DESCRIPTION:
**      A receive wait object contains the file descriptor that is subject
**      to the wait and the amount of time (beginning epoch established
**      when the object is presented to the runtime) the the channel should
**      block before abandoning the process.
**
**      The success of the wait operation will be noted in the object's
**      'outcome' field. The fields are not valid when the NSPR runtime
**      is in possession of the object.
**
**      The memory descriptor describes an interval of writable memory
**      in the caller's address space where data from an initial read
**      can be placed. The description may indicate a null interval.
*/
typedef struct PRRecvWait 
{
    PRCList internal;           /* internal runtime linkages */

    PRFileDesc *fd;             /* file descriptor associated w/ object */
    PRMWStatus outcome;         /* outcome of the current/last operation */
    PRIntervalTime timeout;     /* time allowed for entire operation */

    PRInt32 bytesRecv;          /* number of bytes transferred into buffer */
    PRMemoryDescriptor buffer;  /* where to store first segment of input data */
    PRMWaitClientData *client;  /* pointer to arbitrary client defined data */
} PRRecvWait;

/*
** STRUCTURE:   PRMWaitEnumerator
** DESCRIPTION:
**      An enumeration object is used to store the state of an existing
**      enumeration over a wait group. The opaque object must be allocated
**      by the client and the reference presented on each call to the
**      pseudo-stateless enumerator. The enumeration objects are sharable
**      only in serial fashion.
*/
typedef struct PRMWaitEnumerator PRMWaitEnumerator;


/*
** FUNCTION:    PR_AddWaitFileDesc
** DESCRIPTION:
**      This function will effectively add a file descriptor to the
**      list of those waiting for network receive. The new descriptor
**      will be semantically tied to the wait group specified.
**
**      The ownership for the storage pointed to by 'desc' is temporarily
**      passed over the the NSPR runtime. It will be handed back by the
**      function PR_WaitRecvReady().
**
**  INPUTS
**      group       A reference to a PRWaitGroup or NULL. Wait groups are
**                  created by calling PR_CreateWaitGroup() and are used
**                  to semantically group various file descriptors by the
**                  client's application.
**      desc        A reference to a valid PRRecvWait. The object of the
**                  reference must be preserved and not be modified
**                  until its ownership is returned to the client.
**  RETURN
**      PRStatus    An indication of success. If equal to PR_FAILUE details
**                  of the failure are avaiable via PR_GetError().
**
**  ERRORS
**      PR_INVALID_ARGUMENT_ERROR
**                  Invalid 'group' identifier or duplicate 'desc' object.
**      PR_OUT_OF_MEMORY_ERROR
**                  Insuffient memory for internal data structures.
**      PR_INVALID_STATE_ERROR
**                  The group is being destroyed.
*/
NSPR_API(PRStatus) PR_AddWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc);

/*
** FUNCTION:    PR_WaitRecvReady
** DESCRIPTION:
**      PR_WaitRecvReady will block the calling thread until one of the
**      file descriptors that have been added via PR_AddWaitFileDesc is
**      available for input I/O.
**  INPUT
**      group       A pointer to a valid PRWaitGroup or NULL (the null
**                  group. The function will block the caller until a
**                  channel from the wait group becomes ready for receive
**                  or there is some sort of error.
**  RETURN
**      PRReciveWait
**                  When the caller is resumed it is either returned a
**                  valid pointer to a previously added receive wait or
**                  a NULL. If the latter, the function has terminated
**                  for a reason that can be determined by calling
**                  PR_GetError().
**                  If a valid pointer is returned, the reference is to the
**                  file descriptor contained in the receive wait object.
**                  The outcome of the wait operation may still fail, and
**                  if it has, that fact will be noted in the object's
**                  outcome field. Details can be retrieved from PR_GetError().
**
**  ERRORS
**      PR_INVALID_ARGUMENT_ERROR
**                  The 'group' is not known by the runtime.
**      PR_PENDING_INTERRUPT_ERROR
                    The thread was interrupted.
**      PR_INVALID_STATE_ERROR
**                  The group is being destroyed.
*/
NSPR_API(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group);

/*
** FUNCTION:    PR_CancelWaitFileDesc
** DESCRIPTION:
**      PR_CancelWaitFileDesc is provided as a means for cancelling operations
**      on objects previously submitted by use of PR_AddWaitFileDesc(). If
**      the runtime knows of the object, it will be marked as having failed
**      because it was interrupted (similar to PR_Interrupt()). The first
**      available thread waiting on the group will be made to return the
**      PRRecvWait object with the outcome noted.
**
**  INPUTS
**      group       The wait group under which the wait receive object was
**                  added.
**      desc        A pointer to the wait receive object that is to be
**                  cancelled.
**  RETURN
**      PRStatus    If the wait receive object was located and associated
**                  with the specified wait group, the status returned will
**                  be PR_SUCCESS. There is still a race condition that would
**                  permit the offected object to complete normally, but it
**                  is assured that it will complete in the near future.
**                  If the receive object or wait group are invalid, the
**                  function will return with a status of PR_FAILURE.
**
**  ERRORS
**      PR_INVALID_ARGUMENT_ERROR
**                  The 'group' argument is not recognized as a valid group.
**      PR_COLLECTION_EMPTY_ERROR
**                  There are no more receive wait objects in the group's
**                  collection.
**      PR_INVALID_STATE_ERROR
**                  The group is being destroyed.
*/
NSPR_API(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc);

/*
** FUNCTION:    PR_CancelWaitGroup
** DESCRIPTION:
**      PR_CancelWaitGroup is provided as a means for cancelling operations
**      on objects previously submitted by use of PR_AddWaitFileDesc(). Each
**      successive call will return a pointer to a PRRecvWait object that
**      was previously registered via PR_AddWaitFileDesc(). If no wait
**      objects are associated with the wait group, a NULL will be returned.
**      This function should be called in a loop until a NULL is returned
**      to reclaim all the wait objects prior to calling PR_DestroyWaitGroup().
**
**  INPUTS
**      group       The wait group under which the wait receive object was
**                  added.
**  RETURN
**      PRRecvWait* If the wait group is valid and at least one receive wait
**                  object is present in the group, that object will be
**                  marked as PR_MW_INTERRUPT'd and removed from the group's
**                  queues. Otherwise a NULL will be returned and the reason
**                  for the NULL may be retrieved by calling PR_GetError().
**
**  ERRORS
**      PR_INVALID_ARGUMENT_ERROR
**      PR_GROUP_EMPTY_ERROR
*/
NSPR_API(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group);

/*
** FUNCTION:    PR_CreateWaitGroup
** DESCRIPTION:
**      A wait group is an opaque object that a client may create in order
**      to semantically group various wait requests. Each wait group is
**      unique, including the default wait group (NULL). A wait request
**      that was added under a wait group will only be serviced by a caller
**      that specified the same wait group.
**
**  INPUT
**      size        The size of the hash table to be used to contain the
**                  receive wait objects. This is just the initial size.
**                  It will grow as it needs to, but to avoid that hassle
**                  one can suggest a suitable size initially. It should
**                  be ~30% larger than the maximum number of receive wait
**                  objects expected.
**  RETURN
**      PRWaitGroup If successful, the function will return a pointer to an
**                  object that was allocated by and owned by the runtime.
**                  The reference remains valid until it is explicitly destroyed
**                  by calling PR_DestroyWaitGroup().
**
**  ERRORS
**      PR_OUT_OF_MEMORY_ERROR
*/
NSPR_API(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size);

/*
** FUNCTION:    PR_DestroyWaitGroup
** DESCRIPTION:
**      Undo the effects of PR_CreateWaitGroup(). Any receive wait operations
**      on the group will be treated as if the each had been the target of a
**      PR_CancelWaitFileDesc().
**
**  INPUT
**      group       Reference to a wait group previously allocated using
**                  PR_CreateWaitGroup().
**  RETURN
**      PRStatus    Will be PR_SUCCESS if the wait group was valid and there
**                  are no receive wait objects in that group. Otherwise
**                  will indicate PR_FAILURE.
**
**  ERRORS
**      PR_INVALID_ARGUMENT_ERROR
**                  The 'group' argument does not reference a known object.
**      PR_INVALID_STATE_ERROR
**                  The group still contains receive wait objects.
*/
NSPR_API(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group);

/*
** FUNCTION:    PR_CreateMWaitEnumerator
** DESCRIPTION:
**      The PR_CreateMWaitEnumerator() function returns a reference to an
**      opaque PRMWaitEnumerator object. The enumerator object is required
**      as an argument for each successive call in the stateless enumeration
**      of the indicated wait group.
**
**      group       The wait group that the enumeration is intended to
**                  process. It may be be the default wait group (NULL).
** RETURN
**      PRMWaitEnumerator* group
**                  A reference to an object that will be used to store
**                  intermediate state of enumerations.
** ERRORS
**      Errors are indicated by the function returning a NULL.
**      PR_INVALID_ARGUMENT_ERROR
**                  The 'group' argument does not reference a known object.
**      PR_OUT_OF_MEMORY_ERROR
*/
NSPR_API(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group);

/*
** FUNCTION:    PR_DestroyMWaitEnumerator
** DESCRIPTION:
**      Destroys the object created by PR_CreateMWaitEnumerator(). The reference
**      used as an argument becomes invalid.
**
** INPUT
**      PRMWaitEnumerator* enumerator
**          The PRMWaitEnumerator object to destroy.
** RETURN
**      PRStatus
**          PR_SUCCESS if successful, PR_FAILURE otherwise.
** ERRORS
**      PR_INVALID_ARGUMENT_ERROR
**                  The enumerator is invalid.
*/
NSPR_API(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator);

/*
** FUNCTION:    PR_EnumerateWaitGroup
** DESCRIPTION:
**      PR_EnumerateWaitGroup is a thread safe enumerator over a wait group.
**      Each call to the enumerator must present a valid PRMWaitEnumerator
**      rererence and a pointer to the "previous" element returned from the
**      enumeration process or a NULL.
**
**      An enumeration is started by passing a NULL as the "previous" value.
**      Subsequent calls to the enumerator must pass in the result of the
**      previous call. The enumeration end is signaled by the runtime returning
**      a NULL as the result.
**
**      Modifications to the content of the wait group are allowed during
**      an enumeration. The effect is that the enumeration may have to be
**      "reset" and that may result in duplicates being returned from the
**      enumeration.
**
**      An enumeration may be abandoned at any time. The runtime is not
**      keeping any state, so there are no issues in that regard.
*/
NSPR_API(PRRecvWait*) PR_EnumerateWaitGroup(
    PRMWaitEnumerator *enumerator, const PRRecvWait *previous);
   
PR_END_EXTERN_C

#endif /* defined(_PRMWAIT_H) */

/* prmwait.h */