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