Wed, 31 Dec 2014 06:09:35 +0100
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 */ |