00001 // -*- C++ -*- 00002 00003 //========================================================================== 00004 /** 00005 * @file Thread.h 00006 * 00007 * $Id: Thread.h 80826 2008-03-04 14:51:23Z wotte $ 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 @a flags attributes and running @a func 00056 * with <args> (if <thread_adapter> is non-0 then @a 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 @a priority priority (see 00060 * below). 00061 * 00062 * The @a 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 @a 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 = ACE_DEFAULT_THREAD_STACKSIZE, 00092 ACE_Thread_Adapter *thread_adapter = 0, 00093 const char** thr_name = 0); 00094 00095 /** 00096 * Spawn N new threads, which execute @a func with argument @a arg (if 00097 * @a thread_adapter is non-0 then @a func and @a args are ignored and 00098 * are obtained from @a thread_adapter). If @a stack != 0 it is 00099 * assumed to be an array of @a n pointers to the base of the stacks 00100 * to use for the threads being spawned. Likewise, if @a stack_size 00101 * != 0 it is assumed to be an array of @a n values indicating how 00102 * big each of the corresponding @a stacks are. Returns the number 00103 * of threads actually spawned (if this doesn't equal the number 00104 * requested then something has gone wrong and @c errno will 00105 * explain...). 00106 * 00107 * @see spawn() 00108 */ 00109 static size_t spawn_n (size_t n, 00110 ACE_THR_FUNC func, 00111 void *arg = 0, 00112 long flags = THR_NEW_LWP | THR_JOINABLE, 00113 long priority = ACE_DEFAULT_THREAD_PRIORITY, 00114 void *stack[] = 0, 00115 size_t stack_size[] = 0, 00116 ACE_Thread_Adapter *thread_adapter = 0, 00117 const char* thr_name[] = 0); 00118 00119 /** 00120 * Spawn @a n new threads, which execute @a func with argument @a arg 00121 * (if @a thread_adapter is non-0 then @a func and @a args are ignored 00122 * and are obtained from @a thread_adapter). The thread_ids of 00123 * successfully spawned threads will be placed into the <thread_ids> 00124 * buffer (which must be the same size as @a n). If @a stack != 0 it 00125 * is assumed to be an array of @a n pointers to the base of the 00126 * stacks to use for the threads being spawned. If @a stack_size != 00127 * 0 it is assumed to be an array of @a n values indicating how big 00128 * each of the corresponding @a stacks are. If @a thread_handles != 0 00129 * it is assumed to be an array of @a n thread_handles that will be 00130 * assigned the values of the thread handles being spawned. Returns 00131 * the number of threads actually spawned (if this doesn't equal the 00132 * number requested then something has gone wrong and @c errno will 00133 * explain...). 00134 * 00135 * @see spawn() 00136 */ 00137 static size_t spawn_n (ACE_thread_t thread_ids[], 00138 size_t n, 00139 ACE_THR_FUNC func, 00140 void *arg, 00141 long flags, 00142 long priority = ACE_DEFAULT_THREAD_PRIORITY, 00143 void *stack[] = 0, 00144 size_t stack_size[] = 0, 00145 ACE_hthread_t thread_handles[] = 0, 00146 ACE_Thread_Adapter *thread_adapter = 0, 00147 const char* thr_name[] = 0); 00148 00149 /** 00150 * Wait for one or more threads to exit and reap their exit status. 00151 * thr_join() returns successfully when the target thread terminates. 00152 * 00153 * @param thread_id is the ACE_thread_t ID of the thread to wait for. 00154 * If @a thread_id is 0, join() waits for any 00155 * undetached thread in the process to terminate 00156 * on platforms that support this capability 00157 * (for example, Solaris). 00158 * @param departed points to a location that is set to the ID of the 00159 * terminated thread if join() returns successfully. 00160 * If @a departed is 0, it is ignored. 00161 * @param status Points to the location that receives the joined 00162 * thread's exit value. If @a status is 0, it is ignored. 00163 * 00164 * @retval 0 for success 00165 * @retval -1 (with errno set) for failure. 00166 */ 00167 static int join (ACE_thread_t thread_id, 00168 ACE_thread_t *departed, 00169 ACE_THR_FUNC_RETURN *status); 00170 00171 /// Wait for one thread to exit and reap its exit status. 00172 static int join (ACE_hthread_t, 00173 ACE_THR_FUNC_RETURN * = 0); 00174 00175 /// Continue the execution of a previously suspended thread. 00176 static int resume (ACE_hthread_t); 00177 00178 /// Suspend the execution of a particular thread. 00179 static int suspend (ACE_hthread_t); 00180 00181 /// Get the priority of a particular thread. 00182 static int getprio (ACE_hthread_t ht_id, int &priority); 00183 00184 /// Get the priority and policy of a particular thread. 00185 static int getprio (ACE_hthread_t ht_id, int &priority, int &policy); 00186 00187 /// Set the priority of a particular thread. 00188 static int setprio (ACE_hthread_t ht_id, int priority, int policy = -1); 00189 00190 /// Send a signal to the thread. 00191 static int kill (ACE_thread_t, int signum); 00192 00193 /// Yield the thread to another. 00194 static void yield (void); 00195 00196 /** 00197 * Return the unique kernel handle of the thread. Note that on 00198 * Win32 this is actually a pseudohandle, which cannot be shared 00199 * with other processes or waited on by threads. To locate the real 00200 * handle, please use the ACE_Thread_Manager::thr_self() method. 00201 */ 00202 static void self (ACE_hthread_t &t_handle); 00203 00204 /// Return the unique ID of the thread. 00205 static ACE_thread_t self (void); 00206 00207 /// Exit the current thread and return "status". 00208 /// Should _not_ be called by main thread. 00209 static void exit (ACE_THR_FUNC_RETURN status = 0); 00210 00211 /// Get the LWP concurrency level of the process. 00212 static int getconcurrency (void); 00213 00214 /// Set the LWP concurrency level of the process. 00215 static int setconcurrency (int new_level); 00216 00217 /// Change and/or examine calling thread's signal mask. 00218 static int sigsetmask (int how, 00219 const sigset_t *sigset, 00220 sigset_t *osigset = 0); 00221 00222 /** 00223 * Allocates a @a keyp that is used to identify data that is specific 00224 * to each thread in the process. The key is global to all threads 00225 * in the process. 00226 */ 00227 static int keycreate (ACE_thread_key_t *keyp, 00228 #if defined (ACE_HAS_THR_C_DEST) 00229 ACE_THR_C_DEST destructor, 00230 #else 00231 ACE_THR_DEST destructor, 00232 #endif /* ACE_HAS_THR_C_DEST */ 00233 void * = 0); 00234 00235 /// Free up the key so that other threads can reuse it. 00236 static int keyfree (ACE_thread_key_t key); 00237 00238 /// Bind value to the thread-specific data key, @a key, for the calling 00239 /// thread. 00240 static int setspecific (ACE_thread_key_t key, 00241 void *value); 00242 00243 /// Stores the current value bound to @a key for the calling thread 00244 /// into the location pointed to by @a valuep. 00245 static int getspecific (ACE_thread_key_t key, 00246 void **valuep); 00247 00248 /// Disable thread cancellation. 00249 static int disablecancel (struct cancel_state *old_state); 00250 00251 /// Enable thread cancellation. 00252 static int enablecancel (struct cancel_state *old_state, 00253 int flag); 00254 00255 /// Set the cancellation state. 00256 static int setcancelstate (struct cancel_state &new_state, 00257 struct cancel_state *old_state); 00258 00259 /** 00260 * Cancel a thread. 00261 * @note This method is only portable on platforms, such as POSIX pthreads, 00262 * that support thread cancellation. 00263 */ 00264 static int cancel (ACE_thread_t t_id); 00265 00266 /// Test the cancel. 00267 static void testcancel (void); 00268 00269 private: 00270 /// Ensure that we don't get instantiated. 00271 ACE_Thread (void); 00272 }; 00273 00274 ACE_END_VERSIONED_NAMESPACE_DECL 00275 00276 #if defined (__ACE_INLINE__) 00277 #include "ace/Thread.inl" 00278 #endif /* __ACE_INLINE__ */ 00279 00280 #include /**/ "ace/post.h" 00281 00282 #endif /* ACE_THREAD_H */