Back to index

lightning-sunbird  0.9+nobinonly
prmwait.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #if defined(_PRMWAIT_H)
00039 #else
00040 #define _PRMWAIT_H
00041 
00042 #include "prio.h"
00043 #include "prtypes.h"
00044 #include "prclist.h"
00045 
00046 PR_BEGIN_EXTERN_C
00047 
00048 /********************************************************************************/
00049 /********************************************************************************/
00050 /********************************************************************************/
00051 /******************************       WARNING        ****************************/
00052 /********************************************************************************/
00053 /**************************** This is work in progress. *************************/
00054 /************************** Do not make any assumptions *************************/
00055 /************************** about the stability of this *************************/
00056 /************************** API or the underlying imple- ************************/
00057 /************************** mentation.                   ************************/
00058 /********************************************************************************/
00059 /********************************************************************************/
00060 
00061 /*
00062 ** STRUCTURE:   PRWaitGroup
00063 ** DESCRIPTION:
00064 **      The client may define several wait groups in order to semantically
00065 **      tie a collection of file descriptors for a single purpose. This allows
00066 **      easier dispatching of threads that returned with active file descriptors
00067 **      from the wait function.
00068 */
00069 typedef struct PRWaitGroup PRWaitGroup;
00070 
00071 /*
00072 ** ENUMERATION: PRMWStatus
00073 ** DESCRIPTION:
00074 **      This enumeration is used to indicate the completion status of
00075 **      a receive wait object. Generally stated, a positive value indicates
00076 **      that the operation is not yet complete. A zero value indicates
00077 **      success (similar to PR_SUCCESS) and any negative value is an
00078 **      indication of failure. The reason for the failure can be retrieved
00079 **      by calling PR_GetError().
00080 **
00081 **  PR_MW_PENDING       The operation is still pending. None of the other
00082 **                      fields of the object are currently valid.
00083 **  PR_MW_SUCCESS       The operation is complete and it was successful.
00084 **  PR_MW_FAILURE       The operation failed. The reason for the failure
00085 **                      can be retrieved by calling PR_GetError().
00086 **  PR_MW_TIMEOUT       The amount of time allowed for by the object's
00087 **                      'timeout' field has expired w/o the operation
00088 **                      otherwise coming to closure.
00089 **  PR_MW_INTERRUPT     The operation was cancelled, either by the client
00090 **                      calling PR_CancelWaitFileDesc() or destroying the
00091 **                      entire wait group (PR_DestroyWaitGroup()).
00092 */
00093 typedef enum PRMWStatus
00094 {
00095     PR_MW_PENDING = 1,
00096     PR_MW_SUCCESS = 0,
00097     PR_MW_FAILURE = -1,
00098     PR_MW_TIMEOUT = -2,
00099     PR_MW_INTERRUPT = -3
00100 } PRMWStatus;
00101 
00102 /*
00103 ** STRUCTURE:   PRMemoryDescriptor
00104 ** DESCRIPTION:
00105 **      THis is a descriptor for an interval of memory. It contains a
00106 **      pointer to the first byte of that memory and the length (in
00107 **      bytes) of the interval.
00108 */
00109 typedef struct PRMemoryDescriptor
00110 {
00111     void *start;                /* pointer to first byte of memory */
00112     PRSize length;              /* length (in bytes) of memory interval */
00113 } PRMemoryDescriptor;
00114 
00115 /*
00116 ** STRUCTURE:   PRMWaitClientData
00117 ** DESCRIPTION:
00118 **      An opague stucture for which a client MAY give provide a concrete
00119 **      definition and associate with a receive descriptor. The NSPR runtime
00120 **      does not manage this field. It is completely up to the client.
00121 */
00122 typedef struct PRMWaitClientData PRMWaitClientData;
00123 
00124 /*
00125 ** STRUCTURE:   PRRecvWait
00126 ** DESCRIPTION:
00127 **      A receive wait object contains the file descriptor that is subject
00128 **      to the wait and the amount of time (beginning epoch established
00129 **      when the object is presented to the runtime) the the channel should
00130 **      block before abandoning the process.
00131 **
00132 **      The success of the wait operation will be noted in the object's
00133 **      'outcome' field. The fields are not valid when the NSPR runtime
00134 **      is in possession of the object.
00135 **
00136 **      The memory descriptor describes an interval of writable memory
00137 **      in the caller's address space where data from an initial read
00138 **      can be placed. The description may indicate a null interval.
00139 */
00140 typedef struct PRRecvWait 
00141 {
00142     PRCList internal;           /* internal runtime linkages */
00143 
00144     PRFileDesc *fd;             /* file descriptor associated w/ object */
00145     PRMWStatus outcome;         /* outcome of the current/last operation */
00146     PRIntervalTime timeout;     /* time allowed for entire operation */
00147 
00148     PRInt32 bytesRecv;          /* number of bytes transferred into buffer */
00149     PRMemoryDescriptor buffer;  /* where to store first segment of input data */
00150     PRMWaitClientData *client;  /* pointer to arbitrary client defined data */
00151 } PRRecvWait;
00152 
00153 /*
00154 ** STRUCTURE:   PRMWaitEnumerator
00155 ** DESCRIPTION:
00156 **      An enumeration object is used to store the state of an existing
00157 **      enumeration over a wait group. The opaque object must be allocated
00158 **      by the client and the reference presented on each call to the
00159 **      pseudo-stateless enumerator. The enumeration objects are sharable
00160 **      only in serial fashion.
00161 */
00162 typedef struct PRMWaitEnumerator PRMWaitEnumerator;
00163 
00164 
00165 /*
00166 ** FUNCTION:    PR_AddWaitFileDesc
00167 ** DESCRIPTION:
00168 **      This function will effectively add a file descriptor to the
00169 **      list of those waiting for network receive. The new descriptor
00170 **      will be semantically tied to the wait group specified.
00171 **
00172 **      The ownership for the storage pointed to by 'desc' is temporarily
00173 **      passed over the the NSPR runtime. It will be handed back by the
00174 **      function PR_WaitRecvReady().
00175 **
00176 **  INPUTS
00177 **      group       A reference to a PRWaitGroup or NULL. Wait groups are
00178 **                  created by calling PR_CreateWaitGroup() and are used
00179 **                  to semantically group various file descriptors by the
00180 **                  client's application.
00181 **      desc        A reference to a valid PRRecvWait. The object of the
00182 **                  reference must be preserved and not be modified
00183 **                  until its ownership is returned to the client.
00184 **  RETURN
00185 **      PRStatus    An indication of success. If equal to PR_FAILUE details
00186 **                  of the failure are avaiable via PR_GetError().
00187 **
00188 **  ERRORS
00189 **      PR_INVALID_ARGUMENT_ERROR
00190 **                  Invalid 'group' identifier or duplicate 'desc' object.
00191 **      PR_OUT_OF_MEMORY_ERROR
00192 **                  Insuffient memory for internal data structures.
00193 **      PR_INVALID_STATE_ERROR
00194 **                  The group is being destroyed.
00195 */
00196 NSPR_API(PRStatus) PR_AddWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc);
00197 
00198 /*
00199 ** FUNCTION:    PR_WaitRecvReady
00200 ** DESCRIPTION:
00201 **      PR_WaitRecvReady will block the calling thread until one of the
00202 **      file descriptors that have been added via PR_AddWaitFileDesc is
00203 **      available for input I/O.
00204 **  INPUT
00205 **      group       A pointer to a valid PRWaitGroup or NULL (the null
00206 **                  group. The function will block the caller until a
00207 **                  channel from the wait group becomes ready for receive
00208 **                  or there is some sort of error.
00209 **  RETURN
00210 **      PRReciveWait
00211 **                  When the caller is resumed it is either returned a
00212 **                  valid pointer to a previously added receive wait or
00213 **                  a NULL. If the latter, the function has terminated
00214 **                  for a reason that can be determined by calling
00215 **                  PR_GetError().
00216 **                  If a valid pointer is returned, the reference is to the
00217 **                  file descriptor contained in the receive wait object.
00218 **                  The outcome of the wait operation may still fail, and
00219 **                  if it has, that fact will be noted in the object's
00220 **                  outcome field. Details can be retrieved from PR_GetError().
00221 **
00222 **  ERRORS
00223 **      PR_INVALID_ARGUMENT_ERROR
00224 **                  The 'group' is not known by the runtime.
00225 **      PR_PENDING_INTERRUPT_ERROR
00226                     The thread was interrupted.
00227 **      PR_INVALID_STATE_ERROR
00228 **                  The group is being destroyed.
00229 */
00230 NSPR_API(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group);
00231 
00232 /*
00233 ** FUNCTION:    PR_CancelWaitFileDesc
00234 ** DESCRIPTION:
00235 **      PR_CancelWaitFileDesc is provided as a means for cancelling operations
00236 **      on objects previously submitted by use of PR_AddWaitFileDesc(). If
00237 **      the runtime knows of the object, it will be marked as having failed
00238 **      because it was interrupted (similar to PR_Interrupt()). The first
00239 **      available thread waiting on the group will be made to return the
00240 **      PRRecvWait object with the outcome noted.
00241 **
00242 **  INPUTS
00243 **      group       The wait group under which the wait receive object was
00244 **                  added.
00245 **      desc        A pointer to the wait receive object that is to be
00246 **                  cancelled.
00247 **  RETURN
00248 **      PRStatus    If the wait receive object was located and associated
00249 **                  with the specified wait group, the status returned will
00250 **                  be PR_SUCCESS. There is still a race condition that would
00251 **                  permit the offected object to complete normally, but it
00252 **                  is assured that it will complete in the near future.
00253 **                  If the receive object or wait group are invalid, the
00254 **                  function will return with a status of PR_FAILURE.
00255 **
00256 **  ERRORS
00257 **      PR_INVALID_ARGUMENT_ERROR
00258 **                  The 'group' argument is not recognized as a valid group.
00259 **      PR_COLLECTION_EMPTY_ERROR
00260 **                  There are no more receive wait objects in the group's
00261 **                  collection.
00262 **      PR_INVALID_STATE_ERROR
00263 **                  The group is being destroyed.
00264 */
00265 NSPR_API(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc);
00266 
00267 /*
00268 ** FUNCTION:    PR_CancelWaitGroup
00269 ** DESCRIPTION:
00270 **      PR_CancelWaitGroup is provided as a means for cancelling operations
00271 **      on objects previously submitted by use of PR_AddWaitFileDesc(). Each
00272 **      successive call will return a pointer to a PRRecvWait object that
00273 **      was previously registered via PR_AddWaitFileDesc(). If no wait
00274 **      objects are associated with the wait group, a NULL will be returned.
00275 **      This function should be called in a loop until a NULL is returned
00276 **      to reclaim all the wait objects prior to calling PR_DestroyWaitGroup().
00277 **
00278 **  INPUTS
00279 **      group       The wait group under which the wait receive object was
00280 **                  added.
00281 **  RETURN
00282 **      PRRecvWait* If the wait group is valid and at least one receive wait
00283 **                  object is present in the group, that object will be
00284 **                  marked as PR_MW_INTERRUPT'd and removed from the group's
00285 **                  queues. Otherwise a NULL will be returned and the reason
00286 **                  for the NULL may be retrieved by calling PR_GetError().
00287 **
00288 **  ERRORS
00289 **      PR_INVALID_ARGUMENT_ERROR
00290 **      PR_GROUP_EMPTY_ERROR
00291 */
00292 NSPR_API(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group);
00293 
00294 /*
00295 ** FUNCTION:    PR_CreateWaitGroup
00296 ** DESCRIPTION:
00297 **      A wait group is an opaque object that a client may create in order
00298 **      to semantically group various wait requests. Each wait group is
00299 **      unique, including the default wait group (NULL). A wait request
00300 **      that was added under a wait group will only be serviced by a caller
00301 **      that specified the same wait group.
00302 **
00303 **  INPUT
00304 **      size        The size of the hash table to be used to contain the
00305 **                  receive wait objects. This is just the initial size.
00306 **                  It will grow as it needs to, but to avoid that hassle
00307 **                  one can suggest a suitable size initially. It should
00308 **                  be ~30% larger than the maximum number of receive wait
00309 **                  objects expected.
00310 **  RETURN
00311 **      PRWaitGroup If successful, the function will return a pointer to an
00312 **                  object that was allocated by and owned by the runtime.
00313 **                  The reference remains valid until it is explicitly destroyed
00314 **                  by calling PR_DestroyWaitGroup().
00315 **
00316 **  ERRORS
00317 **      PR_OUT_OF_MEMORY_ERROR
00318 */
00319 NSPR_API(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size);
00320 
00321 /*
00322 ** FUNCTION:    PR_DestroyWaitGroup
00323 ** DESCRIPTION:
00324 **      Undo the effects of PR_CreateWaitGroup(). Any receive wait operations
00325 **      on the group will be treated as if the each had been the target of a
00326 **      PR_CancelWaitFileDesc().
00327 **
00328 **  INPUT
00329 **      group       Reference to a wait group previously allocated using
00330 **                  PR_CreateWaitGroup().
00331 **  RETURN
00332 **      PRStatus    Will be PR_SUCCESS if the wait group was valid and there
00333 **                  are no receive wait objects in that group. Otherwise
00334 **                  will indicate PR_FAILURE.
00335 **
00336 **  ERRORS
00337 **      PR_INVALID_ARGUMENT_ERROR
00338 **                  The 'group' argument does not reference a known object.
00339 **      PR_INVALID_STATE_ERROR
00340 **                  The group still contains receive wait objects.
00341 */
00342 NSPR_API(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group);
00343 
00344 /*
00345 ** FUNCTION:    PR_CreateMWaitEnumerator
00346 ** DESCRIPTION:
00347 **      The PR_CreateMWaitEnumerator() function returns a reference to an
00348 **      opaque PRMWaitEnumerator object. The enumerator object is required
00349 **      as an argument for each successive call in the stateless enumeration
00350 **      of the indicated wait group.
00351 **
00352 **      group       The wait group that the enumeration is intended to
00353 **                  process. It may be be the default wait group (NULL).
00354 ** RETURN
00355 **      PRMWaitEnumerator* group
00356 **                  A reference to an object that will be used to store
00357 **                  intermediate state of enumerations.
00358 ** ERRORS
00359 **      Errors are indicated by the function returning a NULL.
00360 **      PR_INVALID_ARGUMENT_ERROR
00361 **                  The 'group' argument does not reference a known object.
00362 **      PR_OUT_OF_MEMORY_ERROR
00363 */
00364 NSPR_API(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group);
00365 
00366 /*
00367 ** FUNCTION:    PR_DestroyMWaitEnumerator
00368 ** DESCRIPTION:
00369 **      Destroys the object created by PR_CreateMWaitEnumerator(). The reference
00370 **      used as an argument becomes invalid.
00371 **
00372 ** INPUT
00373 **      PRMWaitEnumerator* enumerator
00374 **          The PRMWaitEnumerator object to destroy.
00375 ** RETURN
00376 **      PRStatus
00377 **          PR_SUCCESS if successful, PR_FAILURE otherwise.
00378 ** ERRORS
00379 **      PR_INVALID_ARGUMENT_ERROR
00380 **                  The enumerator is invalid.
00381 */
00382 NSPR_API(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator);
00383 
00384 /*
00385 ** FUNCTION:    PR_EnumerateWaitGroup
00386 ** DESCRIPTION:
00387 **      PR_EnumerateWaitGroup is a thread safe enumerator over a wait group.
00388 **      Each call to the enumerator must present a valid PRMWaitEnumerator
00389 **      rererence and a pointer to the "previous" element returned from the
00390 **      enumeration process or a NULL.
00391 **
00392 **      An enumeration is started by passing a NULL as the "previous" value.
00393 **      Subsequent calls to the enumerator must pass in the result of the
00394 **      previous call. The enumeration end is signaled by the runtime returning
00395 **      a NULL as the result.
00396 **
00397 **      Modifications to the content of the wait group are allowed during
00398 **      an enumeration. The effect is that the enumeration may have to be
00399 **      "reset" and that may result in duplicates being returned from the
00400 **      enumeration.
00401 **
00402 **      An enumeration may be abandoned at any time. The runtime is not
00403 **      keeping any state, so there are no issues in that regard.
00404 */
00405 NSPR_API(PRRecvWait*) PR_EnumerateWaitGroup(
00406     PRMWaitEnumerator *enumerator, const PRRecvWait *previous);
00407    
00408 PR_END_EXTERN_C
00409 
00410 #endif /* defined(_PRMWAIT_H) */
00411 
00412 /* prmwait.h */