prmwait.h 16 KB

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