1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/include/prmwait.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,380 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#if defined(_PRMWAIT_H) 1.10 +#else 1.11 +#define _PRMWAIT_H 1.12 + 1.13 +#include "prio.h" 1.14 +#include "prtypes.h" 1.15 +#include "prclist.h" 1.16 + 1.17 +PR_BEGIN_EXTERN_C 1.18 + 1.19 +/********************************************************************************/ 1.20 +/********************************************************************************/ 1.21 +/********************************************************************************/ 1.22 +/****************************** WARNING ****************************/ 1.23 +/********************************************************************************/ 1.24 +/**************************** This is work in progress. *************************/ 1.25 +/************************** Do not make any assumptions *************************/ 1.26 +/************************** about the stability of this *************************/ 1.27 +/************************** API or the underlying imple- ************************/ 1.28 +/************************** mentation. ************************/ 1.29 +/********************************************************************************/ 1.30 +/********************************************************************************/ 1.31 + 1.32 +/* 1.33 +** STRUCTURE: PRWaitGroup 1.34 +** DESCRIPTION: 1.35 +** The client may define several wait groups in order to semantically 1.36 +** tie a collection of file descriptors for a single purpose. This allows 1.37 +** easier dispatching of threads that returned with active file descriptors 1.38 +** from the wait function. 1.39 +*/ 1.40 +typedef struct PRWaitGroup PRWaitGroup; 1.41 + 1.42 +/* 1.43 +** ENUMERATION: PRMWStatus 1.44 +** DESCRIPTION: 1.45 +** This enumeration is used to indicate the completion status of 1.46 +** a receive wait object. Generally stated, a positive value indicates 1.47 +** that the operation is not yet complete. A zero value indicates 1.48 +** success (similar to PR_SUCCESS) and any negative value is an 1.49 +** indication of failure. The reason for the failure can be retrieved 1.50 +** by calling PR_GetError(). 1.51 +** 1.52 +** PR_MW_PENDING The operation is still pending. None of the other 1.53 +** fields of the object are currently valid. 1.54 +** PR_MW_SUCCESS The operation is complete and it was successful. 1.55 +** PR_MW_FAILURE The operation failed. The reason for the failure 1.56 +** can be retrieved by calling PR_GetError(). 1.57 +** PR_MW_TIMEOUT The amount of time allowed for by the object's 1.58 +** 'timeout' field has expired w/o the operation 1.59 +** otherwise coming to closure. 1.60 +** PR_MW_INTERRUPT The operation was cancelled, either by the client 1.61 +** calling PR_CancelWaitFileDesc() or destroying the 1.62 +** entire wait group (PR_DestroyWaitGroup()). 1.63 +*/ 1.64 +typedef enum PRMWStatus 1.65 +{ 1.66 + PR_MW_PENDING = 1, 1.67 + PR_MW_SUCCESS = 0, 1.68 + PR_MW_FAILURE = -1, 1.69 + PR_MW_TIMEOUT = -2, 1.70 + PR_MW_INTERRUPT = -3 1.71 +} PRMWStatus; 1.72 + 1.73 +/* 1.74 +** STRUCTURE: PRMemoryDescriptor 1.75 +** DESCRIPTION: 1.76 +** THis is a descriptor for an interval of memory. It contains a 1.77 +** pointer to the first byte of that memory and the length (in 1.78 +** bytes) of the interval. 1.79 +*/ 1.80 +typedef struct PRMemoryDescriptor 1.81 +{ 1.82 + void *start; /* pointer to first byte of memory */ 1.83 + PRSize length; /* length (in bytes) of memory interval */ 1.84 +} PRMemoryDescriptor; 1.85 + 1.86 +/* 1.87 +** STRUCTURE: PRMWaitClientData 1.88 +** DESCRIPTION: 1.89 +** An opague stucture for which a client MAY give provide a concrete 1.90 +** definition and associate with a receive descriptor. The NSPR runtime 1.91 +** does not manage this field. It is completely up to the client. 1.92 +*/ 1.93 +typedef struct PRMWaitClientData PRMWaitClientData; 1.94 + 1.95 +/* 1.96 +** STRUCTURE: PRRecvWait 1.97 +** DESCRIPTION: 1.98 +** A receive wait object contains the file descriptor that is subject 1.99 +** to the wait and the amount of time (beginning epoch established 1.100 +** when the object is presented to the runtime) the the channel should 1.101 +** block before abandoning the process. 1.102 +** 1.103 +** The success of the wait operation will be noted in the object's 1.104 +** 'outcome' field. The fields are not valid when the NSPR runtime 1.105 +** is in possession of the object. 1.106 +** 1.107 +** The memory descriptor describes an interval of writable memory 1.108 +** in the caller's address space where data from an initial read 1.109 +** can be placed. The description may indicate a null interval. 1.110 +*/ 1.111 +typedef struct PRRecvWait 1.112 +{ 1.113 + PRCList internal; /* internal runtime linkages */ 1.114 + 1.115 + PRFileDesc *fd; /* file descriptor associated w/ object */ 1.116 + PRMWStatus outcome; /* outcome of the current/last operation */ 1.117 + PRIntervalTime timeout; /* time allowed for entire operation */ 1.118 + 1.119 + PRInt32 bytesRecv; /* number of bytes transferred into buffer */ 1.120 + PRMemoryDescriptor buffer; /* where to store first segment of input data */ 1.121 + PRMWaitClientData *client; /* pointer to arbitrary client defined data */ 1.122 +} PRRecvWait; 1.123 + 1.124 +/* 1.125 +** STRUCTURE: PRMWaitEnumerator 1.126 +** DESCRIPTION: 1.127 +** An enumeration object is used to store the state of an existing 1.128 +** enumeration over a wait group. The opaque object must be allocated 1.129 +** by the client and the reference presented on each call to the 1.130 +** pseudo-stateless enumerator. The enumeration objects are sharable 1.131 +** only in serial fashion. 1.132 +*/ 1.133 +typedef struct PRMWaitEnumerator PRMWaitEnumerator; 1.134 + 1.135 + 1.136 +/* 1.137 +** FUNCTION: PR_AddWaitFileDesc 1.138 +** DESCRIPTION: 1.139 +** This function will effectively add a file descriptor to the 1.140 +** list of those waiting for network receive. The new descriptor 1.141 +** will be semantically tied to the wait group specified. 1.142 +** 1.143 +** The ownership for the storage pointed to by 'desc' is temporarily 1.144 +** passed over the the NSPR runtime. It will be handed back by the 1.145 +** function PR_WaitRecvReady(). 1.146 +** 1.147 +** INPUTS 1.148 +** group A reference to a PRWaitGroup or NULL. Wait groups are 1.149 +** created by calling PR_CreateWaitGroup() and are used 1.150 +** to semantically group various file descriptors by the 1.151 +** client's application. 1.152 +** desc A reference to a valid PRRecvWait. The object of the 1.153 +** reference must be preserved and not be modified 1.154 +** until its ownership is returned to the client. 1.155 +** RETURN 1.156 +** PRStatus An indication of success. If equal to PR_FAILUE details 1.157 +** of the failure are avaiable via PR_GetError(). 1.158 +** 1.159 +** ERRORS 1.160 +** PR_INVALID_ARGUMENT_ERROR 1.161 +** Invalid 'group' identifier or duplicate 'desc' object. 1.162 +** PR_OUT_OF_MEMORY_ERROR 1.163 +** Insuffient memory for internal data structures. 1.164 +** PR_INVALID_STATE_ERROR 1.165 +** The group is being destroyed. 1.166 +*/ 1.167 +NSPR_API(PRStatus) PR_AddWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc); 1.168 + 1.169 +/* 1.170 +** FUNCTION: PR_WaitRecvReady 1.171 +** DESCRIPTION: 1.172 +** PR_WaitRecvReady will block the calling thread until one of the 1.173 +** file descriptors that have been added via PR_AddWaitFileDesc is 1.174 +** available for input I/O. 1.175 +** INPUT 1.176 +** group A pointer to a valid PRWaitGroup or NULL (the null 1.177 +** group. The function will block the caller until a 1.178 +** channel from the wait group becomes ready for receive 1.179 +** or there is some sort of error. 1.180 +** RETURN 1.181 +** PRReciveWait 1.182 +** When the caller is resumed it is either returned a 1.183 +** valid pointer to a previously added receive wait or 1.184 +** a NULL. If the latter, the function has terminated 1.185 +** for a reason that can be determined by calling 1.186 +** PR_GetError(). 1.187 +** If a valid pointer is returned, the reference is to the 1.188 +** file descriptor contained in the receive wait object. 1.189 +** The outcome of the wait operation may still fail, and 1.190 +** if it has, that fact will be noted in the object's 1.191 +** outcome field. Details can be retrieved from PR_GetError(). 1.192 +** 1.193 +** ERRORS 1.194 +** PR_INVALID_ARGUMENT_ERROR 1.195 +** The 'group' is not known by the runtime. 1.196 +** PR_PENDING_INTERRUPT_ERROR 1.197 + The thread was interrupted. 1.198 +** PR_INVALID_STATE_ERROR 1.199 +** The group is being destroyed. 1.200 +*/ 1.201 +NSPR_API(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group); 1.202 + 1.203 +/* 1.204 +** FUNCTION: PR_CancelWaitFileDesc 1.205 +** DESCRIPTION: 1.206 +** PR_CancelWaitFileDesc is provided as a means for cancelling operations 1.207 +** on objects previously submitted by use of PR_AddWaitFileDesc(). If 1.208 +** the runtime knows of the object, it will be marked as having failed 1.209 +** because it was interrupted (similar to PR_Interrupt()). The first 1.210 +** available thread waiting on the group will be made to return the 1.211 +** PRRecvWait object with the outcome noted. 1.212 +** 1.213 +** INPUTS 1.214 +** group The wait group under which the wait receive object was 1.215 +** added. 1.216 +** desc A pointer to the wait receive object that is to be 1.217 +** cancelled. 1.218 +** RETURN 1.219 +** PRStatus If the wait receive object was located and associated 1.220 +** with the specified wait group, the status returned will 1.221 +** be PR_SUCCESS. There is still a race condition that would 1.222 +** permit the offected object to complete normally, but it 1.223 +** is assured that it will complete in the near future. 1.224 +** If the receive object or wait group are invalid, the 1.225 +** function will return with a status of PR_FAILURE. 1.226 +** 1.227 +** ERRORS 1.228 +** PR_INVALID_ARGUMENT_ERROR 1.229 +** The 'group' argument is not recognized as a valid group. 1.230 +** PR_COLLECTION_EMPTY_ERROR 1.231 +** There are no more receive wait objects in the group's 1.232 +** collection. 1.233 +** PR_INVALID_STATE_ERROR 1.234 +** The group is being destroyed. 1.235 +*/ 1.236 +NSPR_API(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc); 1.237 + 1.238 +/* 1.239 +** FUNCTION: PR_CancelWaitGroup 1.240 +** DESCRIPTION: 1.241 +** PR_CancelWaitGroup is provided as a means for cancelling operations 1.242 +** on objects previously submitted by use of PR_AddWaitFileDesc(). Each 1.243 +** successive call will return a pointer to a PRRecvWait object that 1.244 +** was previously registered via PR_AddWaitFileDesc(). If no wait 1.245 +** objects are associated with the wait group, a NULL will be returned. 1.246 +** This function should be called in a loop until a NULL is returned 1.247 +** to reclaim all the wait objects prior to calling PR_DestroyWaitGroup(). 1.248 +** 1.249 +** INPUTS 1.250 +** group The wait group under which the wait receive object was 1.251 +** added. 1.252 +** RETURN 1.253 +** PRRecvWait* If the wait group is valid and at least one receive wait 1.254 +** object is present in the group, that object will be 1.255 +** marked as PR_MW_INTERRUPT'd and removed from the group's 1.256 +** queues. Otherwise a NULL will be returned and the reason 1.257 +** for the NULL may be retrieved by calling PR_GetError(). 1.258 +** 1.259 +** ERRORS 1.260 +** PR_INVALID_ARGUMENT_ERROR 1.261 +** PR_GROUP_EMPTY_ERROR 1.262 +*/ 1.263 +NSPR_API(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group); 1.264 + 1.265 +/* 1.266 +** FUNCTION: PR_CreateWaitGroup 1.267 +** DESCRIPTION: 1.268 +** A wait group is an opaque object that a client may create in order 1.269 +** to semantically group various wait requests. Each wait group is 1.270 +** unique, including the default wait group (NULL). A wait request 1.271 +** that was added under a wait group will only be serviced by a caller 1.272 +** that specified the same wait group. 1.273 +** 1.274 +** INPUT 1.275 +** size The size of the hash table to be used to contain the 1.276 +** receive wait objects. This is just the initial size. 1.277 +** It will grow as it needs to, but to avoid that hassle 1.278 +** one can suggest a suitable size initially. It should 1.279 +** be ~30% larger than the maximum number of receive wait 1.280 +** objects expected. 1.281 +** RETURN 1.282 +** PRWaitGroup If successful, the function will return a pointer to an 1.283 +** object that was allocated by and owned by the runtime. 1.284 +** The reference remains valid until it is explicitly destroyed 1.285 +** by calling PR_DestroyWaitGroup(). 1.286 +** 1.287 +** ERRORS 1.288 +** PR_OUT_OF_MEMORY_ERROR 1.289 +*/ 1.290 +NSPR_API(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size); 1.291 + 1.292 +/* 1.293 +** FUNCTION: PR_DestroyWaitGroup 1.294 +** DESCRIPTION: 1.295 +** Undo the effects of PR_CreateWaitGroup(). Any receive wait operations 1.296 +** on the group will be treated as if the each had been the target of a 1.297 +** PR_CancelWaitFileDesc(). 1.298 +** 1.299 +** INPUT 1.300 +** group Reference to a wait group previously allocated using 1.301 +** PR_CreateWaitGroup(). 1.302 +** RETURN 1.303 +** PRStatus Will be PR_SUCCESS if the wait group was valid and there 1.304 +** are no receive wait objects in that group. Otherwise 1.305 +** will indicate PR_FAILURE. 1.306 +** 1.307 +** ERRORS 1.308 +** PR_INVALID_ARGUMENT_ERROR 1.309 +** The 'group' argument does not reference a known object. 1.310 +** PR_INVALID_STATE_ERROR 1.311 +** The group still contains receive wait objects. 1.312 +*/ 1.313 +NSPR_API(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group); 1.314 + 1.315 +/* 1.316 +** FUNCTION: PR_CreateMWaitEnumerator 1.317 +** DESCRIPTION: 1.318 +** The PR_CreateMWaitEnumerator() function returns a reference to an 1.319 +** opaque PRMWaitEnumerator object. The enumerator object is required 1.320 +** as an argument for each successive call in the stateless enumeration 1.321 +** of the indicated wait group. 1.322 +** 1.323 +** group The wait group that the enumeration is intended to 1.324 +** process. It may be be the default wait group (NULL). 1.325 +** RETURN 1.326 +** PRMWaitEnumerator* group 1.327 +** A reference to an object that will be used to store 1.328 +** intermediate state of enumerations. 1.329 +** ERRORS 1.330 +** Errors are indicated by the function returning a NULL. 1.331 +** PR_INVALID_ARGUMENT_ERROR 1.332 +** The 'group' argument does not reference a known object. 1.333 +** PR_OUT_OF_MEMORY_ERROR 1.334 +*/ 1.335 +NSPR_API(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group); 1.336 + 1.337 +/* 1.338 +** FUNCTION: PR_DestroyMWaitEnumerator 1.339 +** DESCRIPTION: 1.340 +** Destroys the object created by PR_CreateMWaitEnumerator(). The reference 1.341 +** used as an argument becomes invalid. 1.342 +** 1.343 +** INPUT 1.344 +** PRMWaitEnumerator* enumerator 1.345 +** The PRMWaitEnumerator object to destroy. 1.346 +** RETURN 1.347 +** PRStatus 1.348 +** PR_SUCCESS if successful, PR_FAILURE otherwise. 1.349 +** ERRORS 1.350 +** PR_INVALID_ARGUMENT_ERROR 1.351 +** The enumerator is invalid. 1.352 +*/ 1.353 +NSPR_API(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator); 1.354 + 1.355 +/* 1.356 +** FUNCTION: PR_EnumerateWaitGroup 1.357 +** DESCRIPTION: 1.358 +** PR_EnumerateWaitGroup is a thread safe enumerator over a wait group. 1.359 +** Each call to the enumerator must present a valid PRMWaitEnumerator 1.360 +** rererence and a pointer to the "previous" element returned from the 1.361 +** enumeration process or a NULL. 1.362 +** 1.363 +** An enumeration is started by passing a NULL as the "previous" value. 1.364 +** Subsequent calls to the enumerator must pass in the result of the 1.365 +** previous call. The enumeration end is signaled by the runtime returning 1.366 +** a NULL as the result. 1.367 +** 1.368 +** Modifications to the content of the wait group are allowed during 1.369 +** an enumeration. The effect is that the enumeration may have to be 1.370 +** "reset" and that may result in duplicates being returned from the 1.371 +** enumeration. 1.372 +** 1.373 +** An enumeration may be abandoned at any time. The runtime is not 1.374 +** keeping any state, so there are no issues in that regard. 1.375 +*/ 1.376 +NSPR_API(PRRecvWait*) PR_EnumerateWaitGroup( 1.377 + PRMWaitEnumerator *enumerator, const PRRecvWait *previous); 1.378 + 1.379 +PR_END_EXTERN_C 1.380 + 1.381 +#endif /* defined(_PRMWAIT_H) */ 1.382 + 1.383 +/* prmwait.h */