tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 */