nsprpub/pr/include/prmwait.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial