prmwait.h (16264B)
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 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 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 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 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 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 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 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 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 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 */