|
|
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.