home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / nspr30-e.zip / nspr30-e / include / prthread.h < prev    next >
C/C++ Source or Header  |  1998-11-02  |  10KB  |  255 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #ifndef prthread_h___
  20. #define prthread_h___
  21.  
  22. /*
  23. ** API for NSPR threads. On some architectures (MAC and WIN16
  24. ** notably) pre-emptibility is not guaranteed. Hard priority scheduling
  25. ** is not guaranteed, so programming using priority based synchronization
  26. ** is a no-no.
  27. **
  28. ** NSPR threads are scheduled based loosly on their client set priority.
  29. ** In general, a thread of a higher priority has a statistically better
  30. ** chance of running relative to threads of lower priority. However,
  31. ** NSPR uses multiple strategies to provide execution vehicles for thread
  32. ** abstraction of various host platforms. As it turns out, there is little
  33. ** NSPR can do to affect the scheduling attributes of "GLOBAL" threads.
  34. ** However, a semblance of GLOBAL threads is used to implement "LOCAL"
  35. ** threads. An arbitrary number of such LOCAL threads can be assigned to
  36. ** a single GLOBAL thread.
  37. **
  38. ** For scheduling, NSPR will attempt to run the highest priority LOCAL
  39. ** thread associated with a given GLOBAL thread. It is further assumed
  40. ** that the host OS will apply some form of "fair" scheduling on the
  41. ** GLOBAL threads.
  42. **
  43. ** Threads have a "system flag" which when set indicates the thread
  44. ** doesn't count for determining when the process should exit (the
  45. ** process exits when the last user thread exits).
  46. **
  47. ** Threads also have a "scope flag" which controls whether the threads
  48. ** are scheduled in the local scope or scheduled by the OS globally. This 
  49. ** indicates whether a thread is permanently bound to a native OS thread. 
  50. ** An unbound thread competes for scheduling resources in the same process.
  51. **
  52. ** Another flag is "state flag" which control whether the thread is joinable.
  53. ** It allows other threads to wait for the created thread to reach completion.
  54. **
  55. ** Threads can have "per-thread-data" attached to them. Each thread has a
  56. ** per-thread error number and error string which are updated when NSPR
  57. ** operations fail.
  58. */
  59. #include "prtypes.h"
  60. #include "prinrval.h"
  61.  
  62. PR_BEGIN_EXTERN_C
  63.  
  64. typedef struct PRThread PRThread;
  65. typedef struct PRThreadStack PRThreadStack;
  66.  
  67. typedef enum PRThreadType {
  68.     PR_USER_THREAD,
  69.     PR_SYSTEM_THREAD
  70. } PRThreadType;
  71.  
  72. typedef enum PRThreadScope {
  73.     PR_LOCAL_THREAD,
  74.     PR_GLOBAL_THREAD
  75. } PRThreadScope;
  76.  
  77. typedef enum PRThreadState {
  78.     PR_JOINABLE_THREAD,
  79.     PR_UNJOINABLE_THREAD
  80. } PRThreadState;
  81.  
  82. typedef enum PRThreadPriority
  83. {
  84.     PR_PRIORITY_FIRST = 0,      /* just a placeholder */
  85.     PR_PRIORITY_LOW = 0,        /* the lowest possible priority */
  86.     PR_PRIORITY_NORMAL = 1,     /* most common expected priority */
  87.     PR_PRIORITY_HIGH = 2,       /* slightly more aggressive scheduling */
  88.     PR_PRIORITY_URGENT = 3,     /* it does little good to have more than one */
  89.     PR_PRIORITY_LAST = 3        /* this is just a placeholder */
  90. } PRThreadPriority;
  91.  
  92. /*
  93. ** Create a new thread:
  94. **     "type" is the type of thread to create
  95. **     "start(arg)" will be invoked as the threads "main"
  96. **     "priority" will be created thread's priority
  97. **     "scope" will specify whether the thread is local or global
  98. **     "state" will specify whether the thread is joinable or not
  99. **     "stackSize" the size of the stack, in bytes. The value can be zero
  100. **        and then a machine specific stack size will be chosen.
  101. **
  102. ** This can return NULL if some kind of error occurs, such as if memory is
  103. ** tight.
  104. **
  105. ** If you want the thread to start up waiting for the creator to do
  106. ** something, enter a lock before creating the thread and then have the
  107. ** threads start routine enter and exit the same lock. When you are ready
  108. ** for the thread to run, exit the lock.
  109. **
  110. ** If you want to detect the completion of the created thread, the thread
  111. ** should be created joinable.  Then, use PR_JoinThread to synchrnoize the
  112. ** termination of another thread.
  113. **
  114. ** When the start function returns the thread exits. If it is the last
  115. ** PR_USER_THREAD to exit then the process exits.
  116. */
  117. PR_EXTERN(PRThread*) PR_CreateThread(PRThreadType type,
  118.                      void (*start)(void *arg),
  119.                      void *arg,
  120.                      PRThreadPriority priority,
  121.                      PRThreadScope scope,
  122.                      PRThreadState state,
  123.                      PRUint32 stackSize);
  124.  
  125. /*
  126. ** Wait for thread termination:
  127. **     "thread" is the target thread 
  128. **
  129. ** This can return PR_FAILURE if no joinable thread could be found 
  130. ** corresponding to the specified target thread.
  131. **
  132. ** The calling thread is blocked until the target thread completes.
  133. ** Several threads cannot wait for the same thread to complete; one thread
  134. ** will operate successfully and others will terminate with an error PR_FAILURE.
  135. ** The calling thread will not be blocked if the target thread has already
  136. ** terminated.
  137. */
  138. PR_EXTERN(PRStatus) PR_JoinThread(PRThread *thread);
  139.  
  140. /*
  141. ** Return the current thread object for the currently running code.
  142. ** Never returns NULL.
  143. */
  144. PR_EXTERN(PRThread*) PR_GetCurrentThread(void);
  145. #define PR_CurrentThread() PR_GetCurrentThread() /* for nspr1.0 compat. */
  146.  
  147. /*
  148. ** Get the priority of "thread".
  149. */
  150. PR_EXTERN(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread);
  151.  
  152. /*
  153. ** Change the priority of the "thread" to "priority".
  154. */
  155. PR_EXTERN(void) PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority);
  156.  
  157. /*
  158. ** This routine returns a new index for per-thread-private data table. 
  159. ** The index is visible to all threads within a process. This index can 
  160. ** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines 
  161. ** to save and retrieve data associated with the index for a thread.
  162. **
  163. ** Each index is associationed with a destructor function ('dtor'). The function
  164. ** may be specified as NULL when the index is created. If it is not NULL, the
  165. ** function will be called when:
  166. **      - the thread exits and the private data for the associated index
  167. **        is not NULL,
  168. **      - new thread private data is set and the current private data is
  169. **        not NULL.
  170. **
  171. ** The index independently maintains specific values for each binding thread. 
  172. ** A thread can only get access to its own thread-specific-data.
  173. **
  174. ** Upon a new index return the value associated with the index for all threads
  175. ** is NULL, and upon thread creation the value associated with all indices for 
  176. ** that thread is NULL. 
  177. **
  178. ** Returns PR_FAILURE if the total number of indices will exceed the maximun 
  179. ** allowed.
  180. */
  181. typedef void (PR_CALLBACK *PRThreadPrivateDTOR)(void *priv);
  182.  
  183. PR_EXTERN(PRStatus) PR_NewThreadPrivateIndex(
  184.     PRUintn *newIndex, PRThreadPrivateDTOR destructor);
  185.  
  186. /*
  187. ** Define some per-thread-private data.
  188. **     "tpdIndex" is an index into the per-thread private data table
  189. **     "priv" is the per-thread-private data 
  190. **
  191. ** If the per-thread private data table has a previously registered
  192. ** destructor function and a non-NULL per-thread-private data value,
  193. ** the destructor function is invoked.
  194. **
  195. ** This can return PR_FAILURE if the index is invalid.
  196. */
  197. PR_EXTERN(PRStatus) PR_SetThreadPrivate(PRUintn tpdIndex, void *priv);
  198.  
  199. /*
  200. ** Recover the per-thread-private data for the current thread. "tpdIndex" is
  201. ** the index into the per-thread private data table. 
  202. **
  203. ** The returned value may be NULL which is indistinguishable from an error 
  204. ** condition.
  205. **
  206. ** A thread can only get access to its own thread-specific-data.
  207. */
  208. PR_EXTERN(void*) PR_GetThreadPrivate(PRUintn tpdIndex);
  209.  
  210. /*
  211. ** This routine sets the interrupt request for a target thread. The interrupt
  212. ** request remains in the thread's state until it is delivered exactly once
  213. ** or explicitly canceled.
  214. **
  215. ** A thread that has been interrupted will fail all NSPR blocking operations
  216. ** that return a PRStatus (I/O, waiting on a condition, etc).
  217. **
  218. ** PR_Interrupt may itself fail if the target thread is invalid.
  219. */
  220. PR_EXTERN(PRStatus) PR_Interrupt(PRThread *thread);
  221.  
  222. /*
  223. ** Clear the interrupt request for the calling thread. If no such request
  224. ** is pending, this operation is a noop.
  225. */
  226. PR_EXTERN(void) PR_ClearInterrupt(void);
  227.  
  228. /*
  229. ** Make the current thread sleep until "ticks" time amount of time
  230. ** has expired. If "ticks" is PR_INTERVAL_NO_WAIT then the call is
  231. ** equivalent to calling PR_Yield. Calling PR_Sleep with an argument
  232. ** equivalent to PR_INTERVAL_NO_TIMEOUT is an error and will result
  233. ** in a PR_FAILURE error return.
  234. */
  235. PR_EXTERN(PRStatus) PR_Sleep(PRIntervalTime ticks);
  236.  
  237. /*
  238. ** Get the scoping of this thread.
  239. */
  240. PR_EXTERN(PRThreadScope) PR_GetThreadScope(const PRThread *thread);
  241.  
  242. /*
  243. ** Get the type of this thread.
  244. */
  245. PR_EXTERN(PRThreadType) PR_GetThreadType(const PRThread *thread);
  246.  
  247. /*
  248. ** Get the join state of this thread.
  249. */
  250. PR_EXTERN(PRThreadState) PR_GetThreadState(const PRThread *thread);
  251.  
  252. PR_END_EXTERN_C
  253.  
  254. #endif /* prthread_h___ */
  255.