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