OS_NS_Thread.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file   OS_NS_Thread.h
00006  *
00007  *  OS_NS_Thread.h,v 1.61 2006/05/30 13:15:25 schmidt Exp
00008  *
00009  *  @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
00010  *  @author Jesper S. M|ller<stophph@diku.dk>
00011  *  @author and a cast of thousands...
00012  *
00013  *  Originally in OS.h.
00014  */
00015 //=============================================================================
00016 
00017 #ifndef ACE_OS_NS_THREAD_H
00018 # define ACE_OS_NS_THREAD_H
00019 
00020 # include /**/ "ace/pre.h"
00021 
00022 # include "ace/config-all.h"
00023 
00024 # if !defined (ACE_LACKS_PRAGMA_ONCE)
00025 #  pragma once
00026 # endif /* ACE_LACKS_PRAGMA_ONCE */
00027 
00028 # include "ace/Global_Macros.h"
00029 # include "ace/Basic_Types.h"
00030 # include "ace/Default_Constants.h"
00031 # include "ace/os_include/os_pthread.h"
00032 # include "ace/os_include/os_sched.h"
00033 # include "ace/Base_Thread_Adapter.h"
00034 # include "ace/os_include/sys/os_sem.h"
00035 # include "ace/os_include/os_semaphore.h"
00036 # include "ace/OS_Memory.h"
00037 # include "ace/OS_NS_signal.h"
00038 # include "ace/ACE_export.h"
00039 # include "ace/Object_Manager_Base.h"
00040 
00041 # if defined (ACE_EXPORT_MACRO)
00042 #   undef ACE_EXPORT_MACRO
00043 # endif
00044 # define ACE_EXPORT_MACRO ACE_Export
00045 
00046 # if defined (ACE_HAS_PRIOCNTL)
00047   // Need to #include thread.h before #defining THR_BOUND, etc.,
00048   // when building without threads on SunOS 5.x.
00049 #   if defined (sun)
00050 #     include /**/ <thread.h>
00051 #   endif /* sun */
00052 
00053   // Need to #include these before #defining USYNC_PROCESS on SunOS 5.x.
00054 #   include /**/ <sys/rtpriocntl.h>
00055 #   include /**/ <sys/tspriocntl.h>
00056 # endif /* ACE_HAS_PRIOCNTL */
00057 
00058 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00059 
00060 # if defined (ACE_WIN32)
00061 typedef DWORD ACE_thread_t;
00062 typedef HANDLE ACE_hthread_t;
00063 // Native TSS key type
00064 typedef DWORD ACE_OS_thread_key_t;
00065 // Application TSS key type (use this type except in TSS Emulation)
00066 #   if defined (ACE_HAS_TSS_EMULATION)
00067       typedef u_int ACE_thread_key_t;
00068 #   else  /* ! ACE_HAS_TSS_EMULATION */
00069       typedef ACE_OS_thread_key_t ACE_thread_key_t;
00070 #   endif /* ! ACE_HAS_TSS_EMULATION */
00071 # endif /* ACE_WIN32 */
00072 
00073 ACE_END_VERSIONED_NAMESPACE_DECL
00074 
00075 # if !defined (ACE_HAS_POSIX_SEM) && defined (ACE_USES_FIFO_SEM)
00076 
00077 extern "C" {
00078   typedef struct
00079   {
00080     char* name_;
00081     ACE_HANDLE fd_[2];
00082   } ACE_sema_t;
00083 }
00084 
00085 #endif /* !ACE_HAS_POSIX_SEM && ACE_USES_FIFO_SEM */
00086 
00087 # if defined (ACE_HAS_THREADS)
00088 
00089 #   if defined (ACE_HAS_STHREADS)
00090 #     include /**/ <synch.h>
00091 #     include /**/ <thread.h>
00092 #     define ACE_SCOPE_PROCESS P_PID
00093 #     define ACE_SCOPE_LWP P_LWPID
00094 #     define ACE_SCOPE_THREAD (ACE_SCOPE_LWP + 1)
00095 #   else
00096 #     define ACE_SCOPE_PROCESS 0
00097 #     define ACE_SCOPE_LWP 1
00098 #     define ACE_SCOPE_THREAD 2
00099 #   endif /* ACE_HAS_STHREADS */
00100 
00101 #   if !defined (ACE_HAS_PTHREADS)
00102 #     define ACE_SCHED_OTHER 0
00103 #     define ACE_SCHED_FIFO 1
00104 #     define ACE_SCHED_RR 2
00105 #   endif /* ! ACE_HAS_PTHREADS */
00106 
00107 #   if defined (ACE_HAS_PTHREADS)
00108 // moved to pthread.h
00109 #   elif defined (ACE_HAS_STHREADS)
00110 
00111 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00112 
00113 // Solaris threads, without PTHREADS.
00114 // Typedefs to help compatibility with Windows NT and Pthreads.
00115 typedef thread_t ACE_thread_t;
00116 // Native TSS key type (not for general use)
00117 typedef thread_key_t ACE_OS_thread_key_t;
00118 // Application TSS key type (use this type except in TSS Emulation)
00119 #   if defined (ACE_HAS_TSS_EMULATION)
00120       typedef u_int ACE_thread_key_t;
00121 #   else  /* ! ACE_HAS_TSS_EMULATION */
00122       typedef ACE_OS_thread_key_t ACE_thread_key_t;
00123 #   endif /* ! ACE_HAS_TSS_EMULATION */
00124 typedef mutex_t ACE_mutex_t;
00125 #     if !defined (ACE_LACKS_RWLOCK_T)
00126 typedef rwlock_t ACE_rwlock_t;
00127 #     endif /* !ACE_LACKS_RWLOCK_T */
00128 #     if !defined (ACE_HAS_POSIX_SEM) && !defined (ACE_USES_FIFO_SEM)
00129 typedef sema_t ACE_sema_t;
00130 #     endif /* !ACE_HAS_POSIX_SEM */
00131 
00132 typedef cond_t ACE_cond_t;
00133 struct ACE_Export ACE_condattr_t
00134 {
00135   int type;
00136 };
00137 struct ACE_Export ACE_mutexattr_t
00138 {
00139   int type;
00140 };
00141 typedef ACE_thread_t ACE_hthread_t;
00142 typedef ACE_mutex_t ACE_thread_mutex_t;
00143 
00144 ACE_END_VERSIONED_NAMESPACE_DECL
00145 
00146 #     define THR_CANCEL_DISABLE      0
00147 #     define THR_CANCEL_ENABLE       0
00148 #     define THR_CANCEL_DEFERRED     0
00149 #     define THR_CANCEL_ASYNCHRONOUS 0
00150 #     define THR_JOINABLE            0
00151 #     define THR_SCHED_FIFO          0
00152 #     define THR_SCHED_RR            0
00153 #     define THR_SCHED_DEFAULT       0
00154 
00155 #   elif defined (ACE_VXWORKS)
00156 #     include /**/ <sysLib.h> // for sysClkRateGet()
00157 #     if !defined (__RTP__)
00158 #       include /**/ <taskLib.h>
00159 #       include /**/ <taskHookLib.h>
00160 #     endif
00161 
00162 // make sure these are included for VXWORKS.
00163 // @todo move these to a common place, perhaps the top of the file.
00164 #     include "ace/os_include/os_fcntl.h"
00165 #     include "ace/os_include/os_netdb.h"
00166 #     include "ace/os_include/os_semaphore.h"
00167 #     include "ace/os_include/os_signal.h"
00168 #     include "ace/os_include/os_stdio.h"
00169 #     include "ace/os_include/os_stdlib.h"
00170 #     include "ace/os_include/os_stropts.h"
00171 #     include "ace/os_include/os_unistd.h"
00172 #     include "ace/os_include/arpa/os_inet.h"
00173 #     include "ace/os_include/sys/os_select.h"
00174 #     include "ace/os_include/sys/os_socket.h"
00175 
00176 // task options:  the other options are either obsolete, internal, or for
00177 // Fortran or Ada support
00178 #     define VX_UNBREAKABLE        0x0002  /* breakpoints ignored */
00179 #     if !defined (VX_FP_TASK)
00180 #       define VX_FP_TASK            0x0008  /* floating point coprocessor */
00181 #     endif
00182 #     define VX_PRIVATE_ENV        0x0080  /* private environment support */
00183 #     define VX_NO_STACK_FILL      0x0100  /* do not stack fill for
00184                                               checkstack () */
00185 
00186 #     define THR_CANCEL_DISABLE      0
00187 #     define THR_CANCEL_ENABLE       0
00188 #     define THR_CANCEL_DEFERRED     0
00189 #     define THR_CANCEL_ASYNCHRONOUS 0
00190 #     define THR_BOUND               0
00191 #     define THR_NEW_LWP             0
00192 #     define THR_DETACHED            0
00193 #     define THR_SUSPENDED           0
00194 #     define THR_DAEMON              0
00195 #     define THR_JOINABLE            0
00196 #     define THR_SCHED_FIFO          0
00197 #     define THR_SCHED_RR            0
00198 #     define THR_SCHED_DEFAULT       0
00199 #     define THR_INHERIT_SCHED       0
00200 #     define THR_EXPLICIT_SCHED      0
00201 #     define THR_SCHED_IO            0
00202 #     define THR_SCOPE_SYSTEM        0
00203 #     define THR_SCOPE_PROCESS       0
00204 #     define USYNC_THREAD            0
00205 #     define USYNC_PROCESS           1 /* It's all global on VxWorks
00206                                           (without MMU option). */
00207 
00208 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00209 
00210 typedef SEM_ID ACE_mutex_t;
00211 // Implement ACE_thread_mutex_t with ACE_mutex_t because there's just
00212 // one process . . .
00213 typedef ACE_mutex_t ACE_thread_mutex_t;
00214 #     if !defined (ACE_HAS_POSIX_SEM)
00215 // Use VxWorks semaphores, wrapped ...
00216 typedef struct
00217 {
00218   /// Semaphore handle.  This is allocated by VxWorks.
00219   SEM_ID sema_;
00220 
00221   /// Name of the semaphore:  always NULL with VxWorks.
00222   char *name_;
00223 } ACE_sema_t;
00224 #     endif /* !ACE_HAS_POSIX_SEM */
00225 typedef char * ACE_thread_t;
00226 typedef int ACE_hthread_t;
00227 // Key type: the ACE TSS emulation requires the key type be unsigned,
00228 // for efficiency.  (Current POSIX and Solaris TSS implementations also
00229 // use u_int, so the ACE TSS emulation is compatible with them.)
00230 // Native TSS key type
00231 typedef u_int ACE_OS_thread_key_t;
00232 // Application TSS key type (use this type except in TSS Emulation)
00233 #   if defined (ACE_HAS_TSS_EMULATION)
00234       typedef u_int ACE_thread_key_t;
00235 #   else  /* ! ACE_HAS_TSS_EMULATION */
00236       typedef ACE_OS_thread_key_t ACE_thread_key_t;
00237 #   endif /* ! ACE_HAS_TSS_EMULATION */
00238 
00239 ACE_END_VERSIONED_NAMESPACE_DECL
00240 
00241       // Marker for ACE_Thread_Manager to indicate that it allocated
00242       // an ACE_thread_t.  It is placed at the beginning of the ID.
00243 #     define ACE_THR_ID_ALLOCATED '\022'
00244 
00245 #   elif defined (ACE_HAS_WTHREADS)
00246 
00247 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00248 
00249 typedef CRITICAL_SECTION ACE_thread_mutex_t;
00250 
00251 typedef struct
00252 {
00253   /// Either USYNC_THREAD or USYNC_PROCESS
00254   int type_;
00255   union
00256   {
00257     HANDLE proc_mutex_;
00258     CRITICAL_SECTION thr_mutex_;
00259   };
00260 } ACE_mutex_t;
00261 
00262 // Wrapper for NT Events.
00263 typedef HANDLE ACE_event_t;
00264 
00265 #     if defined (ACE_WIN32)
00266 //@@ ACE_USES_WINCE_SEMA_SIMULATION is used to debug
00267 //   semaphore simulation on WinNT.  It should be
00268 //   changed to ACE_USES_HAS_WINCE at some later point.
00269 #       if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
00270 typedef HANDLE ACE_sema_t;
00271 #       else
00272 /**
00273  * @class ACE_sema_t
00274  *
00275  * @brief Semaphore simulation for Windows CE.
00276  */
00277 class ACE_Export ACE_sema_t
00278 {
00279 public:
00280   /// Serializes access to <count_>.
00281   ACE_thread_mutex_t lock_;
00282 
00283   /// This event is signaled whenever the count becomes non-zero.
00284   ACE_event_t count_nonzero_;
00285 
00286   /// Current count of the semaphore.
00287   u_int count_;
00288 };
00289 
00290 #       endif /* ACE_USES_WINCE_SEMA_SIMULATION */
00291 #     endif /* defined (ACE_WIN32) */
00292 
00293 ACE_END_VERSIONED_NAMESPACE_DECL
00294 
00295 // These need to be different values, neither of which can be 0...
00296 #     define USYNC_THREAD 1
00297 #     define USYNC_PROCESS 2
00298 
00299 #     define THR_CANCEL_DISABLE      0
00300 #     define THR_CANCEL_ENABLE       0
00301 #     define THR_CANCEL_DEFERRED     0
00302 #     define THR_CANCEL_ASYNCHRONOUS 0
00303 #     define THR_DETACHED            0x02000000 /* ignore in most places */
00304 #     define THR_BOUND               0          /* ignore in most places */
00305 #     define THR_NEW_LWP             0          /* ignore in most places */
00306 #     define THR_DAEMON              0          /* ignore in most places */
00307 #     define THR_JOINABLE            0          /* ignore in most places */
00308 #     define THR_SUSPENDED   CREATE_SUSPENDED
00309 #     define THR_USE_AFX             0x01000000
00310 #     define THR_SCHED_FIFO          0
00311 #     define THR_SCHED_RR            0
00312 #     define THR_SCHED_DEFAULT       0
00313 #     define THR_INHERIT_SCHED       0
00314 #     define THR_SCOPE_PROCESS       0
00315 #     define THR_SCOPE_SYSTEM        0
00316 #   endif /* ACE_HAS_PTHREADS / STHREADS / VXWORKS / WTHREADS **********/
00317 
00318 // If we're using PACE then we don't want this class (since PACE
00319 // takes care of it) unless we're on Windows. Win32 mutexes, semaphores,
00320 // and condition variables are not yet supported in PACE.
00321 #   if defined (ACE_LACKS_COND_T)
00322 
00323 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00324 
00325 /**
00326  * @class ACE_cond_t
00327  *
00328  * @brief This structure is used to implement condition variables on
00329  * platforms that lack it natively, such as VxWorks, and Win32.
00330  *
00331  * At the current time, this stuff only works for threads
00332  * within the same process.
00333  */
00334 class ACE_Export ACE_cond_t
00335 {
00336 public:
00337 
00338   /// Returns the number of waiters.
00339   long waiters (void) const;
00340 
00341 //protected:
00342   /// Number of waiting threads.
00343   long waiters_;
00344 
00345   /// Serialize access to the waiters count.
00346   ACE_thread_mutex_t waiters_lock_;
00347 
00348   /// Queue up threads waiting for the condition to become signaled.
00349   ACE_sema_t sema_;
00350 
00351 #     if defined (ACE_VXWORKS)
00352   /**
00353    * A semaphore used by the broadcast/signal thread to wait for all
00354    * the waiting thread(s) to wake up and be released from the
00355    * semaphore.
00356    */
00357   ACE_sema_t waiters_done_;
00358 #     elif defined (ACE_WIN32)
00359   /**
00360    * An auto reset event used by the broadcast/signal thread to wait
00361    * for the waiting thread(s) to wake up and get a chance at the
00362    * semaphore.
00363    */
00364   HANDLE waiters_done_;
00365 #     else
00366 #       error "Please implement this feature or check your config.h file!"
00367 #     endif /* ACE_VXWORKS */
00368 
00369   /// Keeps track of whether we were broadcasting or just signaling.
00370   size_t was_broadcast_;
00371 };
00372 
00373 struct ACE_Export ACE_condattr_t
00374 {
00375   int type;
00376 };
00377 
00378 struct ACE_Export ACE_mutexattr_t
00379 {
00380   int type;
00381 };
00382 
00383 ACE_END_VERSIONED_NAMESPACE_DECL
00384 
00385 #   endif /* ACE_LACKS_COND_T */
00386 
00387 #   if defined (ACE_LACKS_RWLOCK_T) && !defined (ACE_HAS_PTHREADS_UNIX98_EXT)
00388 
00389 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00390 
00391 /**
00392  * @class ACE_rwlock_t
00393  *
00394  * @brief This is used to implement readers/writer locks on NT,
00395  *     VxWorks, and POSIX pthreads.
00396  *
00397  *     At the current time, this stuff only works for threads
00398  *     within the same process.
00399  */
00400 struct ACE_Export ACE_rwlock_t
00401 {
00402 public:
00403 //protected:
00404 
00405   /// Serialize access to internal state.
00406   ACE_mutex_t lock_;
00407 
00408   /// Reader threads waiting to acquire the lock.
00409   ACE_cond_t waiting_readers_;
00410 
00411   /// Number of waiting readers.
00412   int num_waiting_readers_;
00413 
00414   /// Writer threads waiting to acquire the lock.
00415   ACE_cond_t waiting_writers_;
00416 
00417   /// Number of waiting writers.
00418   int num_waiting_writers_;
00419 
00420   /// Value is -1 if writer has the lock, else this keeps track of the
00421   /// number of readers holding the lock.
00422   int ref_count_;
00423 
00424   /// Indicate that a reader is trying to upgrade
00425   int important_writer_;
00426 
00427   /// Condition for the upgrading reader
00428   ACE_cond_t waiting_important_writer_;
00429 };
00430 
00431 ACE_END_VERSIONED_NAMESPACE_DECL
00432 
00433 #   elif defined (ACE_HAS_PTHREADS_UNIX98_EXT)
00434 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00435 typedef pthread_rwlock_t ACE_rwlock_t;
00436 ACE_END_VERSIONED_NAMESPACE_DECL
00437 #   elif defined (ACE_HAS_STHREADS)
00438 #     include /**/ <synch.h>
00439 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00440 typedef rwlock_t ACE_rwlock_t;
00441 ACE_END_VERSIONED_NAMESPACE_DECL
00442 #   endif /* ACE_LACKS_RWLOCK_T */
00443 
00444 // Define some default thread priorities on all threaded platforms, if
00445 // not defined above or in the individual platform config file.
00446 // ACE_THR_PRI_FIFO_DEF should be used by applications for default
00447 // real-time thread priority.  ACE_THR_PRI_OTHER_DEF should be used
00448 // for non-real-time priority.
00449 #   if !defined(ACE_THR_PRI_FIFO_DEF)
00450 #     if defined (ACE_WTHREADS)
00451       // It would be more in spirit to use THREAD_PRIORITY_NORMAL.  But,
00452       // using THREAD_PRIORITY_ABOVE_NORMAL should give preference to the
00453       // threads in this process, even if the process is not in the
00454       // REALTIME_PRIORITY_CLASS.
00455 #       define ACE_THR_PRI_FIFO_DEF THREAD_PRIORITY_ABOVE_NORMAL
00456 #     else  /* ! ACE_WTHREADS */
00457 #       define ACE_THR_PRI_FIFO_DEF 0
00458 #     endif /* ! ACE_WTHREADS */
00459 #   endif /* ! ACE_THR_PRI_FIFO_DEF */
00460 
00461 #   if !defined(ACE_THR_PRI_OTHER_DEF)
00462 #     if defined (ACE_WTHREADS)
00463       // It would be more in spirit to use THREAD_PRIORITY_NORMAL.  But,
00464       // using THREAD_PRIORITY_ABOVE_NORMAL should give preference to the
00465       // threads in this process, even if the process is not in the
00466       // REALTIME_PRIORITY_CLASS.
00467 #       define ACE_THR_PRI_OTHER_DEF THREAD_PRIORITY_NORMAL
00468 #     else  /* ! ACE_WTHREADS */
00469 #       define ACE_THR_PRI_OTHER_DEF 0
00470 #     endif /* ! ACE_WTHREADS */
00471 #   endif /* ! ACE_THR_PRI_OTHER_DEF */
00472 
00473 // Recursive mutex support.
00474 //
00475 // There are two parts to this:
00476 // 1. The mutex type itself. This is based on whether or not the
00477 //    platform supports recursive mutexes natively or they're emulated.
00478 // 2. Support for using the recursive mutex with a condition variable.
00479 //    When a thread waits on a condition variable, it has to relinquish
00480 //    the lock and wait atomically, then reacquire it after the condition
00481 //    variable is signaled. In non-recursive mutexes, the platform
00482 //    handles this automatically. But in recursive mutexes, especially
00483 //    when emulated, the recursion count needs to be maintained across
00484 //    the wait. Since another thread needs to be able to acquire the
00485 //    lock, it needs to appear free, even if the waiting thread had done
00486 //    multiple acquires. Thus, there's another structure to hold this
00487 //    information, and is used with the recursive_mutex_cond_unlock()
00488 //    and recursive_mutex_cond_relock() methods to maintain the expected
00489 //    state when the wait finishes.
00490 #   if defined (ACE_HAS_RECURSIVE_MUTEXES)
00491 
00492 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00493 
00494 typedef ACE_thread_mutex_t ACE_recursive_thread_mutex_t;
00495 #     if defined (ACE_WIN32)
00496 // Windows has recursive mutexes, but doesn't have condition variables,
00497 // so there's no built-in support for this. Thus, the condition-related
00498 // unlock/relock is augmented in ACE.
00499 struct ACE_recursive_mutex_state
00500 {
00501   // On Windows the augmented processing is simply unlocking/relocking
00502   // the recursive locks - the condition handles a single lock ok.
00503   LONG relock_count_;
00504 };
00505 #     else
00506 // No need for special handling; just need a type for method signatures.
00507 typedef int ACE_recursive_mutex_state;
00508 #     endif /* ACE_WIN32 */
00509 
00510 ACE_END_VERSIONED_NAMESPACE_DECL
00511 
00512 #   else
00513 
00514 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00515 
00516 /**
00517  * @class ACE_recursive_thread_mutex_t
00518  *
00519  * @brief Implement a thin C++ wrapper that allows nested acquisition
00520  * and release of a mutex that occurs in the same thread.
00521  *
00522  * This implementation is based on an algorithm sketched by Dave
00523  * Butenhof <butenhof@zko.dec.com>.  Naturally, I take the
00524  * credit for any mistakes ;-)
00525  */
00526 class ACE_recursive_thread_mutex_t
00527 {
00528 public:
00529   /// Guards the state of the nesting level and thread id.
00530   ACE_thread_mutex_t nesting_mutex_;
00531 
00532   /// This condition variable suspends other waiting threads until the
00533   /// mutex is available.
00534   ACE_cond_t lock_available_;
00535 
00536   /// Current nesting level of the recursion.
00537   int nesting_level_;
00538 
00539   /// Current owner of the lock.
00540   ACE_thread_t owner_id_;
00541 };
00542 
00543 // Since recursive mutex is emulated, the state saving needs to be handled
00544 // in ACE as well. These members save those from ACE_recursive_thread_mutex_t.
00545 struct ACE_recursive_mutex_state
00546 {
00547   int nesting_level_;
00548   ACE_thread_t owner_id_;
00549 };
00550 
00551 ACE_END_VERSIONED_NAMESPACE_DECL
00552 
00553 #   endif /* ACE_HAS_RECURSIVE_MUTEXES */
00554 
00555 # else /* !ACE_HAS_THREADS, i.e., the OS/platform doesn't support threading. */
00556 
00557 // Give these things some reasonable value...
00558 #   define ACE_SCOPE_PROCESS 0
00559 #   define ACE_SCOPE_LWP 1
00560 #   define ACE_SCOPE_THREAD 2
00561 #   define ACE_SCHED_OTHER 0
00562 #   define ACE_SCHED_FIFO 1
00563 #   define ACE_SCHED_RR 2
00564 #   if !defined (THR_CANCEL_DISABLE)
00565 #     define THR_CANCEL_DISABLE      0
00566 #   endif /* ! THR_CANCEL_DISABLE */
00567 #   if !defined (THR_CANCEL_ENABLE)
00568 #     define THR_CANCEL_ENABLE       0
00569 #   endif /* ! THR_CANCEL_ENABLE */
00570 #   if !defined (THR_CANCEL_DEFERRED)
00571 #     define THR_CANCEL_DEFERRED     0
00572 #   endif /* ! THR_CANCEL_DEFERRED */
00573 #   if !defined (THR_CANCEL_ASYNCHRONOUS)
00574 #     define THR_CANCEL_ASYNCHRONOUS 0
00575 #   endif /* ! THR_CANCEL_ASYNCHRONOUS */
00576 #   if !defined (THR_JOINABLE)
00577 #     define THR_JOINABLE    0     /* ignore in most places */
00578 #   endif /* ! THR_JOINABLE */
00579 #   if !defined (THR_DETACHED)
00580 #     define THR_DETACHED    0     /* ignore in most places */
00581 #   endif /* ! THR_DETACHED */
00582 #   if !defined (THR_DAEMON)
00583 #     define THR_DAEMON      0     /* ignore in most places */
00584 #   endif /* ! THR_DAEMON */
00585 #   if !defined (THR_BOUND)
00586 #     define THR_BOUND       0     /* ignore in most places */
00587 #   endif /* ! THR_BOUND */
00588 #   if !defined (THR_NEW_LWP)
00589 #     define THR_NEW_LWP     0     /* ignore in most places */
00590 #   endif /* ! THR_NEW_LWP */
00591 #   if !defined (THR_SUSPENDED)
00592 #     define THR_SUSPENDED   0     /* ignore in most places */
00593 #   endif /* ! THR_SUSPENDED */
00594 #   if !defined (THR_SCHED_FIFO)
00595 #     define THR_SCHED_FIFO 0
00596 #   endif /* ! THR_SCHED_FIFO */
00597 #   if !defined (THR_SCHED_RR)
00598 #     define THR_SCHED_RR 0
00599 #   endif /* ! THR_SCHED_RR */
00600 #   if !defined (THR_SCHED_DEFAULT)
00601 #     define THR_SCHED_DEFAULT 0
00602 #   endif /* ! THR_SCHED_DEFAULT */
00603 #   if !defined (THR_INHERIT_SCHED)
00604 #     define THR_INHERIT_SCHED 0
00605 #   endif /* ! THR_INHERIT_SCHED */
00606 #   if !defined (USYNC_THREAD)
00607 #     define USYNC_THREAD 0
00608 #   endif /* ! USYNC_THREAD */
00609 #   if !defined (USYNC_PROCESS)
00610 #     define USYNC_PROCESS 0
00611 #   endif /* ! USYNC_PROCESS */
00612 #   if !defined (THR_SCOPE_PROCESS)
00613 #     define THR_SCOPE_PROCESS 0
00614 #   endif /* ! THR_SCOPE_PROCESS */
00615 #   if !defined (THR_SCOPE_SYSTEM)
00616 #     define THR_SCOPE_SYSTEM 0
00617 #   endif /* ! THR_SCOPE_SYSTEM */
00618 
00619 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00620 
00621 // These are dummies needed for class OS.h
00622 typedef int ACE_cond_t;
00623 struct ACE_Export ACE_condattr_t
00624 {
00625   int type;
00626 };
00627 struct ACE_Export ACE_mutexattr_t
00628 {
00629   int type;
00630 };
00631 typedef int ACE_mutex_t;
00632 typedef int ACE_thread_mutex_t;
00633 typedef int ACE_recursive_thread_mutex_t;
00634 typedef int ACE_recursive_mutex_state;
00635 #   if !defined (ACE_HAS_POSIX_SEM) && !defined (ACE_USES_FIFO_SEM)
00636 typedef int ACE_sema_t;
00637 #   endif /* !ACE_HAS_POSIX_SEM && !ACE_USES_FIFO_SEM */
00638 typedef int ACE_rwlock_t;
00639 typedef int ACE_thread_t;
00640 typedef int ACE_hthread_t;
00641 // Native TSS key type
00642 typedef unsigned int ACE_OS_thread_key_t;
00643 // Application TSS key type (use this type except in TSS Emulation)
00644 #   if defined (ACE_HAS_TSS_EMULATION)
00645       typedef u_int ACE_thread_key_t;
00646 #   else  /* ! ACE_HAS_TSS_EMULATION */
00647       typedef ACE_OS_thread_key_t ACE_thread_key_t;
00648 #   endif /* ! ACE_HAS_TSS_EMULATION */
00649 
00650 ACE_END_VERSIONED_NAMESPACE_DECL
00651 
00652 // Ensure that ACE_THR_PRI_FIFO_DEF and ACE_THR_PRI_OTHER_DEF are
00653 // defined on non-threaded platforms, to support application source
00654 // code compatibility.  ACE_THR_PRI_FIFO_DEF should be used by
00655 // applications for default real-time thread priority.
00656 // ACE_THR_PRI_OTHER_DEF should be used for non-real-time priority.
00657 #   if !defined(ACE_THR_PRI_FIFO_DEF)
00658 #     define ACE_THR_PRI_FIFO_DEF 0
00659 #   endif /* ! ACE_THR_PRI_FIFO_DEF */
00660 #   if !defined(ACE_THR_PRI_OTHER_DEF)
00661 #     define ACE_THR_PRI_OTHER_DEF 0
00662 #   endif /* ! ACE_THR_PRI_OTHER_DEF */
00663 
00664 # endif /* ACE_HAS_THREADS ***********************************************/
00665 
00666 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00667 
00668 /**
00669  * @class ACE_Thread_ID
00670  *
00671  * @brief Defines a platform-independent thread ID class.  Note that
00672  *  this class should be defined within the scope of a thread, rather
00673  *  than at global scope!
00674  */
00675 class ACE_Export ACE_Thread_ID
00676 {
00677 public:
00678   /// Initialize the object using the thread id and thread handle
00679   /// passed as parameters.
00680   ACE_Thread_ID (ACE_thread_t thr_id,
00681                  ACE_hthread_t thr_handle);
00682 
00683   /// Initialize the object using calls to ACE_OS::thr_self().
00684   ACE_Thread_ID (void);
00685 
00686   /// Copy constructor.
00687   ACE_Thread_ID (const ACE_Thread_ID &rhs);
00688 
00689   /// Get the thread id.
00690   ACE_thread_t id (void) const;
00691 
00692   /// Set the thread id.
00693   void id (ACE_thread_t);
00694 
00695   /// Get the thread handle.
00696   ACE_hthread_t handle (void) const;
00697 
00698   /// Set the thread handle.
00699   void handle (ACE_hthread_t);
00700 
00701   // Create a string representation of the thread id.
00702   void to_string (char *thr_string) const;
00703 
00704   /// Equality operator.
00705   bool operator== (const ACE_Thread_ID &) const;
00706 
00707   /// Inequality operator.
00708   bool operator!= (const ACE_Thread_ID &) const;
00709 
00710 private:
00711   /// Identify the thread.
00712   ACE_thread_t thread_id_;
00713 
00714   /// Handle to the thread (typically used to "wait" on Win32).
00715   ACE_hthread_t thread_handle_;
00716 };
00717 
00718 // = The ACE_Sched_Priority type should be used for platform-
00719 //   independent thread and process priorities, by convention.
00720 //   int should be used for OS-specific priorities.
00721 typedef int ACE_Sched_Priority;
00722 
00723 # if !defined (ACE_DEFAULT_SYNCH_TYPE)
00724 #   if defined (ACE_VXWORKS)
00725       // Types include these options: SEM_Q_PRIORITY, SEM_Q_FIFO,
00726       // SEM_DELETE_SAFE, and SEM_INVERSION_SAFE.  SEM_Q_FIFO is
00727       // used as the default because that is VxWorks' default.
00728 #     define ACE_DEFAULT_SYNCH_TYPE SEM_Q_FIFO
00729 #   else
00730 #     define ACE_DEFAULT_SYNCH_TYPE USYNC_THREAD
00731 #   endif /* ACE_VXWORKS */
00732 #endif /* ! ACE_DEFAULT_SYNCH_TYPE */
00733 
00734 // forward declaration
00735 class ACE_Sched_Params;
00736 class ACE_Time_Value;
00737 
00738 #if defined (ACE_WIN32)
00739 typedef int ACE_idtype_t;
00740 typedef DWORD ACE_id_t;
00741 typedef int ACE_pri_t;
00742 #   define ACE_SELF (0)
00743 #else /* !defined (ACE_WIN32) */
00744 #   if defined (ACE_HAS_IDTYPE_T)
00745   typedef idtype_t ACE_idtype_t;
00746 #   else
00747   typedef int ACE_idtype_t;
00748 #   endif /* ACE_HAS_IDTYPE_T */
00749 #   if defined (ACE_HAS_STHREADS) || defined (DIGITAL_UNIX)
00750 #     if defined (ACE_LACKS_PRI_T)
00751     typedef int pri_t;
00752 #     endif /* ACE_LACKS_PRI_T */
00753   typedef id_t ACE_id_t;
00754 #     define ACE_SELF P_MYID
00755   typedef pri_t ACE_pri_t;
00756 #   else  /* ! ACE_HAS_STHREADS && ! DIGITAL_UNIX */
00757   typedef long ACE_id_t;
00758 #     define ACE_SELF (-1)
00759   typedef short ACE_pri_t;
00760 #   endif /* ! ACE_HAS_STHREADS && ! DIGITAL_UNIX */
00761 #endif /* !defined (ACE_WIN32) */
00762 
00763 # if defined (ACE_HAS_TSS_EMULATION)
00764     // Allow config.h to set the default number of thread keys.
00765 #   if !defined (ACE_DEFAULT_THREAD_KEYS)
00766 #     define ACE_DEFAULT_THREAD_KEYS 64
00767 #   endif /* ! ACE_DEFAULT_THREAD_KEYS */
00768 
00769 // forward declaration
00770 class ACE_TSS_Keys;
00771 
00772 /**
00773  * @class ACE_TSS_Emulation
00774  *
00775  * @brief Thread-specific storage emulation.
00776  *
00777  * This provides a thread-specific storage implementation.
00778  * It is intended for use on platforms that don't have a
00779  * native TSS, or have a TSS with limitations such as the
00780  * number of keys or lack of support for removing keys.
00781  */
00782 class ACE_Export ACE_TSS_Emulation
00783 {
00784 public:
00785   typedef void (*ACE_TSS_DESTRUCTOR)(void *value) /* throw () */;
00786 
00787   /// Maximum number of TSS keys allowed over the life of the program.
00788   enum { ACE_TSS_THREAD_KEYS_MAX = ACE_DEFAULT_THREAD_KEYS };
00789 
00790   /// Returns the total number of keys allocated so far.
00791   static u_int total_keys ();
00792 
00793   /// Sets the argument to the next available key.  Returns 0 on success,
00794   /// -1 if no keys are available.
00795   static int next_key (ACE_thread_key_t &key);
00796 
00797   /// Release a key that was used. This way the key can be given out in a
00798   /// new request. Returns 0 on success, 1 if the key was not reserved.
00799   static int release_key (ACE_thread_key_t key);
00800 
00801   /// Check a key for validity.
00802   static int is_key (ACE_thread_key_t key);
00803 
00804   /// Returns the exit hook associated with the key.  Does _not_ check
00805   /// for a valid key.
00806   static ACE_TSS_DESTRUCTOR tss_destructor (const ACE_thread_key_t key);
00807 
00808   /// Associates the TSS destructor with the key.  Does _not_ check
00809   /// for a valid key.
00810   static void tss_destructor (const ACE_thread_key_t key,
00811                               ACE_TSS_DESTRUCTOR destructor);
00812 
00813   /// Accesses the object referenced by key in the current thread's TSS array.
00814   /// Does _not_ check for a valid key.
00815   static void *&ts_object (const ACE_thread_key_t key);
00816 
00817   /**
00818    * Setup an array to be used for local TSS.  Returns the array
00819    * address on success.  Returns 0 if local TSS had already been
00820    * setup for this thread.  There is no corresponding tss_close ()
00821    * because it is not needed.
00822    * @note tss_open () is called by ACE for threads that it spawns.
00823    * If your application spawns threads without using ACE, and it uses
00824    * ACE's TSS emulation, each of those threads should call tss_open
00825    * ().  See the ace_thread_adapter () implementation for an example.
00826    */
00827   static void *tss_open (void *ts_storage[ACE_TSS_THREAD_KEYS_MAX]);
00828 
00829   /// Shutdown TSS emulation.  For use only by ACE_OS::cleanup_tss ().
00830   static void tss_close ();
00831 
00832 private:
00833   // Global TSS structures.
00834   /// Contains the possible value of the next key to be allocated. Which key
00835   /// is actually allocated is based on the tss_keys_used
00836   static u_int total_keys_;
00837 
00838   /// Array of thread exit hooks (TSS destructors) that are called for each
00839   /// key (that has one) when the thread exits.
00840   static ACE_TSS_DESTRUCTOR tss_destructor_ [ACE_TSS_THREAD_KEYS_MAX];
00841 
00842   /// TSS_Keys instance to administrate whether a specific key is in used
00843   /// or not.
00844   /// or not.
00845   // Static construction in VxWorks 5.4 and later is slightly broken.
00846   // If the static object is more complex than an integral type, static
00847   // construction will occur twice.  The tss_keys_used_ object is
00848   // statically constructed and then modified by ACE_Log_Msg::instance()
00849   // when two keys are created and TSS data is stored.  However, at
00850   // the end of static construction the tss_keys_used_ object is again
00851   // initialized and therefore it will appear to next_key() that no
00852   // TSS keys have been handed out.  That is all true unless the
00853   // tss_keys_used object is a static pointer instead of a static object.
00854   static ACE_TSS_Keys* tss_keys_used_;
00855 
00856 #   if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
00857   /// Location of current thread's TSS array.
00858   static void **tss_base (void* ts_storage[] = 0, u_int *ts_created = 0);
00859 #   else  /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
00860   /// Location of current thread's TSS array.
00861   static void **&tss_base ();
00862 #   endif /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
00863 
00864 #   if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
00865   // Rely on native thread specific storage for the implementation,
00866   // but just use one key.
00867   static ACE_OS_thread_key_t native_tss_key_;
00868 
00869   // Used to indicate if native tss key has been allocated
00870   static int key_created_;
00871 #   endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
00872 };
00873 
00874 # else   /* ! ACE_HAS_TSS_EMULATION */
00875     // allow user to define its own ACE_DEFAULT_THREAD_KEYS in Windows,
00876     // where The MSSDK defines only 64 entries
00877 #   if defined (TLS_MINIMUM_AVAILABLE) && !defined (ACE_DEFAULT_THREAD_KEYS)
00878     // WIN32 platforms define TLS_MINIMUM_AVAILABLE natively.
00879 #     define ACE_DEFAULT_THREAD_KEYS TLS_MINIMUM_AVAILABLE
00880 #   endif /* TSL_MINIMUM_AVAILABLE */
00881 
00882 # endif /* ACE_HAS_TSS_EMULATION */
00883 
00884 // moved ACE_TSS_Ref, ACE_TSS_Info, and ACE_TSS_Keys class
00885 // declarations from OS.cpp so they are visible to the single
00886 // file of template instantiations.
00887 # if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION)
00888 /**
00889  * @class ACE_TSS_Ref
00890  *
00891  * @brief "Reference count" for thread-specific storage keys.
00892  *
00893  * Since the <ACE_Unbounded_Stack> doesn't allow duplicates, the
00894  * "reference count" is the identify of the thread_id.
00895  */
00896 class ACE_TSS_Ref
00897 {
00898 public:
00899   /// Constructor
00900   ACE_TSS_Ref (ACE_thread_t id);
00901 
00902   /// Default constructor
00903   ACE_TSS_Ref (void);
00904 
00905   /// Check for equality.
00906   bool operator== (const ACE_TSS_Ref &) const;
00907 
00908   /// Check for inequality.
00909   bool operator!= (const ACE_TSS_Ref &) const;
00910 
00911 // private:
00912 
00913   /// ID of thread using a specific key.
00914   ACE_thread_t tid_;
00915 };
00916 
00917 /**
00918  * @class ACE_TSS_Info
00919  *
00920  * @brief Thread Specific Key management.
00921  *
00922  * This class maps a key to a "destructor."
00923  */
00924 class ACE_TSS_Info
00925 {
00926 public:
00927   /// Declare pointer to function to destroy tss object.
00928   typedef void (*Destructor)(void *);
00929 
00930   /// Constructor
00931   ACE_TSS_Info (ACE_thread_key_t key,
00932                 Destructor dest = 0);
00933 
00934   /// Default constructor
00935   ACE_TSS_Info (void);
00936 
00937   /// Returns 1 if the key is in use, 0 if not.
00938   int key_in_use (void) const { return thread_count_ != -1; }
00939 
00940   /// Mark the key as being in use if the flag is non-zero, or
00941   /// not in use if the flag is 0.
00942   void key_in_use (int flag) { thread_count_ = flag == 0  ?  -1  :  1; }
00943 
00944   /// Check for equality.
00945   bool operator== (const ACE_TSS_Info &) const;
00946 
00947   /// Check for inequality.
00948   bool operator!= (const ACE_TSS_Info &) const;
00949 
00950   /// Dump the state.
00951   void dump (void);
00952 
00953 private:
00954   /// Key to the thread-specific storage item.
00955   ACE_thread_key_t key_;
00956 
00957   /// "Destructor" that gets called when the item is finally released.
00958   Destructor destructor_;
00959 
00960   /// Count of threads that are using this key.  Contains -1 when the
00961   /// key is not in use.
00962   int thread_count_;
00963 
00964   friend class ACE_TSS_Cleanup;
00965 };
00966 
00967 /**
00968  * @class ACE_TSS_Keys
00969  *
00970  * @brief Collection of in-use flags for a thread's TSS keys.
00971  * For internal use only by ACE_TSS_Cleanup; it is public because
00972  * some compilers can't use nested classes for template instantiation
00973  * parameters.
00974  *
00975  * Wrapper around array of whether each key is in use.  A simple
00976  * typedef doesn't work with Sun C++ 4.2.
00977  */
00978 class ACE_TSS_Keys
00979 {
00980 public:
00981   /// Default constructor, to initialize all bits to zero (unused).
00982   ACE_TSS_Keys (void);
00983 
00984   /// Mark the specified key as being in use, if it was not already so marked.
00985   /// Returns 1 if the had already been marked, 0 if not.
00986   int test_and_set (const ACE_thread_key_t key);
00987 
00988   /// Mark the specified key as not being in use, if it was not already so
00989   /// cleared.  Returns 1 if the key had already been cleared, 0 if not.
00990   int test_and_clear (const ACE_thread_key_t key);
00991 
00992   /// Return whether the specific key is marked as in use.
00993   /// Returns 1 if the key is been marked, 0 if not.
00994   int is_set (const ACE_thread_key_t key) const;
00995 
00996 private:
00997   /// For a given key, find the word and bit number that represent it.
00998   static void find (const u_int key, u_int &word, u_int &bit);
00999 
01000   enum
01001     {
01002 #   if ACE_SIZEOF_LONG == 8
01003       ACE_BITS_PER_WORD = 64,
01004 #   elif ACE_SIZEOF_LONG == 4
01005       ACE_BITS_PER_WORD = 32,
01006 #   else
01007 #     error ACE_TSS_Keys only supports 32 or 64 bit longs.
01008 #   endif /* ACE_SIZEOF_LONG == 8 */
01009       ACE_WORDS = (ACE_DEFAULT_THREAD_KEYS - 1) / ACE_BITS_PER_WORD + 1
01010     };
01011 
01012   /// Bit flag collection.  A bit value of 1 indicates that the key is in
01013   /// use by this thread.
01014   u_long key_bit_words_[ACE_WORDS];
01015 };
01016 
01017 # endif /* defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) */
01018 
01019 // Support non-scalar thread keys, such as with some POSIX
01020 // implementations, e.g., MVS.
01021 # if defined (ACE_HAS_NONSCALAR_THREAD_KEY_T)
01022 #   define ACE_KEY_INDEX(OBJ,KEY) \
01023   u_int OBJ; \
01024   ACE_OS::memcpy (&OBJ, &KEY, sizeof (u_int))
01025 # else
01026 #   define ACE_KEY_INDEX(OBJ,KEY) u_int OBJ = KEY
01027 # endif /* ACE_HAS_NONSCALAR_THREAD_KEY_T */
01028 
01029 ACE_END_VERSIONED_NAMESPACE_DECL
01030 
01031 #if (defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1)
01032 # define ACE_MUTEX_LOCK_CLEANUP_ADAPTER_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ace_mutex_lock_cleanup_adapter)
01033 #endif  /* ACE_HAS_VERSIONED_NAMESPACE == 1 */
01034 
01035 
01036 # if defined (ACE_HAS_THR_C_FUNC)
01037 // This is necessary to work around nasty problems with MVS C++.
01038 extern "C" ACE_Export void ACE_MUTEX_LOCK_CLEANUP_ADAPTER_NAME (void *args);
01039 #   define ACE_PTHREAD_CLEANUP_PUSH(A) pthread_cleanup_push (ACE_MUTEX_LOCK_CLEANUP_ADAPTER_NAME, (void *) A);
01040 #   define ACE_PTHREAD_CLEANUP_POP(A) pthread_cleanup_pop(A)
01041 # elif defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CLEANUP)
01042 // Though we are defining a extern "C" function to match the prototype of
01043 // pthread_cleanup_push, it is undone by the Solaris header file
01044 // /usr/include/pthread.h. So this macro generates a warning under Solaris
01045 // with SunCC. This is a bug in the Solaris header file.
01046 extern "C" ACE_Export void ACE_MUTEX_LOCK_CLEANUP_ADAPTER_NAME (void *args);
01047 #   define ACE_PTHREAD_CLEANUP_PUSH(A) pthread_cleanup_push (ACE_MUTEX_LOCK_CLEANUP_ADAPTER_NAME, (void *) A);
01048 #   define ACE_PTHREAD_CLEANUP_POP(A) pthread_cleanup_pop(A)
01049 # else
01050 #   define ACE_PTHREAD_CLEANUP_PUSH(A)
01051 #   define ACE_PTHREAD_CLEANUP_POP(A)
01052 # endif /* ACE_HAS_THR_C_FUNC */
01053 
01054 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
01055 
01056 # if !defined (ACE_WIN32)
01057 // forward decl's
01058 class ACE_event_t;
01059 # endif
01060 
01061 class ACE_Base_Thread_Adapter;
01062 
01063 namespace ACE_OS {
01064   //@{ @name A set of wrappers for threads
01065 
01066   /// This is necessary to deal with POSIX pthreads and their use of
01067   /// structures for thread ids.
01068   extern ACE_Export ACE_thread_t NULL_thread;
01069 
01070   /// This is necessary to deal with POSIX pthreads and their use of
01071   /// structures for thread handles.
01072   extern ACE_Export ACE_hthread_t NULL_hthread;
01073 
01074   /// This is necessary to deal with POSIX pthreads and their use of
01075   /// structures for TSS keys.
01076   extern ACE_Export ACE_thread_key_t NULL_key;
01077   //@}
01078 
01079   /**
01080    * Call TSS destructors for the current thread.  If the current
01081    * thread is the main thread, then the argument must be 1.
01082    * For private use of ACE_Object_Manager and ACE_Thread_Adapter only.
01083    */
01084   extern ACE_Export
01085   void cleanup_tss (const u_int main_thread);
01086 
01087   //@{ @name A set of wrappers for condition variables.
01088 #if defined (ACE_LACKS_COND_T)
01089   extern ACE_Export
01090 #else
01091   ACE_NAMESPACE_INLINE_FUNCTION
01092 #endif /* ACE_LACKS_COND_T */
01093   int condattr_init (ACE_condattr_t &attributes,
01094                      int type = ACE_DEFAULT_SYNCH_TYPE);
01095 
01096 #if defined (ACE_LACKS_COND_T)
01097   extern ACE_Export
01098 #else
01099   ACE_NAMESPACE_INLINE_FUNCTION
01100 #endif /* ACE_LACKS_COND_T */
01101   int condattr_destroy (ACE_condattr_t &attributes);
01102 
01103 #if defined (ACE_LACKS_COND_T)
01104   extern ACE_Export
01105 #else
01106   ACE_NAMESPACE_INLINE_FUNCTION
01107 #endif /* ACE_LACKS_COND_T */
01108   int cond_broadcast (ACE_cond_t *cv);
01109 
01110 #if defined (ACE_LACKS_COND_T)
01111   extern ACE_Export
01112 #else
01113   ACE_NAMESPACE_INLINE_FUNCTION
01114 #endif /* ACE_LACKS_COND_T */
01115   int cond_destroy (ACE_cond_t *cv);
01116 
01117   extern ACE_Export
01118   int cond_init (ACE_cond_t *cv,
01119                  short type = ACE_DEFAULT_SYNCH_TYPE,
01120                  const char *name = 0,
01121                  void *arg = 0);
01122 
01123 #if defined (ACE_LACKS_COND_T)
01124   extern ACE_Export
01125 #else
01126   ACE_NAMESPACE_INLINE_FUNCTION
01127 #endif /* ACE_LACKS_COND_T */
01128   int cond_init (ACE_cond_t *cv,
01129                  ACE_condattr_t &attributes,
01130                  const char *name = 0,
01131                  void *arg = 0);
01132 
01133 # if defined (ACE_HAS_WCHAR)
01134 #   if defined (ACE_LACKS_COND_T)
01135   extern ACE_Export
01136 #   else
01137   ACE_NAMESPACE_INLINE_FUNCTION
01138 #   endif /* ACE_LACKS_COND_T */
01139   int cond_init (ACE_cond_t *cv,
01140                  short type,
01141                  const wchar_t *name,
01142                  void *arg = 0);
01143 
01144 #   if defined (ACE_LACKS_COND_T)
01145   extern ACE_Export
01146 #   else
01147   ACE_NAMESPACE_INLINE_FUNCTION
01148 #   endif /* ACE_LACKS_COND_T */
01149   int cond_init (ACE_cond_t *cv,
01150                  ACE_condattr_t &attributes,
01151                  const wchar_t *name,
01152                  void *arg = 0);
01153 # endif /* ACE_HAS_WCHAR */
01154 
01155 #if defined (ACE_LACKS_COND_T)
01156   extern ACE_Export
01157 #else
01158   ACE_NAMESPACE_INLINE_FUNCTION
01159 #endif /* ACE_LACKS_COND_T */
01160   int cond_signal (ACE_cond_t *cv);
01161 
01162 #if defined (ACE_LACKS_COND_T)
01163   extern ACE_Export
01164 #else
01165   ACE_NAMESPACE_INLINE_FUNCTION
01166 #endif /* ACE_LACKS_COND_T */
01167   int cond_timedwait (ACE_cond_t *cv,
01168                       ACE_mutex_t *m,
01169                       ACE_Time_Value *);
01170 
01171 #if defined (ACE_LACKS_COND_T)
01172   extern ACE_Export
01173 #else
01174   ACE_NAMESPACE_INLINE_FUNCTION
01175 #endif /* ACE_LACKS_COND_T */
01176   int cond_wait (ACE_cond_t *cv,
01177                  ACE_mutex_t *m);
01178 
01179 # if defined (ACE_WIN32) && defined (ACE_HAS_WTHREADS)
01180 #   if defined (ACE_LACKS_COND_T)
01181   extern ACE_Export
01182 #   else
01183   ACE_NAMESPACE_INLINE_FUNCTION
01184 #   endif /* ACE_LACKS_COND_T */
01185   int cond_timedwait (ACE_cond_t *cv,
01186                       ACE_thread_mutex_t *m,
01187                       ACE_Time_Value *);
01188 
01189 #   if defined (ACE_LACKS_COND_T)
01190   extern ACE_Export
01191 #   else
01192   ACE_NAMESPACE_INLINE_FUNCTION
01193 #   endif /* ACE_LACKS_COND_T */
01194   int cond_wait (ACE_cond_t *cv,
01195                  ACE_thread_mutex_t *m);
01196 # endif /* ACE_WIN32 && ACE_HAS_WTHREADS */
01197 
01198   //@{ @name A set of wrappers for auto-reset and manual events.
01199 
01200   extern ACE_Export
01201   int event_destroy (ACE_event_t *event);
01202 
01203   extern ACE_Export
01204   int event_init (ACE_event_t *event,
01205                   int manual_reset = 0,
01206                   int initial_state = 0,
01207                   int type = ACE_DEFAULT_SYNCH_TYPE,
01208                   const char *name = 0,
01209                   void *arg = 0,
01210                   LPSECURITY_ATTRIBUTES sa = 0);
01211 
01212 # if defined (ACE_HAS_WCHAR)
01213   ACE_NAMESPACE_INLINE_FUNCTION
01214   int event_init (ACE_event_t *event,
01215                   int manual_reset,
01216                   int initial_state,
01217                   int type,
01218                   const wchar_t *name,
01219                   void *arg = 0,
01220                   LPSECURITY_ATTRIBUTES sa = 0);
01221 # endif /* ACE_HAS_WCHAR */
01222 
01223   extern ACE_Export
01224   int event_pulse (ACE_event_t *event);
01225 
01226   extern ACE_Export
01227   int event_reset (ACE_event_t *event);
01228 
01229   extern ACE_Export
01230   int event_signal (ACE_event_t *event);
01231 
01232   extern ACE_Export
01233   int event_timedwait (ACE_event_t *event,
01234                        ACE_Time_Value *timeout,
01235                        int use_absolute_time = 1);
01236 
01237   extern ACE_Export
01238   int event_wait (ACE_event_t *event);
01239 
01240   //@}
01241 
01242   extern ACE_Export
01243   int lwp_getparams (ACE_Sched_Params &);
01244 
01245   extern ACE_Export
01246   int lwp_setparams (const ACE_Sched_Params &);
01247 
01248 
01249   //@{ @name A set of wrappers for mutex locks.
01250 
01251   extern ACE_Export
01252   int mutex_destroy (ACE_mutex_t *m);
01253 
01254   extern ACE_Export
01255   int mutex_init (ACE_mutex_t *m,
01256                   int lock_scope = ACE_DEFAULT_SYNCH_TYPE,
01257                   const char *name = 0,
01258                   ACE_mutexattr_t *arg = 0,
01259                   LPSECURITY_ATTRIBUTES sa = 0,
01260                   int lock_type = 0);
01261 
01262 #if defined (ACE_HAS_WCHAR)
01263   extern ACE_Export
01264   int mutex_init (ACE_mutex_t *m,
01265                   int lock_scope,
01266                   const wchar_t *name,
01267                   ACE_mutexattr_t *arg = 0,
01268                   LPSECURITY_ATTRIBUTES sa = 0,
01269                   int lock_type = 0);
01270 #endif /* ACE_HAS_WCHAR */
01271 
01272   /// Win32 note: Abandoned mutexes are not treated differently. 0 is
01273   /// returned since the calling thread does get the ownership.
01274   extern ACE_Export
01275   int mutex_lock (ACE_mutex_t *m);
01276 
01277   /// This method is only implemented for Win32.  For abandoned
01278   /// mutexes, <abandoned> is set to 1 and 0 is returned.
01279   extern ACE_Export
01280   int mutex_lock (ACE_mutex_t *m,
01281                   int &abandoned);
01282 
01283   /**
01284    * This method attempts to acquire a lock, but gives up if the lock
01285    * has not been acquired by the given time.  If the lock is not
01286    * acquired within the given amount of time, then this method
01287    * returns -1 with an <ETIME> errno on platforms that actually
01288    * support timed mutexes.  The timeout should be an absolute time.
01289    * Note that the mutex should not be a recursive one, i.e., it
01290    * should only be a standard mutex or an error checking mutex since
01291    * some implementations of this method don't support recursive
01292    * mutexes.  If you want to use a recursive mutex see the methods
01293    * below.
01294    */
01295   extern ACE_Export
01296   int mutex_lock (ACE_mutex_t *m,
01297                   const ACE_Time_Value &timeout);
01298 
01299   /**
01300    * If <timeout> == 0, calls <ACE_OS::mutex_lock(m)>.  Otherwise,
01301    * this method attempts to acquire a lock, but gives up if the lock
01302    * has not been acquired by the given time, in which case it returns
01303    * -1 with an <ETIME> errno on platforms that actually support timed
01304    * mutexes.  The timeout should be an absolute time.  Note that the
01305    * mutex should not be a recursive one, i.e., it should only be a
01306    * standard mutex or an error checking mutex since some
01307    * implementations of this method don't support recursive mutexes.
01308    * If you want to use a recursive mutex see the methods below.
01309    */
01310   ACE_NAMESPACE_INLINE_FUNCTION
01311   int mutex_lock (ACE_mutex_t *m,
01312                   const ACE_Time_Value *timeout);
01313 
01314   /// Handle asynchronous thread cancellation cleanup.
01315   extern ACE_Export
01316   void mutex_lock_cleanup (void *mutex);
01317 
01318   /// Win32 note: Abandoned mutexes are not treated differently. 0 is
01319   /// returned since the calling thread does get the ownership.
01320   extern ACE_Export
01321   int mutex_trylock (ACE_mutex_t *m);
01322 
01323   /// This method is only implemented for Win32.  For abandoned
01324   /// mutexes, <abandoned> is set to 1 and 0 is returned.
01325   extern ACE_Export
01326   int mutex_trylock (ACE_mutex_t *m,
01327                      int &abandoned);
01328 
01329   extern ACE_Export
01330   int mutex_unlock (ACE_mutex_t *m);
01331 
01332   //@}
01333 
01334   /// Low-level interface to <priocntl>(2).
01335   /**
01336    * Can't call the following priocntl, because that's a macro on
01337    * Solaris.
01338    */
01339   ACE_NAMESPACE_INLINE_FUNCTION
01340   long priority_control (ACE_idtype_t, ACE_id_t, int, void *);
01341 
01342   //@{ @name A set of wrappers for recursive mutex locks.
01343 
01344   // These two methods are primarily in support of
01345   // ACE_Condition<ACE_Recursive_Thread_Mutex> and should probably not
01346   // be called outside that context.
01347   ACE_NAMESPACE_INLINE_FUNCTION
01348   int recursive_mutex_cond_unlock (ACE_recursive_thread_mutex_t *m,
01349                                    ACE_recursive_mutex_state &state);
01350 
01351   ACE_NAMESPACE_INLINE_FUNCTION
01352   void recursive_mutex_cond_relock (ACE_recursive_thread_mutex_t *m,
01353                                     ACE_recursive_mutex_state &state);
01354 
01355   ACE_NAMESPACE_INLINE_FUNCTION
01356   int recursive_mutex_destroy (ACE_recursive_thread_mutex_t *m);
01357 
01358   ACE_NAMESPACE_INLINE_FUNCTION
01359   int recursive_mutex_init (ACE_recursive_thread_mutex_t *m,
01360                             const ACE_TCHAR *name = 0,
01361                             ACE_mutexattr_t *arg = 0,
01362                             LPSECURITY_ATTRIBUTES sa = 0);
01363 
01364   ACE_NAMESPACE_INLINE_FUNCTION
01365   int recursive_mutex_lock (ACE_recursive_thread_mutex_t *m);
01366 
01367   ACE_NAMESPACE_INLINE_FUNCTION
01368   int recursive_mutex_lock (ACE_recursive_thread_mutex_t *m,
01369                             const ACE_Time_Value &timeout);
01370 
01371   ACE_NAMESPACE_INLINE_FUNCTION
01372   int recursive_mutex_lock (ACE_recursive_thread_mutex_t *m,
01373                             const ACE_Time_Value *timeout);
01374 
01375   ACE_NAMESPACE_INLINE_FUNCTION
01376   int recursive_mutex_trylock (ACE_recursive_thread_mutex_t *m);
01377 
01378   ACE_NAMESPACE_INLINE_FUNCTION
01379   int recursive_mutex_unlock (ACE_recursive_thread_mutex_t *m);
01380 
01381   //@}
01382 
01383 
01384   //@{ @name A set of wrappers for readers/writer locks.
01385 
01386   ACE_NAMESPACE_INLINE_FUNCTION
01387   int rw_rdlock (ACE_rwlock_t *rw);
01388 
01389   ACE_NAMESPACE_INLINE_FUNCTION
01390   int rw_tryrdlock (ACE_rwlock_t *rw);
01391 
01392   ACE_NAMESPACE_INLINE_FUNCTION
01393   int rw_trywrlock (ACE_rwlock_t *rw);
01394 
01395   ACE_NAMESPACE_INLINE_FUNCTION
01396   int rw_trywrlock_upgrade (ACE_rwlock_t *rw);
01397 
01398   ACE_NAMESPACE_INLINE_FUNCTION
01399   int rw_unlock (ACE_rwlock_t *rw);
01400 
01401   ACE_NAMESPACE_INLINE_FUNCTION
01402   int rw_wrlock (ACE_rwlock_t *rw);
01403 
01404   ACE_NAMESPACE_INLINE_FUNCTION
01405   int rwlock_destroy (ACE_rwlock_t *rw);
01406 
01407   extern ACE_Export
01408   int rwlock_init (ACE_rwlock_t *rw,
01409                    int type = ACE_DEFAULT_SYNCH_TYPE,
01410                    const ACE_TCHAR *name = 0,
01411                    void *arg = 0);
01412 
01413   //@}
01414 
01415   //@{ @name Thread scheduler interface.
01416   /// Set scheduling parameters.  An id of ACE_SELF indicates, e.g.,
01417   /// set the parameters on the calling thread.
01418   extern ACE_Export
01419   int sched_params (const ACE_Sched_Params &, ACE_id_t id = ACE_SELF);
01420   //@}
01421 
01422   /// Find the schedling class ID that corresponds to the class name.
01423   extern ACE_Export
01424   int scheduling_class (const char *class_name, ACE_id_t &);
01425 
01426   //@{ @name A set of wrappers for semaphores.
01427 
01428   ACE_NAMESPACE_INLINE_FUNCTION
01429   int sema_destroy (ACE_sema_t *s);
01430 
01431   ACE_NAMESPACE_INLINE_FUNCTION
01432   int sema_init (ACE_sema_t *s,
01433                  u_int count,
01434                  int type = ACE_DEFAULT_SYNCH_TYPE,
01435                  const char *name = 0,
01436                  void *arg = 0,
01437                  int max = 0x7fffffff,
01438                  LPSECURITY_ATTRIBUTES sa = 0);
01439 
01440 # if defined (ACE_HAS_WCHAR)
01441   ACE_NAMESPACE_INLINE_FUNCTION
01442   int sema_init (ACE_sema_t *s,
01443                  u_int count,
01444                  int type,
01445                  const wchar_t *name,
01446                  void *arg = 0,
01447                  int max = 0x7fffffff,
01448                  LPSECURITY_ATTRIBUTES sa = 0);
01449 # endif /* ACE_HAS_WCHAR */
01450 
01451   ACE_NAMESPACE_INLINE_FUNCTION
01452   int sema_post (ACE_sema_t *s);
01453 
01454   ACE_NAMESPACE_INLINE_FUNCTION
01455   int sema_post (ACE_sema_t *s,
01456                  u_int release_count);
01457 
01458   ACE_NAMESPACE_INLINE_FUNCTION
01459   int sema_trywait (ACE_sema_t *s);
01460 
01461   ACE_NAMESPACE_INLINE_FUNCTION
01462   int sema_wait (ACE_sema_t *s);
01463 
01464   ACE_NAMESPACE_INLINE_FUNCTION
01465   int sema_wait (ACE_sema_t *s,
01466                  ACE_Time_Value &tv);
01467 
01468   ACE_NAMESPACE_INLINE_FUNCTION
01469   int sema_wait (ACE_sema_t *s,
01470                  ACE_Time_Value *tv);
01471 
01472   //@}
01473 
01474   //@{ @name A set of wrappers for System V semaphores.
01475   ACE_NAMESPACE_INLINE_FUNCTION
01476   int semctl (int int_id,
01477               int semnum,
01478               int cmd,
01479               semun);
01480 
01481   ACE_NAMESPACE_INLINE_FUNCTION
01482   int semget (key_t key,
01483               int nsems,
01484               int flags);
01485 
01486   ACE_NAMESPACE_INLINE_FUNCTION
01487   int semop (int int_id,
01488              struct sembuf *sops,
01489              size_t nsops);
01490   //@}
01491 
01492   /// Friendly interface to <priocntl>(2).
01493   extern ACE_Export
01494   int set_scheduling_params (const ACE_Sched_Params &,
01495                              ACE_id_t id = ACE_SELF);
01496 
01497   ACE_NAMESPACE_INLINE_FUNCTION
01498   int sigtimedwait (const sigset_t *set,
01499                     siginfo_t *info,
01500                     const ACE_Time_Value *timeout);
01501 
01502   ACE_NAMESPACE_INLINE_FUNCTION
01503   int sigwait (sigset_t *set,
01504                int *sig = 0);
01505 
01506   ACE_NAMESPACE_INLINE_FUNCTION
01507   int sigwaitinfo (const sigset_t *set,
01508                    siginfo_t *info);
01509 
01510   ACE_NAMESPACE_INLINE_FUNCTION
01511   int thr_cancel (ACE_thread_t t_id);
01512 
01513   ACE_NAMESPACE_INLINE_FUNCTION
01514   int thr_cmp (ACE_hthread_t t1,
01515                ACE_hthread_t t2);
01516 
01517   // These are non-portable since they use ACE_thread_t and
01518   // ACE_hthread_t and will go away in a future release.
01519   ACE_NAMESPACE_INLINE_FUNCTION
01520   int thr_continue (ACE_hthread_t target_thread);
01521 
01522   /*
01523    * Creates a new thread having <flags> attributes and running <func>
01524    * with <args> (if <thread_adapter> is non-0 then <func> and <args>
01525    * are ignored and are obtained from <thread_adapter>).  <thr_id>
01526    * and <t_handle> are set to the thread's ID and handle (?),
01527    * respectively.  The thread runs at <priority> priority (see
01528    * below).
01529    *
01530    * The <flags> are a bitwise-OR of the following:
01531    * = BEGIN<INDENT>
01532    * THR_CANCEL_DISABLE, THR_CANCEL_ENABLE, THR_CANCEL_DEFERRED,
01533    * THR_CANCEL_ASYNCHRONOUS, THR_BOUND, THR_NEW_LWP, THR_DETACHED,
01534    * THR_SUSPENDED, THR_DAEMON, THR_JOINABLE, THR_SCHED_FIFO,
01535    * THR_SCHED_RR, THR_SCHED_DEFAULT, THR_EXPLICIT_SCHED,
01536    * THR_SCOPE_SYSTEM, THR_SCOPE_PROCESS
01537    * = END<INDENT>
01538    *
01539    * By default, or if <priority> is set to
01540    * ACE_DEFAULT_THREAD_PRIORITY, an "appropriate" priority value for
01541    * the given scheduling policy (specified in <flags}>, e.g.,
01542    * <THR_SCHED_DEFAULT>) is used.  This value is calculated
01543    * dynamically, and is the median value between the minimum and
01544    * maximum priority values for the given policy.  If an explicit
01545    * value is given, it is used.  Note that actual priority values are
01546    * EXTREMEMLY implementation-dependent, and are probably best
01547    * avoided.
01548    *
01549    * Note that <thread_adapter> is always deleted by <thr_create>,
01550    * therefore it must be allocated with global operator new.
01551    */
01552   extern ACE_Export
01553   int thr_create (ACE_THR_FUNC func,
01554                   void *args,
01555                   long flags,
01556                   ACE_thread_t *thr_id,
01557                   ACE_hthread_t *t_handle = 0,
01558                   long priority = ACE_DEFAULT_THREAD_PRIORITY,
01559                   void *stack = 0,
01560                   size_t stacksize = 0,
01561                   ACE_Base_Thread_Adapter *thread_adapter = 0);
01562 
01563   ACE_NAMESPACE_INLINE_FUNCTION
01564   int thr_equal (ACE_thread_t t1,
01565                  ACE_thread_t t2);
01566 
01567   extern ACE_Export
01568   void thr_exit (ACE_THR_FUNC_RETURN status = 0);
01569 
01570   ACE_NAMESPACE_INLINE_FUNCTION
01571   int thr_getconcurrency (void);
01572 
01573   ACE_NAMESPACE_INLINE_FUNCTION
01574   int thr_getprio (ACE_hthread_t id,
01575                    int &priority);
01576 
01577   ACE_NAMESPACE_INLINE_FUNCTION
01578   int thr_getprio (ACE_hthread_t id,
01579                    int &priority,
01580                    int &policy);
01581 
01582 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
01583   ACE_NAMESPACE_INLINE_FUNCTION
01584   /// for internal use only.  Applications should call thr_getspecific
01585   int thr_getspecific_native (ACE_OS_thread_key_t key,
01586                        void **data);
01587 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
01588 
01589   ACE_NAMESPACE_INLINE_FUNCTION
01590   int thr_getspecific (ACE_thread_key_t key,
01591                        void **data);
01592 
01593 #if defined (ACE_VXWORKS)
01594   extern ACE_Export
01595 #else
01596   ACE_NAMESPACE_INLINE_FUNCTION
01597 #endif /* ACE_VXWORKS */
01598   int thr_join (ACE_hthread_t waiter_id,
01599                 ACE_THR_FUNC_RETURN *status);
01600 
01601 #if defined (ACE_VXWORKS)
01602   extern ACE_Export
01603 #else
01604   ACE_NAMESPACE_INLINE_FUNCTION
01605 #endif /* ACE_VXWORKS */
01606   int thr_join (ACE_thread_t waiter_id,
01607                 ACE_thread_t *thr_id,
01608                 ACE_THR_FUNC_RETURN *status);
01609 
01610   /**
01611    * Get the thread affinity
01612    *
01613    * @param thr_id For NPTL-threads, when ACE_HAS_PTHREAD_SETAFFINITY_NP
01614    * defined, this is the thread-id. For linux-threads, when
01615    * ACE_HAS_SCHED_SETAFFINITY defined, it expects a process-id. Since for
01616    * linux-threads a thread is seen as a process, it does the job.
01617    * @param cpu_set_size The size of the cpu_mask
01618    * @param cpu_mask Is a bitmask of CPUs to bind to, e.g value 1 binds the
01619    * thread to the "CPU 0", etc
01620    */
01621   extern ACE_Export
01622   int thr_get_affinity (ACE_hthread_t id,
01623                         size_t cpu_set_size,
01624                         cpu_set_t * cpu_mask);
01625 
01626 
01627   /**
01628    * Set the thread affinity
01629    *
01630    * @param thr_id For NPTL-threads, when ACE_HAS_PTHREAD_SETAFFINITY_NP
01631    * defined, this is the thread-id. For linux-threads, when
01632    * ACE_HAS_SCHED_SETAFFINITY defined, it expects a process-id. Since for
01633    * linux-threads a thread is seen as a process, it does the job.
01634    * @param cpu_set_size The size of the cpu_mask
01635    * @param cpu_mask Is a bitmask of CPUs to bind to, e.g value 1 binds the
01636    * thread to the "CPU 0", etc
01637    */
01638   extern ACE_Export
01639   int thr_set_affinity (ACE_hthread_t thr_id,
01640                         size_t cpu_set_size,
01641                         const cpu_set_t * cpu_mask);
01642 
01643   /**
01644    * @note the "inst" arg is deprecated.  It will be ignored.
01645    */
01646   extern ACE_Export
01647   int thr_key_detach (ACE_thread_key_t key, void * inst);
01648 
01649   extern ACE_Export
01650   int thr_key_used (ACE_thread_key_t key);
01651 
01652 # if defined (ACE_HAS_THR_C_DEST)
01653 #   if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
01654   /// @internal Applications should call thr_keycreate
01655   extern ACE_Export
01656   int thr_keycreate_native (ACE_OS_thread_key_t *key,
01657                      ACE_THR_C_DEST);
01658 #   endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
01659 
01660   /**
01661    * @note the "inst" arge is deprecated.  It will be ignored.
01662    */
01663   extern ACE_Export
01664   int thr_keycreate (ACE_thread_key_t *key,
01665                      ACE_THR_C_DEST,
01666                      void *inst = 0);
01667 # else
01668 #   if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
01669   /// @internal Applications should call thr_keycreate instead
01670   extern ACE_Export
01671   int thr_keycreate_native (ACE_OS_thread_key_t *key,
01672                      ACE_THR_DEST);
01673 #   endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
01674   /**
01675    * @note the "inst" arge is deprecated.  It will be ignored.
01676    */
01677   extern ACE_Export
01678   int thr_keycreate (ACE_thread_key_t *key,
01679                      ACE_THR_DEST,
01680                      void *inst = 0);
01681 
01682 # endif /* ACE_HAS_THR_C_DEST */
01683 
01684 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
01685   /// @internal  applications should call thr_keyfree instead
01686   extern ACE_Export
01687   int thr_keyfree_native (ACE_OS_thread_key_t key);
01688 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
01689 
01690   extern ACE_Export
01691   int thr_keyfree (ACE_thread_key_t key);
01692 
01693   ACE_NAMESPACE_INLINE_FUNCTION
01694   int thr_kill (ACE_thread_t thr_id,
01695                 int signum);
01696 
01697   ACE_NAMESPACE_INLINE_FUNCTION
01698   size_t thr_min_stack (void);
01699 
01700   ACE_NAMESPACE_INLINE_FUNCTION
01701   ACE_thread_t thr_self (void);
01702 
01703   ACE_NAMESPACE_INLINE_FUNCTION
01704   void thr_self (ACE_hthread_t &);
01705 
01706   ACE_NAMESPACE_INLINE_FUNCTION
01707   int thr_setcancelstate (int new_state,
01708                           int *old_state);
01709 
01710   ACE_NAMESPACE_INLINE_FUNCTION
01711   int thr_setcanceltype (int new_type,
01712                          int *old_type);
01713 
01714   ACE_NAMESPACE_INLINE_FUNCTION
01715   int thr_setconcurrency (int hint);
01716 
01717   ACE_NAMESPACE_INLINE_FUNCTION
01718   int thr_setprio (ACE_hthread_t ht_id,
01719                    int priority,
01720                    int policy = -1);
01721 
01722   extern ACE_Export
01723   int thr_setprio (const ACE_Sched_Priority prio);
01724 
01725 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
01726   /// @internal Applications should call thr_setspecific
01727   extern ACE_Export
01728   int thr_setspecific_native (ACE_OS_thread_key_t key,
01729                               void *data);
01730 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
01731 
01732   extern ACE_Export
01733   int thr_setspecific (ACE_thread_key_t key,
01734                        void *data);
01735 
01736   ACE_NAMESPACE_INLINE_FUNCTION
01737   int thr_sigsetmask (int how,
01738                       const sigset_t *nsm,
01739                       sigset_t *osm);
01740 
01741   ACE_NAMESPACE_INLINE_FUNCTION
01742   int thr_suspend (ACE_hthread_t target_thread);
01743 
01744   ACE_NAMESPACE_INLINE_FUNCTION
01745   void thr_testcancel (void);
01746 
01747   ACE_NAMESPACE_INLINE_FUNCTION
01748   void thr_yield (void);
01749 
01750   //@{ @name A set of wrappers for mutex locks that only work within a single process.
01751 
01752   ACE_NAMESPACE_INLINE_FUNCTION
01753   int thread_mutex_destroy (ACE_thread_mutex_t *m);
01754 
01755   ACE_NAMESPACE_INLINE_FUNCTION
01756   int thread_mutex_init (ACE_thread_mutex_t *m,
01757                          int lock_type = 0,
01758                          const char *name = 0,
01759                          ACE_mutexattr_t *arg = 0);
01760 
01761 #if defined (ACE_HAS_WCHAR)
01762   ACE_NAMESPACE_INLINE_FUNCTION
01763   int thread_mutex_init (ACE_thread_mutex_t *m,
01764                          int lock_type,
01765                          const wchar_t *name,
01766                          ACE_mutexattr_t *arg = 0);
01767 #endif /* ACE_HAS_WCHAR */
01768 
01769   ACE_NAMESPACE_INLINE_FUNCTION
01770   int thread_mutex_lock (ACE_thread_mutex_t *m);
01771 
01772   ACE_NAMESPACE_INLINE_FUNCTION
01773   int thread_mutex_lock (ACE_thread_mutex_t *m,
01774                          const ACE_Time_Value &timeout);
01775 
01776   ACE_NAMESPACE_INLINE_FUNCTION
01777   int thread_mutex_lock (ACE_thread_mutex_t *m,
01778                          const ACE_Time_Value *timeout);
01779 
01780   ACE_NAMESPACE_INLINE_FUNCTION
01781   int thread_mutex_trylock (ACE_thread_mutex_t *m);
01782 
01783   ACE_NAMESPACE_INLINE_FUNCTION
01784   int thread_mutex_unlock (ACE_thread_mutex_t *m);
01785 
01786   //@}
01787 
01788   /**
01789    * This method uses process id and object pointer to come up with a
01790    * machine wide unique name.  The process ID will provide uniqueness
01791    * between processes on the same machine. The "this" pointer of the
01792    * <object> will provide uniqueness between other "live" objects in
01793    * the same process. The uniqueness of this name is therefore only
01794    * valid for the life of <object>.
01795    */
01796   extern ACE_Export
01797   void unique_name (const void *object,
01798                     char *name,
01799                     size_t length);
01800 #if defined (ACE_USES_WCHAR)
01801   extern ACE_Export
01802   void unique_name (const void *object,
01803                     wchar_t *name,
01804                     size_t length);
01805 #endif /* ACE_USES_WCHAR */
01806 } /* namespace ACE_OS */
01807 
01808 ACE_END_VERSIONED_NAMESPACE_DECL
01809 
01810 #if !defined (ACE_WIN32)
01811 
01812 extern "C"
01813 {
01814   typedef struct
01815   {
01816 #if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
01817     (!defined (ACE_USES_FIFO_SEM) && \
01818       (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
01819     /// Protect critical section.
01820     ACE_mutex_t lock_;
01821     /// Keeps track of waiters.
01822     ACE_cond_t condition_;
01823 #else
01824 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_MUTEXATTR_PSHARED)) || \
01825      (!defined (ACE_USES_FIFO_SEM) && (!defined (ACE_HAS_POSIX_SEM) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
01826     /// Protect critical section.
01827     ACE_mutex_t lock_;
01828 # endif
01829 #endif
01830 
01831     /// Object type.
01832     int type_;
01833 
01834     /// Specifies if this is an auto- or manual-reset event.
01835     int manual_reset_;
01836 
01837     /// "True" if signaled.
01838     int is_signaled_;
01839 
01840     /// Special bool for auto_events alone
01841     /**
01842      * The semantics of auto events forces us to introduce this extra
01843      * variable to ensure that the thread is not woken up
01844      * spuriously. Please see event_wait and event_timedwait () to see
01845      * how this is used for auto_events. Theoretically this is a hack
01846      * that needs revisiting after x.4
01847      */
01848     bool auto_event_signaled_;
01849 
01850     /// Number of waiting threads.
01851     unsigned long waiting_threads_;
01852 
01853     /// Signal count
01854     unsigned long signal_count_;
01855   } ACE_eventdata_t;
01856 }
01857 
01858 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
01859 
01860 /**
01861  * @class ACE_event_t
01862  *
01863  * @brief Wrapper for NT events on UNIX.
01864  */
01865 class ACE_Export ACE_event_t
01866 {
01867   friend int ACE_OS::event_init(ACE_event_t*, int, int, int, const char*, void*,int);
01868   friend int ACE_OS::event_destroy(ACE_event_t*);
01869   friend int ACE_OS::event_wait(ACE_event_t*);
01870   friend int ACE_OS::event_timedwait(ACE_event_t*, ACE_Time_Value*, int);
01871   friend int ACE_OS::event_signal(ACE_event_t*);
01872   friend int ACE_OS::event_pulse(ACE_event_t*);
01873   friend int ACE_OS::event_reset(ACE_event_t*);
01874 protected:
01875 
01876   /// Event name if process shared.
01877   char* name_;
01878 
01879   /// Event data
01880   ACE_eventdata_t* eventdata_;
01881 
01882 #if (!defined (ACE_HAS_PTHREADS) || !defined (_POSIX_THREAD_PROCESS_SHARED) || defined (ACE_LACKS_CONDATTR_PSHARED)) && \
01883   (defined (ACE_USES_FIFO_SEM) || \
01884     (defined (ACE_HAS_POSIX_SEM) && defined (ACE_HAS_POSIX_SEM_TIMEOUT) && !defined (ACE_LACKS_NAMED_POSIX_SEM)))
01885   /// Keeps track of waiters.
01886   ACE_sema_t semaphore_;
01887 
01888 # if (!defined (ACE_HAS_PTHREADS) || !defined (_POSIX_THREAD_PROCESS_SHARED) || defined (ACE_LACKS_MUTEXATTR_PSHARED)) && \
01889      (defined (ACE_USES_FIFO_SEM) || (defined (ACE_HAS_POSIX_SEM) && !defined (ACE_LACKS_NAMED_POSIX_SEM)))
01890     /// Protect critical section.
01891   ACE_sema_t lock_;
01892 # endif
01893 #endif
01894 };
01895 
01896 ACE_END_VERSIONED_NAMESPACE_DECL
01897 
01898 #endif /* ACE_WIN32 */
01899 
01900 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
01901 
01902 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
01903 
01904 /**
01905  * @class ACE_OS_Thread_Mutex_Guard
01906  *
01907  * This data structure is meant to be used within an ACE_OS
01908  * function.  It performs automatic aquisition and release of
01909  * an ACE_thread_mutex_t.
01910  *
01911  * If an object of this class is instantiated before ACE_Object_Manager is
01912  * initialized, it will not do anything. This is because this class is
01913  * used only with the ACE_OS_GUARD macro which is passing a reference to
01914  * one of the preallocated Object Manager locks. If the object manager
01915  * hasn't been initialized yet, the lock reference is bogus. This is an
01916  * acceptable tradeoff since in cases where the lock reference is bogus,
01917  * there isn't multithreaded access. Please see detailed comments in
01918  * Object_Manager.h for further information.
01919  *
01920  * For internal use only by ACE_OS.
01921  */
01922 class ACE_OS_Thread_Mutex_Guard
01923 {
01924 public:
01925   /// Implicitly and automatically acquire the lock.
01926   ACE_OS_Thread_Mutex_Guard (ACE_thread_mutex_t &m);
01927 
01928   /// Implicitly release the lock.
01929   ~ACE_OS_Thread_Mutex_Guard (void);
01930 
01931   /// Explicitly acquire the lock.
01932   int acquire (void);
01933 
01934   /// Explicitly release the lock.
01935   int release (void);
01936 
01937 protected:
01938   /// Reference to the mutex.
01939   ACE_thread_mutex_t &lock_;
01940 
01941   /// Keeps track of whether we acquired the lock or failed.
01942   int owner_;
01943 
01944   // = Prevent assignment and initialization.
01945   ACE_OS_Thread_Mutex_Guard &operator= (const ACE_OS_Thread_Mutex_Guard &);
01946   ACE_OS_Thread_Mutex_Guard (const ACE_OS_Thread_Mutex_Guard &);
01947 };
01948 
01949 /**
01950  * @class ACE_OS_Recursive_Thread_Mutex_Guard
01951  *
01952  * @brief For internal use only by ACE_OS.
01953  *
01954  * This data structure is meant to be used within an ACE_OS
01955  * function.  It performs automatic aquisition and release of
01956  * an ACE_recursive_thread_mutex_t.
01957  *
01958  * If an object of this class is instantiated before ACE_Object_Manager is
01959  * initialized, it will not do anything. This is because this class is
01960  * used only with the ACE_TSS_GUARD macro which is passing a reference to
01961  * one of the preallocated Object Manager locks. If the object manager
01962  * hasn't been initialized yet, the lock reference is bogus. This is an
01963  * acceptable tradeoff since in cases where the lock reference is bogus,
01964  * there isn't multithreaded access. Please see detailed comments in
01965  * Object_Manager.h for further information.
01966  */
01967 class ACE_OS_Recursive_Thread_Mutex_Guard
01968 {
01969 public:
01970   /// Implicitly and automatically acquire the lock.
01971   ACE_OS_Recursive_Thread_Mutex_Guard (ACE_recursive_thread_mutex_t &m);
01972 
01973   /// Implicitly release the lock.
01974   ~ACE_OS_Recursive_Thread_Mutex_Guard (void);
01975 
01976   /// Explicitly acquire the lock.
01977   int acquire (void);
01978 
01979   /// Explicitly release the lock.
01980   int release (void);
01981 
01982 protected:
01983   /// Reference to the mutex.
01984   ACE_recursive_thread_mutex_t &lock_;
01985 
01986   /// Keeps track of whether we acquired the lock or failed.
01987   int owner_;
01988 
01989   // = Prevent assignment and initialization.
01990   ACE_OS_Recursive_Thread_Mutex_Guard &operator= (
01991     const ACE_OS_Recursive_Thread_Mutex_Guard &);
01992   ACE_OS_Recursive_Thread_Mutex_Guard (
01993     const ACE_OS_Recursive_Thread_Mutex_Guard &);
01994 };
01995 
01996 ACE_END_VERSIONED_NAMESPACE_DECL
01997 
01998 // used in time and unistd
01999 # define ACE_OS_GUARD \
02000   ACE_OS_Thread_Mutex_Guard ace_os_guard__ (*(ACE_thread_mutex_t *) \
02001     ACE_OS_Object_Manager::preallocated_object[ \
02002       ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]);
02003 
02004 // used in Thread
02005 # define ACE_TSS_CLEANUP_GUARD \
02006   ACE_OS_Recursive_Thread_Mutex_Guard ace_tss_cleanup_guard__ (*(ACE_recursive_thread_mutex_t *) \
02007     ACE_OS_Object_Manager::preallocated_object[ \
02008       ACE_OS_Object_Manager::ACE_TSS_CLEANUP_LOCK]);
02009 
02010 // used in Thread
02011 # define ACE_TSS_BASE_GUARD \
02012   ACE_OS_Recursive_Thread_Mutex_Guard ace_tss_base_guard__ (*(ACE_recursive_thread_mutex_t *) \
02013     ACE_OS_Object_Manager::preallocated_object[ \
02014       ACE_OS_Object_Manager::ACE_TSS_BASE_LOCK]);
02015 
02016 #else  /* ! ACE_MT_SAFE */
02017 # define ACE_OS_GUARD
02018 # define ACE_TSS_CLEANUP_GUARD
02019 # define ACE_TSS_BASE_GUARD
02020 #endif /* ! ACE_MT_SAFE */
02021 
02022 # if defined (ACE_HAS_INLINED_OSCALLS)
02023 #   if defined (ACE_INLINE)
02024 #     undef ACE_INLINE
02025 #   endif /* ACE_INLINE */
02026 #   define ACE_INLINE inline
02027 #   include "ace/OS_NS_Thread.inl"
02028 # endif /* ACE_HAS_INLINED_OSCALLS */
02029 
02030 # include /**/ "ace/post.h"
02031 #endif /* ACE_OS_NS_THREAD_H */

Generated on Thu Nov 9 09:41:58 2006 for ACE by doxygen 1.3.6