00001 // -*- C++ -*- 00002 00003 //========================================================================== 00004 /** 00005 * @file Thread.h 00006 * 00007 * Thread.h,v 4.44 2005/10/28 23:55:10 ossama Exp 00008 * 00009 * @author Douglas Schmidt <schmidt@cs.wustl.edu> 00010 */ 00011 //========================================================================== 00012 00013 #ifndef ACE_THREAD_H 00014 #define ACE_THREAD_H 00015 00016 #include /**/ "ace/pre.h" 00017 00018 #include "ace/ACE_export.h" 00019 00020 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00021 # pragma once 00022 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00023 00024 #include "ace/OS_NS_Thread.h" 00025 #include "ace/Thread_Adapter.h" 00026 00027 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00028 00029 struct cancel_state 00030 { 00031 /// e.g., PTHREAD_CANCEL_ENABLE, PTHREAD_CANCEL_DISABLE, 00032 /// PTHREAD_CANCELED. 00033 int cancelstate; 00034 00035 /// e.g., PTHREAD_CANCEL_DEFERRED and PTHREAD_CANCEL_ASYNCHRONOUS. 00036 int canceltype; 00037 }; 00038 00039 /** 00040 * @class ACE_Thread 00041 * 00042 * @brief Provides a wrapper for threads. 00043 * 00044 * This class provides a common interface that is mapped onto 00045 * POSIX Pthreads, Solaris threads, Win32 threads, VxWorks 00046 * threads, or pSoS threads. Note, however, that it is 00047 * generally a better idea to use the <ACE_Thread_Manager> 00048 * programming API rather than the <ACE_Thread> API since the 00049 * thread manager is more powerful. 00050 */ 00051 class ACE_Export ACE_Thread 00052 { 00053 public: 00054 /** 00055 * Creates a new thread having <flags> attributes and running <func> 00056 * with <args> (if <thread_adapter> is non-0 then <func> and <args> 00057 * are ignored and are obtained from <thread_adapter>). <thr_id> 00058 * and <t_handle> are set to the thread's ID and handle (?), 00059 * respectively. The thread runs at <priority> priority (see 00060 * below). 00061 * 00062 * The <flags> are a bitwise-OR of the following: 00063 * = BEGIN<INDENT> 00064 * THR_CANCEL_DISABLE, THR_CANCEL_ENABLE, THR_CANCEL_DEFERRED, 00065 * THR_CANCEL_ASYNCHRONOUS, THR_BOUND, THR_NEW_LWP, THR_DETACHED, 00066 * THR_SUSPENDED, THR_DAEMON, THR_JOINABLE, THR_SCHED_FIFO, 00067 * THR_SCHED_RR, THR_SCHED_DEFAULT, THR_EXPLICIT_SCHED, 00068 * THR_SCOPE_SYSTEM, THR_SCOPE_PROCESS 00069 * = END<INDENT> 00070 * 00071 * By default, or if <priority> is set to 00072 * ACE_DEFAULT_THREAD_PRIORITY, an "appropriate" priority value for 00073 * the given scheduling policy (specified in <flags}>, e.g., 00074 * <THR_SCHED_DEFAULT>) is used. This value is calculated 00075 * dynamically, and is the median value between the minimum and 00076 * maximum priority values for the given policy. If an explicit 00077 * value is given, it is used. Note that actual priority values are 00078 * EXTREMEMLY implementation-dependent, and are probably best 00079 * avoided. 00080 * 00081 * Note that <thread_adapter> is always deleted when <spawn> 00082 * is called, so it must be allocated with global operator new. 00083 */ 00084 static int spawn (ACE_THR_FUNC func, 00085 void *arg = 0, 00086 long flags = THR_NEW_LWP | THR_JOINABLE, 00087 ACE_thread_t *t_id = 0, 00088 ACE_hthread_t *t_handle = 0, 00089 long priority = ACE_DEFAULT_THREAD_PRIORITY, 00090 void *stack = 0, 00091 size_t stack_size = 0, 00092 ACE_Thread_Adapter *thread_adapter = 0); 00093 00094 /** 00095 * Spawn N new threads, which execute <func> with argument <arg> (if 00096 * <thread_adapter> is non-0 then <func> and <args> are ignored and 00097 * are obtained from <thread_adapter>). If <stack> != 0 it is 00098 * assumed to be an array of <n> pointers to the base of the stacks 00099 * to use for the threads being spawned. Likewise, if <stack_size> 00100 * != 0 it is assumed to be an array of <n> values indicating how 00101 * big each of the corresponding <stack>s are. Returns the number 00102 * of threads actually spawned (if this doesn't equal the number 00103 * requested then something has gone wrong and <errno> will 00104 * explain...). 00105 * 00106 * @see spawn() 00107 */ 00108 static size_t spawn_n (size_t n, 00109 ACE_THR_FUNC func, 00110 void *arg = 0, 00111 long flags = THR_NEW_LWP | THR_JOINABLE, 00112 long priority = ACE_DEFAULT_THREAD_PRIORITY, 00113 void *stack[] = 0, 00114 size_t stack_size[] = 0, 00115 ACE_Thread_Adapter *thread_adapter = 0); 00116 00117 /** 00118 * Spawn <n> new threads, which execute <func> with argument <arg> 00119 * (if <thread_adapter> is non-0 then <func> and <args> are ignored 00120 * and are obtained from <thread_adapter>). The thread_ids of 00121 * successfully spawned threads will be placed into the <thread_ids> 00122 * buffer (which must be the same size as <n>). If <stack> != 0 it 00123 * is assumed to be an array of <n> pointers to the base of the 00124 * stacks to use for the threads being spawned. If <stack_size> != 00125 * 0 it is assumed to be an array of <n> values indicating how big 00126 * each of the corresponding <stack>s are. If <thread_handles> != 0 00127 * it is assumed to be an array of <n> thread_handles that will be 00128 * assigned the values of the thread handles being spawned. Returns 00129 * the number of threads actually spawned (if this doesn't equal the 00130 * number requested then something has gone wrong and <errno> will 00131 * explain...). 00132 * 00133 * @see spawn() 00134 */ 00135 static size_t spawn_n (ACE_thread_t thread_ids[], 00136 size_t n, 00137 ACE_THR_FUNC func, 00138 void *arg, 00139 long flags, 00140 long priority = ACE_DEFAULT_THREAD_PRIORITY, 00141 void *stack[] = 0, 00142 size_t stack_size[] = 0, 00143 ACE_hthread_t thread_handles[] = 0, 00144 ACE_Thread_Adapter *thread_adapter = 0); 00145 00146 /** 00147 * Wait for one or more threads to exit and reap their exit status. 00148 * thr_join() returns successfully when the target thread terminates. 00149 * 00150 * @param thread_id is the ACE_thread_t ID of the thread to wait for. 00151 * If @a thread_id is 0, join() waits for any 00152 * undetached thread in the process to terminate 00153 * on platforms that support this capability 00154 * (for example, Solaris). 00155 * @param departed points to a location that is set to the ID of the 00156 * terminated thread if join() returns successfully. 00157 * If @a departed is 0, it is ignored. 00158 * @param status Points to the location that receives the joined 00159 * thread's exit value. If @a status is 0, it is ignored. 00160 * 00161 * @retval 0 for success; -1 (with errno set) for failure. 00162 */ 00163 static int join (ACE_thread_t thread_id, 00164 ACE_thread_t *departed, 00165 ACE_THR_FUNC_RETURN *status); 00166 00167 /// Wait for one thread to exit and reap its exit status. 00168 static int join (ACE_hthread_t, 00169 ACE_THR_FUNC_RETURN * = 0); 00170 00171 /// Continue the execution of a previously suspended thread. 00172 static int resume (ACE_hthread_t); 00173 00174 /// Suspend the execution of a particular thread. 00175 static int suspend (ACE_hthread_t); 00176 00177 /// Get the priority of a particular thread. 00178 static int getprio (ACE_hthread_t ht_id, int &priority); 00179 00180 /// Get the priority and policy of a particular thread. 00181 static int getprio (ACE_hthread_t ht_id, int &priority, int &policy); 00182 00183 /// Set the priority of a particular thread. 00184 static int setprio (ACE_hthread_t ht_id, int priority, int policy = -1); 00185 00186 /// Send a signal to the thread. 00187 static int kill (ACE_thread_t, int signum); 00188 00189 /// Yield the thread to another. 00190 static void yield (void); 00191 00192 /** 00193 * Return the unique kernel handle of the thread. Note that on 00194 * Win32 this is actually a pseudohandle, which cannot be shared 00195 * with other processes or waited on by threads. To locate the real 00196 * handle, please use the ACE_Thread_Manager::thr_self() method. 00197 */ 00198 static void self (ACE_hthread_t &t_handle); 00199 00200 /// Return the unique ID of the thread. 00201 static ACE_thread_t self (void); 00202 00203 /// Exit the current thread and return "status". 00204 /// Should _not_ be called by main thread. 00205 static void exit (ACE_THR_FUNC_RETURN status = 0); 00206 00207 /// Get the LWP concurrency level of the process. 00208 static int getconcurrency (void); 00209 00210 /// Set the LWP concurrency level of the process. 00211 static int setconcurrency (int new_level); 00212 00213 /// Change and/or examine calling thread's signal mask. 00214 static int sigsetmask (int how, 00215 const sigset_t *sigset, 00216 sigset_t *osigset = 0); 00217 00218 /** 00219 * Allocates a <keyp> that is used to identify data that is specific 00220 * to each thread in the process. The key is global to all threads 00221 * in the process. 00222 */ 00223 static int keycreate (ACE_thread_key_t *keyp, 00224 #if defined (ACE_HAS_THR_C_DEST) 00225 ACE_THR_C_DEST destructor, 00226 #else 00227 ACE_THR_DEST destructor, 00228 #endif /* ACE_HAS_THR_C_DEST */ 00229 void * = 0); 00230 00231 /// Free up the key so that other threads can reuse it. 00232 static int keyfree (ACE_thread_key_t key); 00233 00234 /// Bind value to the thread-specific data key, <key>, for the calling 00235 /// thread. 00236 static int setspecific (ACE_thread_key_t key, 00237 void *value); 00238 00239 /// Stores the current value bound to <key> for the calling thread 00240 /// into the location pointed to by <valuep>. 00241 static int getspecific (ACE_thread_key_t key, 00242 void **valuep); 00243 00244 /// Disable thread cancellation. 00245 static int disablecancel (struct cancel_state *old_state); 00246 00247 /// Enable thread cancellation. 00248 static int enablecancel (struct cancel_state *old_state, 00249 int flag); 00250 00251 /// Set the cancellation state. 00252 static int setcancelstate (struct cancel_state &new_state, 00253 struct cancel_state *old_state); 00254 00255 /** 00256 * Cancel a thread. Note that this method is only portable on 00257 * platforms, such as POSIX pthreads, that support thread 00258 * cancellation. 00259 */ 00260 static int cancel (ACE_thread_t t_id); 00261 00262 /// Test the cancel. 00263 static void testcancel (void); 00264 00265 private: 00266 /// Ensure that we don't get instantiated. 00267 ACE_Thread (void); 00268 }; 00269 00270 ACE_END_VERSIONED_NAMESPACE_DECL 00271 00272 #if defined (__ACE_INLINE__) 00273 #include "ace/Thread.inl" 00274 #endif /* __ACE_INLINE__ */ 00275 00276 #include /**/ "ace/post.h" 00277 00278 #endif /* ACE_THREAD_H */