3 //=============================================================================
7 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
8 * @author Jesper S. M|ller<stophph@diku.dk>
9 * @author and a cast of thousands...
11 //=============================================================================
13 #ifndef ACE_OS_NS_THREAD_H
14 # define ACE_OS_NS_THREAD_H
16 # include /**/ "ace/pre.h"
18 # include "ace/config-all.h"
20 # if !defined (ACE_LACKS_PRAGMA_ONCE)
22 # endif /* ACE_LACKS_PRAGMA_ONCE */
24 # include "ace/Global_Macros.h"
25 # include "ace/Basic_Types.h"
26 # include "ace/Default_Constants.h"
27 # include "ace/os_include/os_pthread.h"
28 # include "ace/os_include/os_sched.h"
29 # include "ace/Base_Thread_Adapter.h"
30 # include "ace/os_include/sys/os_sem.h"
31 # include "ace/os_include/os_semaphore.h"
32 # include "ace/OS_Memory.h"
33 # include "ace/OS_NS_signal.h"
34 # include "ace/ACE_export.h"
35 # include "ace/Object_Manager_Base.h"
37 #if defined (ACE_HAS_TSS_EMULATION) && !defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
38 # if defined (ACE_HAS_VXTHREADS) && !defined (_WRS_CONFIG_SMP) && !defined (INCLUDE_AMP_CPU)
39 # include "taskVarLib.h" /* used by VxWorks < 6.9 */
40 # endif /* VxWorks and ! SMP */
43 # if defined (ACE_EXPORT_MACRO)
44 # undef ACE_EXPORT_MACRO
46 # define ACE_EXPORT_MACRO ACE_Export
48 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
50 # if defined (ACE_WIN32)
51 typedef DWORD ACE_thread_t
;
52 typedef HANDLE ACE_hthread_t
;
53 // Native TSS key type
54 typedef DWORD ACE_OS_thread_key_t
;
55 // Application TSS key type (use this type except in TSS Emulation)
56 # if defined (ACE_HAS_TSS_EMULATION)
57 typedef u_int ACE_thread_key_t
;
58 # else /* ! ACE_HAS_TSS_EMULATION */
59 typedef ACE_OS_thread_key_t ACE_thread_key_t
;
60 # endif /* ! ACE_HAS_TSS_EMULATION */
61 # endif /* ACE_WIN32 */
63 ACE_END_VERSIONED_NAMESPACE_DECL
65 # if !defined (ACE_HAS_POSIX_SEM) && defined (ACE_USES_FIFO_SEM)
75 #endif /* !ACE_HAS_POSIX_SEM && ACE_USES_FIFO_SEM */
77 # if defined (ACE_HAS_THREADS)
79 # define ACE_SCOPE_PROCESS 0
80 # define ACE_SCOPE_LWP 1
81 # define ACE_SCOPE_THREAD 2
83 # if !defined (ACE_HAS_PTHREADS)
84 # define ACE_SCHED_OTHER 0
85 # define ACE_SCHED_FIFO 1
86 # define ACE_SCHED_RR 2
87 # endif /* ! ACE_HAS_PTHREADS */
89 # if defined (ACE_VXWORKS)
90 # include /**/ <sysLib.h> // for sysClkRateGet()
91 # include /**/ <types/vxTypes.h>
92 # if !defined (__RTP__)
93 # include /**/ <taskLib.h>
94 # include /**/ <taskHookLib.h>
97 // make sure these are included for VXWORKS.
98 // @todo move these to a common place, perhaps the top of the file.
99 # include "ace/os_include/os_fcntl.h"
100 # include "ace/os_include/os_netdb.h"
101 # include "ace/os_include/os_semaphore.h"
102 # include "ace/os_include/os_signal.h"
103 # include "ace/os_include/os_stdio.h"
104 # include "ace/os_include/os_stdlib.h"
105 # include "ace/os_include/os_stropts.h"
106 # include "ace/os_include/os_unistd.h"
107 # include "ace/os_include/arpa/os_inet.h"
108 # include "ace/os_include/sys/os_select.h"
109 # include "ace/os_include/sys/os_socket.h"
111 // task options: the other options are either obsolete, internal, or for
112 // Fortran or Ada support
113 # define VX_UNBREAKABLE 0x0002 /* breakpoints ignored */
114 # if !defined (VX_FP_TASK)
115 # define VX_FP_TASK 0x0008 /* floating point coprocessor */
117 # define VX_PRIVATE_ENV 0x0080 /* private environment support */
118 # define VX_NO_STACK_FILL 0x0100 /* do not stack fill for
121 # define THR_CANCEL_DISABLE 0
122 # define THR_CANCEL_ENABLE 0
123 # define THR_CANCEL_DEFERRED 0
124 # define THR_CANCEL_ASYNCHRONOUS 0
126 # define THR_NEW_LWP 0
127 # define THR_DETACHED 0
128 # define THR_SUSPENDED 0
129 # define THR_DAEMON 0
130 # define THR_JOINABLE 0
131 # define THR_SCHED_FIFO 0
132 # define THR_SCHED_RR 0
133 # define THR_SCHED_DEFAULT 0
134 # define THR_INHERIT_SCHED 0
135 # define THR_EXPLICIT_SCHED 0
136 # define THR_SCHED_IO 0
137 # define THR_SCOPE_SYSTEM 0
138 # define THR_SCOPE_PROCESS 0
139 # define USYNC_THREAD 0
140 # define USYNC_PROCESS 1 /* It's all global on VxWorks
141 (without MMU option). */
143 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
145 typedef SEM_ID ACE_mutex_t
;
146 // Implement ACE_thread_mutex_t with ACE_mutex_t because there's just
148 typedef ACE_mutex_t ACE_thread_mutex_t
;
149 # if !defined (ACE_HAS_POSIX_SEM)
150 // Use VxWorks semaphores, wrapped ...
153 /// Semaphore handle. This is allocated by VxWorks.
156 /// Name of the semaphore: always NULL with VxWorks.
159 # endif /* !ACE_HAS_POSIX_SEM */
160 typedef ACE_VX_TASK_ID ACE_thread_t
;
161 typedef ACE_VX_TASK_ID ACE_hthread_t
;
162 // Key type: the ACE TSS emulation requires the key type be unsigned,
163 // for efficiency. (Current POSIX implementation use u_int, so the
164 // ACE TSS emulation is compatible with them.)
165 // Native TSS key type
166 typedef u_int ACE_OS_thread_key_t
;
167 // Application TSS key type (use this type except in TSS Emulation)
168 # if defined (ACE_HAS_TSS_EMULATION)
169 typedef u_int ACE_thread_key_t
;
170 # else /* ! ACE_HAS_TSS_EMULATION */
171 typedef ACE_OS_thread_key_t ACE_thread_key_t
;
172 # endif /* ! ACE_HAS_TSS_EMULATION */
174 ACE_END_VERSIONED_NAMESPACE_DECL
176 # elif defined (ACE_HAS_WTHREADS)
178 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
180 typedef CRITICAL_SECTION ACE_thread_mutex_t
;
184 /// Either USYNC_THREAD or USYNC_PROCESS
189 CRITICAL_SECTION thr_mutex_
;
193 // Wrapper for NT Events.
194 typedef HANDLE ACE_event_t
;
196 # if defined (ACE_WIN32)
197 typedef HANDLE ACE_sema_t
;
198 # endif /* defined (ACE_WIN32) */
200 ACE_END_VERSIONED_NAMESPACE_DECL
202 // These need to be different values, neither of which can be 0...
203 # define USYNC_THREAD 1
204 # define USYNC_PROCESS 2
206 # define THR_CANCEL_DISABLE 0
207 # define THR_CANCEL_ENABLE 0
208 # define THR_CANCEL_DEFERRED 0
209 # define THR_CANCEL_ASYNCHRONOUS 0
210 # define THR_DETACHED 0x02000000 /* ignore in most places */
211 # define THR_BOUND 0 /* ignore in most places */
212 # define THR_NEW_LWP 0 /* ignore in most places */
213 # define THR_DAEMON 0 /* ignore in most places */
214 # define THR_JOINABLE 0 /* ignore in most places */
215 # define THR_SUSPENDED CREATE_SUSPENDED
216 # if !defined (STACK_SIZE_PARAM_IS_A_RESERVATION)
217 # define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
218 # endif /* STACK_SIZE_PARAM_IS_A_RESERVATION */
219 # define THR_USE_AFX 0x01000000
220 # define THR_SCHED_FIFO 0
221 # define THR_SCHED_RR 0
222 # define THR_SCHED_DEFAULT 0
223 # define THR_INHERIT_SCHED 0
224 # define THR_EXPLICIT_SCHED 0
225 # define THR_SCOPE_PROCESS 0
226 # define THR_SCOPE_SYSTEM 0
227 # endif /* ACE_HAS_PTHREADS / STHREADS / VXWORKS / WTHREADS **********/
229 # if defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
231 typedef CONDITION_VARIABLE ACE_cond_t
;
233 # elif defined (ACE_LACKS_COND_T)
235 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
240 * @brief This structure is used to implement condition variables on
241 * platforms that lack it natively, such as VxWorks, and Win32.
243 * At the current time, this stuff only works for threads
244 * within the same process.
246 class ACE_Export ACE_cond_t
249 /// Returns the number of waiters.
250 long waiters () const;
253 /// Number of waiting threads.
256 /// Serialize access to the waiters count.
257 ACE_thread_mutex_t waiters_lock_
;
259 /// Queue up threads waiting for the condition to become signaled.
262 # if defined (ACE_VXWORKS) || defined (ACE_MQX)
264 * A semaphore used by the broadcast/signal thread to wait for all
265 * the waiting thread(s) to wake up and be released from the
268 ACE_sema_t waiters_done_
;
269 # elif defined (ACE_WIN32)
271 * An auto reset event used by the broadcast/signal thread to wait
272 * for the waiting thread(s) to wake up and get a chance at the
275 HANDLE waiters_done_
;
277 # error "Please implement this feature or check your config.h file!"
278 # endif /* ACE_VXWORKS */
280 /// Keeps track of whether we were broadcasting or just signaling.
281 size_t was_broadcast_
;
284 ACE_END_VERSIONED_NAMESPACE_DECL
286 # endif /* ACE_LACKS_COND_T */
288 # if defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE) || defined (ACE_LACKS_COND_T)
290 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
292 struct ACE_Export ACE_condattr_t
297 #if !defined (ACE_MQX)
298 struct ACE_Export ACE_mutexattr_t
304 ACE_END_VERSIONED_NAMESPACE_DECL
306 # endif /* ACE_HAS_WTHREADS_CONDITION_VARIABLE || ACE_LACKS_COND_T */
308 # if defined (ACE_LACKS_RWLOCK_T)
310 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
313 * @class ACE_rwlock_t
315 * @brief This is used to implement readers/writer locks on NT,
316 * VxWorks, and POSIX pthreads.
318 * At the current time, this stuff only works for threads
319 * within the same process.
321 struct ACE_Export ACE_rwlock_t
325 /// Serialize access to internal state.
328 /// Reader threads waiting to acquire the lock.
329 ACE_cond_t waiting_readers_
;
331 /// Number of waiting readers.
332 int num_waiting_readers_
;
334 /// Writer threads waiting to acquire the lock.
335 ACE_cond_t waiting_writers_
;
337 /// Number of waiting writers.
338 int num_waiting_writers_
;
340 /// Value is -1 if writer has the lock, else this keeps track of the
341 /// number of readers holding the lock.
344 /// Indicate that a reader is trying to upgrade
345 bool important_writer_
;
347 /// Condition for the upgrading reader
348 ACE_cond_t waiting_important_writer_
;
351 ACE_END_VERSIONED_NAMESPACE_DECL
353 # elif defined (ACE_HAS_PTHREADS_UNIX98_EXT)
354 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
355 typedef pthread_rwlock_t ACE_rwlock_t
;
356 ACE_END_VERSIONED_NAMESPACE_DECL
357 # endif /* ACE_LACKS_RWLOCK_T */
359 // Define some default thread priorities on all threaded platforms, if
360 // not defined above or in the individual platform config file.
361 // ACE_THR_PRI_FIFO_DEF should be used by applications for default
362 // real-time thread priority. ACE_THR_PRI_OTHER_DEF should be used
363 // for non-real-time priority.
364 # if !defined(ACE_THR_PRI_FIFO_DEF)
365 # if defined (ACE_WTHREADS)
366 // It would be more in spirit to use THREAD_PRIORITY_NORMAL. But,
367 // using THREAD_PRIORITY_ABOVE_NORMAL should give preference to the
368 // threads in this process, even if the process is not in the
369 // REALTIME_PRIORITY_CLASS.
370 # define ACE_THR_PRI_FIFO_DEF THREAD_PRIORITY_ABOVE_NORMAL
371 # else /* ! ACE_WTHREADS */
372 # define ACE_THR_PRI_FIFO_DEF 0
373 # endif /* ! ACE_WTHREADS */
374 # endif /* ! ACE_THR_PRI_FIFO_DEF */
376 # if !defined(ACE_THR_PRI_OTHER_DEF)
377 # if defined (ACE_WTHREADS)
378 // It would be more in spirit to use THREAD_PRIORITY_NORMAL. But,
379 // using THREAD_PRIORITY_ABOVE_NORMAL should give preference to the
380 // threads in this process, even if the process is not in the
381 // REALTIME_PRIORITY_CLASS.
382 # define ACE_THR_PRI_OTHER_DEF THREAD_PRIORITY_NORMAL
383 # else /* ! ACE_WTHREADS */
384 # define ACE_THR_PRI_OTHER_DEF 0
385 # endif /* ! ACE_WTHREADS */
386 # endif /* ! ACE_THR_PRI_OTHER_DEF */
388 // Recursive mutex support.
390 // There are two parts to this:
391 // 1. The mutex type itself. This is based on whether or not the
392 // platform supports recursive mutexes natively or they're emulated.
393 // 2. Support for using the recursive mutex with a condition variable.
394 // When a thread waits on a condition variable, it has to relinquish
395 // the lock and wait atomically, then reacquire it after the condition
396 // variable is signaled. In non-recursive mutexes, the platform
397 // handles this automatically. But in recursive mutexes, especially
398 // when emulated, the recursion count needs to be maintained across
399 // the wait. Since another thread needs to be able to acquire the
400 // lock, it needs to appear free, even if the waiting thread had done
401 // multiple acquires. Thus, there's another structure to hold this
402 // information, and is used with the recursive_mutex_cond_unlock()
403 // and recursive_mutex_cond_relock() methods to maintain the expected
404 // state when the wait finishes.
405 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
407 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
409 typedef ACE_thread_mutex_t ACE_recursive_thread_mutex_t
;
410 # if defined (ACE_WIN32)
411 // Windows has recursive mutexes, but doesn't have condition variables,
412 // so there's no built-in support for this. Thus, the condition-related
413 // unlock/relock is augmented in ACE.
414 struct ACE_recursive_mutex_state
416 // On Windows the augmented processing is simply unlocking/relocking
417 // the recursive locks - the condition handles a single lock ok.
421 // No need for special handling; just need a type for method signatures.
422 typedef int ACE_recursive_mutex_state
;
423 # endif /* ACE_WIN32 */
425 ACE_END_VERSIONED_NAMESPACE_DECL
429 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
432 * @class ACE_recursive_thread_mutex_t
435 * Implement a thin C++ wrapper that allows nested acquisition
436 * and release of a mutex that occurs in the same thread.
438 * This implementation is based on an algorithm sketched by Dave
439 * Butenhof <butenhof@zko.dec.com>. Naturally, I take the
440 * credit for any mistakes ;-)
442 class ACE_recursive_thread_mutex_t
445 /// Guards the state of the nesting level and thread id.
446 ACE_thread_mutex_t nesting_mutex_
;
448 /// This condition variable suspends other waiting threads until the
449 /// mutex is available.
450 ACE_cond_t lock_available_
;
452 /// Current nesting level of the recursion.
455 /// Current owner of the lock.
456 ACE_thread_t owner_id_
;
459 /// Since recursive mutex is emulated, the state saving needs to be handled
460 /// in ACE as well. These members save those from ACE_recursive_thread_mutex_t.
461 struct ACE_recursive_mutex_state
464 ACE_thread_t owner_id_
;
467 ACE_END_VERSIONED_NAMESPACE_DECL
469 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
471 # else /* !ACE_HAS_THREADS, i.e., the OS/platform doesn't support threading. */
473 // Give these things some reasonable value...
474 # define ACE_SCOPE_PROCESS 0
475 # define ACE_SCOPE_LWP 1
476 # define ACE_SCOPE_THREAD 2
477 # define ACE_SCHED_OTHER 0
478 # define ACE_SCHED_FIFO 1
479 # define ACE_SCHED_RR 2
480 # if !defined (THR_CANCEL_DISABLE)
481 # define THR_CANCEL_DISABLE 0
482 # endif /* ! THR_CANCEL_DISABLE */
483 # if !defined (THR_CANCEL_ENABLE)
484 # define THR_CANCEL_ENABLE 0
485 # endif /* ! THR_CANCEL_ENABLE */
486 # if !defined (THR_CANCEL_DEFERRED)
487 # define THR_CANCEL_DEFERRED 0
488 # endif /* ! THR_CANCEL_DEFERRED */
489 # if !defined (THR_CANCEL_ASYNCHRONOUS)
490 # define THR_CANCEL_ASYNCHRONOUS 0
491 # endif /* ! THR_CANCEL_ASYNCHRONOUS */
492 # if !defined (THR_JOINABLE)
493 # define THR_JOINABLE 0 /* ignore in most places */
494 # endif /* ! THR_JOINABLE */
495 # if !defined (THR_DETACHED)
496 # define THR_DETACHED 0 /* ignore in most places */
497 # endif /* ! THR_DETACHED */
498 # if !defined (THR_DAEMON)
499 # define THR_DAEMON 0 /* ignore in most places */
500 # endif /* ! THR_DAEMON */
501 # if !defined (THR_BOUND)
502 # define THR_BOUND 0 /* ignore in most places */
503 # endif /* ! THR_BOUND */
504 # if !defined (THR_NEW_LWP)
505 # define THR_NEW_LWP 0 /* ignore in most places */
506 # endif /* ! THR_NEW_LWP */
507 # if !defined (THR_SUSPENDED)
508 # define THR_SUSPENDED 0 /* ignore in most places */
509 # endif /* ! THR_SUSPENDED */
510 # if !defined (THR_SCHED_FIFO)
511 # define THR_SCHED_FIFO 0
512 # endif /* ! THR_SCHED_FIFO */
513 # if !defined (THR_SCHED_RR)
514 # define THR_SCHED_RR 0
515 # endif /* ! THR_SCHED_RR */
516 # if !defined (THR_SCHED_DEFAULT)
517 # define THR_SCHED_DEFAULT 0
518 # endif /* ! THR_SCHED_DEFAULT */
519 # if !defined (THR_INHERIT_SCHED)
520 # define THR_INHERIT_SCHED 0
521 # endif /* ! THR_INHERIT_SCHED */
522 # if !defined (USYNC_THREAD)
523 # define USYNC_THREAD 0
524 # endif /* ! USYNC_THREAD */
525 # if !defined (USYNC_PROCESS)
526 # define USYNC_PROCESS 0
527 # endif /* ! USYNC_PROCESS */
528 # if !defined (THR_SCOPE_PROCESS)
529 # define THR_SCOPE_PROCESS 0
530 # endif /* ! THR_SCOPE_PROCESS */
531 # if !defined (THR_SCOPE_SYSTEM)
532 # define THR_SCOPE_SYSTEM 0
533 # endif /* ! THR_SCOPE_SYSTEM */
535 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
537 // These are dummies needed for class OS.h
538 typedef int ACE_cond_t
;
539 struct ACE_Export ACE_condattr_t
543 struct ACE_Export ACE_mutexattr_t
547 typedef int ACE_mutex_t
;
548 typedef int ACE_thread_mutex_t
;
549 typedef int ACE_recursive_thread_mutex_t
;
550 typedef int ACE_recursive_mutex_state
;
551 # if !defined (ACE_HAS_POSIX_SEM) && !defined (ACE_USES_FIFO_SEM)
552 typedef int ACE_sema_t
;
553 # endif /* !ACE_HAS_POSIX_SEM && !ACE_USES_FIFO_SEM */
554 typedef int ACE_rwlock_t
;
555 typedef int ACE_thread_t
;
556 typedef int ACE_hthread_t
;
557 // Native TSS key type
558 typedef unsigned int ACE_OS_thread_key_t
;
559 // Application TSS key type (use this type except in TSS Emulation)
560 # if defined (ACE_HAS_TSS_EMULATION)
561 typedef u_int ACE_thread_key_t
;
562 # else /* ! ACE_HAS_TSS_EMULATION */
563 typedef ACE_OS_thread_key_t ACE_thread_key_t
;
564 # endif /* ! ACE_HAS_TSS_EMULATION */
566 ACE_END_VERSIONED_NAMESPACE_DECL
568 // Ensure that ACE_THR_PRI_FIFO_DEF and ACE_THR_PRI_OTHER_DEF are
569 // defined on non-threaded platforms, to support application source
570 // code compatibility. ACE_THR_PRI_FIFO_DEF should be used by
571 // applications for default real-time thread priority.
572 // ACE_THR_PRI_OTHER_DEF should be used for non-real-time priority.
573 # if !defined(ACE_THR_PRI_FIFO_DEF)
574 # define ACE_THR_PRI_FIFO_DEF 0
575 # endif /* ! ACE_THR_PRI_FIFO_DEF */
576 # if !defined(ACE_THR_PRI_OTHER_DEF)
577 # define ACE_THR_PRI_OTHER_DEF 0
578 # endif /* ! ACE_THR_PRI_OTHER_DEF */
580 # endif /* ACE_HAS_THREADS ***********************************************/
582 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
585 * @class ACE_Thread_ID
588 * Defines a platform-independent thread ID class. Note that
589 * this class should be defined within the scope of a thread, rather
590 * than at global scope!
592 class ACE_Export ACE_Thread_ID
595 /// Initialize the object using the thread id and thread handle
596 /// passed as parameters.
597 ACE_Thread_ID (ACE_thread_t thr_id
,
598 ACE_hthread_t thr_handle
);
600 /// Initialize the object using calls to ACE_OS::thr_self().
603 /// Copy constructor.
604 ACE_Thread_ID (const ACE_Thread_ID
&id
);
606 /// Assignment operator
607 ACE_Thread_ID
& operator= (const ACE_Thread_ID
&id
);
609 /// Get the thread id.
610 ACE_thread_t
id () const;
612 /// Set the thread id.
613 void id (ACE_thread_t
);
615 /// Get the thread handle.
616 ACE_hthread_t
handle () const;
618 /// Set the thread handle.
619 void handle (ACE_hthread_t
);
621 // Create a string representation of the thread id.
622 void to_string (char *thr_string
, size_t thr_string_len
) const;
624 // Create a string representation of the thread id.
626 void to_string (char (&thr_string
)[N
]) const
628 this->to_string (thr_string
, N
);
631 /// Equality operator.
632 bool operator== (const ACE_Thread_ID
&) const;
634 /// Inequality operator.
635 bool operator!= (const ACE_Thread_ID
&) const;
638 /// Identify the thread.
639 ACE_thread_t thread_id_
;
641 /// Handle to the thread (typically used to "wait" on Win32).
642 ACE_hthread_t thread_handle_
;
645 // = The ACE_Sched_Priority type should be used for platform-
646 // independent thread and process priorities, by convention.
647 // int should be used for OS-specific priorities.
648 typedef int ACE_Sched_Priority
;
650 # if !defined (ACE_DEFAULT_SYNCH_TYPE)
651 # if defined (ACE_VXWORKS)
652 // Types include these options: SEM_Q_PRIORITY, SEM_Q_FIFO,
653 // SEM_DELETE_SAFE, and SEM_INVERSION_SAFE. SEM_Q_FIFO is
654 // used as the default because that is VxWorks' default.
655 # define ACE_DEFAULT_SYNCH_TYPE SEM_Q_FIFO
657 # define ACE_DEFAULT_SYNCH_TYPE USYNC_THREAD
658 # endif /* ACE_VXWORKS */
659 #endif /* ! ACE_DEFAULT_SYNCH_TYPE */
661 // forward declaration
662 class ACE_Sched_Params
;
663 class ACE_Time_Value
;
665 #if defined (ACE_WIN32)
666 typedef int ACE_idtype_t
;
667 typedef DWORD ACE_id_t
;
668 typedef int ACE_pri_t
;
669 # define ACE_SELF (0)
670 #else /* !defined (ACE_WIN32) */
671 typedef int ACE_idtype_t
;
672 typedef long ACE_id_t
;
673 # define ACE_SELF (-1)
674 typedef short ACE_pri_t
;
675 #endif /* !defined (ACE_WIN32) */
677 # if defined (ACE_HAS_TSS_EMULATION)
678 // Allow config.h to set the default number of thread keys.
679 # if !defined (ACE_DEFAULT_THREAD_KEYS)
680 # define ACE_DEFAULT_THREAD_KEYS 64
681 # endif /* ! ACE_DEFAULT_THREAD_KEYS */
683 // forward declaration
687 * @class ACE_TSS_Emulation
689 * @brief Thread-specific storage emulation.
691 * This provides a thread-specific storage implementation.
692 * It is intended for use on platforms that don't have a
693 * native TSS, or have a TSS with limitations such as the
694 * number of keys or lack of support for removing keys.
696 class ACE_Export ACE_TSS_Emulation
699 typedef void (*ACE_TSS_DESTRUCTOR
)(void *value
);
701 /// Maximum number of TSS keys allowed over the life of the program.
702 enum { ACE_TSS_THREAD_KEYS_MAX
= ACE_DEFAULT_THREAD_KEYS
};
704 /// Returns the total number of keys allocated so far.
705 static u_int
total_keys ();
707 /// Sets the argument to the next available key. Returns 0 on success,
708 /// -1 if no keys are available.
709 static int next_key (ACE_thread_key_t
&key
);
711 /// Release a key that was used. This way the key can be given out in a
712 /// new request. Returns 0 on success, 1 if the key was not reserved.
713 static int release_key (ACE_thread_key_t key
);
715 /// Check a key for validity.
716 static int is_key (ACE_thread_key_t key
);
718 /// Returns the exit hook associated with the key. Does _not_ check
720 static ACE_TSS_DESTRUCTOR
tss_destructor (const ACE_thread_key_t key
);
722 /// Associates the TSS destructor with the key. Does _not_ check
724 static void tss_destructor (const ACE_thread_key_t key
,
725 ACE_TSS_DESTRUCTOR destructor
);
727 /// Accesses the object referenced by key in the current thread's TSS array.
728 /// Does _not_ check for a valid key.
729 static void *&ts_object (const ACE_thread_key_t key
);
732 * Setup an array to be used for local TSS. Returns the array
733 * address on success. Returns 0 if local TSS had already been
734 * setup for this thread. There is no corresponding tss_close ()
735 * because it is not needed.
736 * @note tss_open () is called by ACE for threads that it spawns.
737 * If your application spawns threads without using ACE, and it uses
738 * ACE's TSS emulation, each of those threads should call tss_open
739 * (). See the ace_thread_adapter () implementation for an example.
741 static void *tss_open (void *ts_storage
[ACE_TSS_THREAD_KEYS_MAX
]);
743 /// Shutdown TSS emulation. For use only by ACE_OS::cleanup_tss ().
744 static void tss_close ();
747 // Global TSS structures.
748 /// Contains the possible value of the next key to be allocated. Which key
749 /// is actually allocated is based on the tss_keys_used
750 static u_int total_keys_
;
752 /// Array of thread exit hooks (TSS destructors) that are called for each
753 /// key (that has one) when the thread exits.
754 static ACE_TSS_DESTRUCTOR tss_destructor_
[ACE_TSS_THREAD_KEYS_MAX
];
756 /// TSS_Keys instance to administrate whether a specific key is in used
759 // Static construction in VxWorks 5.4 and later is slightly broken.
760 // If the static object is more complex than an integral type, static
761 // construction will occur twice. The tss_keys_used_ object is
762 // statically constructed and then modified by ACE_Log_Msg::instance()
763 // when two keys are created and TSS data is stored. However, at
764 // the end of static construction the tss_keys_used_ object is again
765 // initialized and therefore it will appear to next_key() that no
766 // TSS keys have been handed out. That is all true unless the
767 // tss_keys_used object is a static pointer instead of a static object.
768 static ACE_TSS_Keys
* tss_keys_used_
;
770 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
771 /// Location of current thread's TSS array.
772 static void **tss_base (void* ts_storage
[] = 0, u_int
*ts_created
= 0);
773 # else /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
774 /// Location of current thread's TSS array.
775 static void **&tss_base ();
777 # if defined (ACE_HAS_VXTHREADS)
778 # if (defined (_WRS_CONFIG_SMP) || defined (INCLUDE_AMP_CPU))
779 static __thread
void* ace_tss_keys
;
780 # else /* ! VxWorks SMP */
781 static void* ace_tss_keys
;
782 # endif /* ! VxWorks SMP */
783 # endif /* ACE_HAS_VXTHREADS */
785 # endif /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
787 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
788 // Rely on native thread specific storage for the implementation,
789 // but just use one key.
790 static ACE_OS_thread_key_t native_tss_key_
;
792 // Used to indicate if native tss key has been allocated
793 static bool key_created_
;
794 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
796 # endif /* ACE_HAS_TSS_EMULATION */
798 // moved ACE_TSS_Ref, ACE_TSS_Info, and ACE_TSS_Keys class
799 // declarations from OS.cpp so they are visible to the single
800 // file of template instantiations.
801 # if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION)
805 * @brief "Reference count" for thread-specific storage keys.
807 * Since the <ACE_Unbounded_Stack> doesn't allow duplicates, the
808 * "reference count" is the identify of the thread_id.
814 ACE_TSS_Ref (ACE_thread_t id
);
816 /// Default constructor
819 /// Check for equality.
820 bool operator== (const ACE_TSS_Ref
&) const;
822 /// Check for inequality.
823 bool operator!= (const ACE_TSS_Ref
&) const;
826 /// ID of thread using a specific key.
831 * @class ACE_TSS_Info
833 * @brief Thread Specific Key management.
835 * This class maps a key to a "destructor."
840 /// Declare pointer to function to destroy tss object.
841 typedef void (*Destructor
)(void *);
844 ACE_TSS_Info (ACE_thread_key_t key
,
845 Destructor dest
= 0);
847 /// Default constructor
850 /// Returns 1 if the key is in use, 0 if not.
851 int key_in_use () const { return thread_count_
!= -1; }
853 /// Mark the key as being in use if the flag is non-zero, or
854 /// not in use if the flag is 0.
855 void key_in_use (int flag
) { thread_count_
= flag
== 0 ? -1 : 1; }
857 /// Check for equality.
858 bool operator== (const ACE_TSS_Info
&) const;
860 /// Check for inequality.
861 bool operator!= (const ACE_TSS_Info
&) const;
867 /// Key to the thread-specific storage item.
868 ACE_thread_key_t key_
;
870 /// "Destructor" that gets called when the item is finally released.
871 Destructor destructor_
;
873 /// Count of threads that are using this key. Contains -1 when the
874 /// key is not in use.
877 friend class ACE_TSS_Cleanup
;
881 * @class ACE_TSS_Keys
883 * @brief Collection of in-use flags for a thread's TSS keys.
884 * For internal use only by ACE_TSS_Cleanup; it is public because
885 * some compilers can't use nested classes for template instantiation
888 * Wrapper around array of whether each key is in use. A simple
889 * typedef doesn't work with Sun C++ 4.2.
894 ACE_ALLOC_HOOK_DECLARE
;
896 /// Default constructor, to initialize all bits to zero (unused).
899 /// Mark the specified key as being in use, if it was not already so marked.
900 /// Returns 1 if the had already been marked, 0 if not.
901 int test_and_set (const ACE_thread_key_t key
);
903 /// Mark the specified key as not being in use, if it was not already so
904 /// cleared. Returns 1 if the key had already been cleared, 0 if not.
905 int test_and_clear (const ACE_thread_key_t key
);
907 /// Return whether the specific key is marked as in use.
908 /// Returns 1 if the key is been marked, 0 if not.
909 int is_set (const ACE_thread_key_t key
) const;
912 /// For a given key, find the word and bit number that represent it.
913 static void find (const u_int key
, u_int
&word
, u_int
&bit
);
917 # if ACE_SIZEOF_LONG == 8
918 ACE_BITS_PER_WORD
= 64,
919 # elif ACE_SIZEOF_LONG == 4
920 ACE_BITS_PER_WORD
= 32,
922 # error ACE_TSS_Keys only supports 32 or 64 bit longs.
923 # endif /* ACE_SIZEOF_LONG == 8 */
924 ACE_WORDS
= (ACE_DEFAULT_THREAD_KEYS
- 1) / ACE_BITS_PER_WORD
+ 1
927 /// Bit flag collection. A bit value of 1 indicates that the key is in
928 /// use by this thread.
929 u_long key_bit_words_
[ACE_WORDS
];
932 # endif /* defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) */
934 ACE_END_VERSIONED_NAMESPACE_DECL
936 #if (defined (ACE_HAS_VERSIONED_NAMESPACE) && ACE_HAS_VERSIONED_NAMESPACE == 1)
937 # define ACE_MUTEX_LOCK_CLEANUP_ADAPTER_NAME ACE_PREPROC_CONCATENATE(ACE_VERSIONED_NAMESPACE_NAME, _ace_mutex_lock_cleanup_adapter)
938 #endif /* ACE_HAS_VERSIONED_NAMESPACE == 1 */
940 # if defined (ACE_HAS_THR_C_FUNC)
941 // This is necessary to work around nasty problems with MVS C++.
942 extern "C" ACE_Export
void ACE_MUTEX_LOCK_CLEANUP_ADAPTER_NAME (void *args
);
943 # define ACE_PTHREAD_CLEANUP_PUSH(A) pthread_cleanup_push (ACE_MUTEX_LOCK_CLEANUP_ADAPTER_NAME, (void *) A);
944 # define ACE_PTHREAD_CLEANUP_POP(A) pthread_cleanup_pop(A)
945 # elif defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CLEANUP)
946 extern "C" ACE_Export
void ACE_MUTEX_LOCK_CLEANUP_ADAPTER_NAME (void *args
);
947 # define ACE_PTHREAD_CLEANUP_PUSH(A) pthread_cleanup_push (ACE_MUTEX_LOCK_CLEANUP_ADAPTER_NAME, (void *) A);
948 # define ACE_PTHREAD_CLEANUP_POP(A) pthread_cleanup_pop(A)
950 # define ACE_PTHREAD_CLEANUP_PUSH(A)
951 # define ACE_PTHREAD_CLEANUP_POP(A)
952 # endif /* ACE_HAS_THR_C_FUNC */
954 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
956 # if !defined (ACE_WIN32)
961 class ACE_Base_Thread_Adapter
;
964 //@{ @name A set of wrappers for threads
966 /// This is necessary to deal with POSIX pthreads and their use of
967 /// structures for thread ids.
968 extern ACE_Export ACE_thread_t NULL_thread
;
970 /// This is necessary to deal with POSIX pthreads and their use of
971 /// structures for thread handles.
972 extern ACE_Export ACE_hthread_t NULL_hthread
;
974 /// This is necessary to deal with POSIX pthreads and their use of
975 /// structures for TSS keys.
976 extern ACE_Export ACE_thread_key_t NULL_key
;
980 * Call TSS destructors for the current thread. If the current
981 * thread is the main thread, then the argument must be 1.
982 * For private use of ACE_Object_Manager and ACE_Thread_Adapter only.
985 void cleanup_tss (const u_int main_thread
);
987 //@{ @name A set of wrappers for condition variables.
988 ACE_NAMESPACE_INLINE_FUNCTION
989 int condattr_init (ACE_condattr_t
&attributes
,
990 int type
= ACE_DEFAULT_SYNCH_TYPE
);
992 ACE_NAMESPACE_INLINE_FUNCTION
993 int condattr_synctype (ACE_condattr_t
&attributes
, int& type
);
995 ACE_NAMESPACE_INLINE_FUNCTION
996 int condattr_destroy (ACE_condattr_t
&attributes
);
998 ACE_NAMESPACE_INLINE_FUNCTION
999 int condattr_setclock(ACE_condattr_t
&attributes
,
1000 clockid_t clock_id
);
1002 #if defined (ACE_LACKS_COND_T)
1005 ACE_NAMESPACE_INLINE_FUNCTION
1006 #endif /* ACE_LACKS_COND_T */
1007 int cond_broadcast (ACE_cond_t
*cv
);
1009 #if defined (ACE_LACKS_COND_T)
1012 ACE_NAMESPACE_INLINE_FUNCTION
1013 #endif /* ACE_LACKS_COND_T */
1014 int cond_destroy (ACE_cond_t
*cv
);
1017 int cond_init (ACE_cond_t
*cv
,
1018 short type
= ACE_DEFAULT_SYNCH_TYPE
,
1019 const char *name
= 0,
1022 #if defined (ACE_LACKS_COND_T)
1025 ACE_NAMESPACE_INLINE_FUNCTION
1026 #endif /* ACE_LACKS_COND_T */
1027 int cond_init (ACE_cond_t
*cv
,
1028 ACE_condattr_t
&attributes
,
1029 const char *name
= 0,
1032 # if defined (ACE_HAS_WCHAR)
1033 # if defined (ACE_LACKS_COND_T)
1036 ACE_NAMESPACE_INLINE_FUNCTION
1037 # endif /* ACE_LACKS_COND_T */
1038 int cond_init (ACE_cond_t
*cv
,
1040 const wchar_t *name
,
1043 # if defined (ACE_LACKS_COND_T)
1046 ACE_NAMESPACE_INLINE_FUNCTION
1047 # endif /* ACE_LACKS_COND_T */
1048 int cond_init (ACE_cond_t
*cv
,
1049 ACE_condattr_t
&attributes
,
1050 const wchar_t *name
,
1052 # endif /* ACE_HAS_WCHAR */
1054 #if defined (ACE_LACKS_COND_T)
1057 ACE_NAMESPACE_INLINE_FUNCTION
1058 #endif /* ACE_LACKS_COND_T */
1059 int cond_signal (ACE_cond_t
*cv
);
1061 #if defined (ACE_LACKS_COND_T)
1064 ACE_NAMESPACE_INLINE_FUNCTION
1065 #endif /* ACE_LACKS_COND_T */
1066 int cond_timedwait (ACE_cond_t
*cv
,
1068 ACE_Time_Value
*timeout
);
1070 #if defined (ACE_LACKS_COND_T)
1073 ACE_NAMESPACE_INLINE_FUNCTION
1074 #endif /* ACE_LACKS_COND_T */
1075 int cond_wait (ACE_cond_t
*cv
,
1078 # if defined (ACE_WIN32) && defined (ACE_HAS_WTHREADS)
1080 int cond_timedwait (ACE_cond_t
*cv
,
1081 ACE_thread_mutex_t
*m
,
1082 ACE_Time_Value
*timeout
);
1085 int cond_wait (ACE_cond_t
*cv
,
1086 ACE_thread_mutex_t
*m
);
1087 # endif /* ACE_WIN32 && ACE_HAS_WTHREADS */
1089 //@{ @name A set of wrappers for auto-reset and manual events.
1092 int event_destroy (ACE_event_t
*event
);
1094 ACE_NAMESPACE_INLINE_FUNCTION
1095 int event_init (ACE_event_t
*event
,
1096 int manual_reset
= 0,
1097 int initial_state
= 0,
1098 int type
= ACE_DEFAULT_SYNCH_TYPE
,
1099 const char *name
= 0,
1101 LPSECURITY_ATTRIBUTES sa
= 0);
1104 int event_init (ACE_event_t
*event
,
1106 ACE_condattr_t
*attributes
,
1107 int manual_reset
= 0,
1108 int initial_state
= 0,
1109 const char *name
= 0,
1111 LPSECURITY_ATTRIBUTES sa
= 0);
1113 # if defined (ACE_HAS_WCHAR)
1114 ACE_NAMESPACE_INLINE_FUNCTION
1115 int event_init (ACE_event_t
*event
,
1119 const wchar_t *name
,
1121 LPSECURITY_ATTRIBUTES sa
= 0);
1123 ACE_NAMESPACE_INLINE_FUNCTION
1124 int event_init (ACE_event_t
*event
,
1126 ACE_condattr_t
*attributes
,
1129 const wchar_t *name
,
1131 LPSECURITY_ATTRIBUTES sa
= 0);
1132 # endif /* ACE_HAS_WCHAR */
1135 int event_pulse (ACE_event_t
*event
);
1138 int event_reset (ACE_event_t
*event
);
1141 int event_signal (ACE_event_t
*event
);
1144 int event_timedwait (ACE_event_t
*event
,
1145 ACE_Time_Value
*timeout
,
1146 int use_absolute_time
= 1);
1148 ACE_NAMESPACE_INLINE_FUNCTION
1149 int event_wait (ACE_event_t
*event
);
1154 int lwp_getparams (ACE_Sched_Params
&);
1157 int lwp_setparams (const ACE_Sched_Params
&);
1160 //@{ @name A set of wrappers for mutex locks.
1163 int mutex_destroy (ACE_mutex_t
*m
);
1166 int mutex_init (ACE_mutex_t
*m
,
1167 int lock_scope
= ACE_DEFAULT_SYNCH_TYPE
,
1168 const char *name
= 0,
1169 ACE_mutexattr_t
*arg
= 0,
1170 LPSECURITY_ATTRIBUTES sa
= 0,
1173 #if defined (ACE_HAS_WCHAR)
1175 int mutex_init (ACE_mutex_t
*m
,
1177 const wchar_t *name
,
1178 ACE_mutexattr_t
*arg
= 0,
1179 LPSECURITY_ATTRIBUTES sa
= 0,
1181 #endif /* ACE_HAS_WCHAR */
1183 /// Win32 note: Abandoned mutexes are not treated differently. 0 is
1184 /// returned since the calling thread does get the ownership.
1186 int mutex_lock (ACE_mutex_t
*m
);
1188 /// This method is only implemented for Win32. For abandoned
1189 /// mutexes, @a abandoned is set to 1 and 0 is returned.
1191 int mutex_lock (ACE_mutex_t
*m
,
1195 * This method attempts to acquire a lock, but gives up if the lock
1196 * has not been acquired by the given time. If the lock is not
1197 * acquired within the given amount of time, then this method
1198 * returns -1 with an @c ETIME errno on platforms that actually
1199 * support timed mutexes. The timeout should be an absolute time.
1200 * Note that the mutex should not be a recursive one, i.e., it
1201 * should only be a standard mutex or an error checking mutex since
1202 * some implementations of this method don't support recursive
1203 * mutexes. If you want to use a recursive mutex see the methods
1207 int mutex_lock (ACE_mutex_t
*m
,
1208 const ACE_Time_Value
&timeout
);
1211 * If @a timeout == 0, calls <ACE_OS::mutex_lock(m)>. Otherwise,
1212 * this method attempts to acquire a lock, but gives up if the lock
1213 * has not been acquired by the given time, in which case it returns
1214 * -1 with an @c ETIME errno on platforms that actually support timed
1215 * mutexes. The timeout should be an absolute time. Note that the
1216 * mutex should not be a recursive one, i.e., it should only be a
1217 * standard mutex or an error checking mutex since some
1218 * implementations of this method don't support recursive mutexes.
1219 * If you want to use a recursive mutex see the methods below.
1221 ACE_NAMESPACE_INLINE_FUNCTION
1222 int mutex_lock (ACE_mutex_t
*m
,
1223 const ACE_Time_Value
*timeout
);
1225 /// Handle asynchronous thread cancellation cleanup.
1227 void mutex_lock_cleanup (void *mutex
);
1229 /// Win32 note: Abandoned mutexes are not treated differently. 0 is
1230 /// returned since the calling thread does get the ownership.
1232 int mutex_trylock (ACE_mutex_t
*m
);
1234 /// This method is only implemented for Win32. For abandoned
1235 /// mutexes, @a abandoned is set to 1 and 0 is returned.
1237 int mutex_trylock (ACE_mutex_t
*m
,
1241 int mutex_unlock (ACE_mutex_t
*m
);
1245 /// Low-level interface to @c priocntl(2).
1246 ACE_NAMESPACE_INLINE_FUNCTION
1247 long priority_control (ACE_idtype_t
, ACE_id_t
, int, void *);
1249 //@{ @name A set of wrappers for recursive mutex locks.
1251 // These two methods are primarily in support of
1252 // ACE_Condition<ACE_Recursive_Thread_Mutex> and should probably not
1253 // be called outside that context.
1254 ACE_NAMESPACE_INLINE_FUNCTION
1255 int recursive_mutex_cond_unlock (ACE_recursive_thread_mutex_t
*m
,
1256 ACE_recursive_mutex_state
&state
);
1258 ACE_NAMESPACE_INLINE_FUNCTION
1259 void recursive_mutex_cond_relock (ACE_recursive_thread_mutex_t
*m
,
1260 ACE_recursive_mutex_state
&state
);
1262 ACE_NAMESPACE_INLINE_FUNCTION
1263 int recursive_mutex_destroy (ACE_recursive_thread_mutex_t
*m
);
1265 ACE_NAMESPACE_INLINE_FUNCTION
1266 int recursive_mutex_init (ACE_recursive_thread_mutex_t
*m
,
1267 const ACE_TCHAR
*name
= 0,
1268 ACE_mutexattr_t
*arg
= 0,
1269 LPSECURITY_ATTRIBUTES sa
= 0);
1271 ACE_NAMESPACE_INLINE_FUNCTION
1272 int recursive_mutex_lock (ACE_recursive_thread_mutex_t
*m
);
1274 ACE_NAMESPACE_INLINE_FUNCTION
1275 int recursive_mutex_lock (ACE_recursive_thread_mutex_t
*m
,
1276 const ACE_Time_Value
&timeout
);
1278 ACE_NAMESPACE_INLINE_FUNCTION
1279 int recursive_mutex_lock (ACE_recursive_thread_mutex_t
*m
,
1280 const ACE_Time_Value
*timeout
);
1282 ACE_NAMESPACE_INLINE_FUNCTION
1283 int recursive_mutex_trylock (ACE_recursive_thread_mutex_t
*m
);
1285 ACE_NAMESPACE_INLINE_FUNCTION
1286 int recursive_mutex_unlock (ACE_recursive_thread_mutex_t
*m
);
1291 //@{ @name A set of wrappers for readers/writer locks.
1293 ACE_NAMESPACE_INLINE_FUNCTION
1294 int rw_rdlock (ACE_rwlock_t
*rw
);
1296 ACE_NAMESPACE_INLINE_FUNCTION
1297 int rw_tryrdlock (ACE_rwlock_t
*rw
);
1299 ACE_NAMESPACE_INLINE_FUNCTION
1300 int rw_trywrlock (ACE_rwlock_t
*rw
);
1302 ACE_NAMESPACE_INLINE_FUNCTION
1303 int rw_trywrlock_upgrade (ACE_rwlock_t
*rw
);
1305 ACE_NAMESPACE_INLINE_FUNCTION
1306 int rw_unlock (ACE_rwlock_t
*rw
);
1308 ACE_NAMESPACE_INLINE_FUNCTION
1309 int rw_wrlock (ACE_rwlock_t
*rw
);
1311 ACE_NAMESPACE_INLINE_FUNCTION
1312 int rwlock_destroy (ACE_rwlock_t
*rw
);
1315 int rwlock_init (ACE_rwlock_t
*rw
,
1316 int type
= ACE_DEFAULT_SYNCH_TYPE
,
1317 const ACE_TCHAR
*name
= 0,
1322 //@{ @name Thread scheduler interface.
1323 /// Set scheduling parameters. An id of ACE_SELF indicates, e.g.,
1324 /// set the parameters on the calling thread.
1326 int sched_params (const ACE_Sched_Params
&, ACE_id_t id
= ACE_SELF
);
1329 /// Find the scheduling class ID that corresponds to the class name.
1331 int scheduling_class (const char *class_name
, ACE_id_t
&);
1333 //@{ @name A set of wrappers for semaphores.
1335 ACE_NAMESPACE_INLINE_FUNCTION
1336 int sema_destroy (ACE_sema_t
*s
);
1338 ACE_NAMESPACE_INLINE_FUNCTION
1339 int sema_init (ACE_sema_t
*s
,
1341 int type
= ACE_DEFAULT_SYNCH_TYPE
,
1342 const char *name
= 0,
1344 int max
= 0x7fffffff,
1345 LPSECURITY_ATTRIBUTES sa
= 0);
1347 ACE_NAMESPACE_INLINE_FUNCTION
1348 int sema_init (ACE_sema_t
*s
,
1351 ACE_condattr_t
*attributes
,
1352 const char *name
= 0,
1354 int max
= 0x7fffffff,
1355 LPSECURITY_ATTRIBUTES sa
= 0);
1357 # if defined (ACE_HAS_WCHAR)
1358 ACE_NAMESPACE_INLINE_FUNCTION
1359 int sema_init (ACE_sema_t
*s
,
1362 const wchar_t *name
,
1364 int max
= 0x7fffffff,
1365 LPSECURITY_ATTRIBUTES sa
= 0);
1367 ACE_NAMESPACE_INLINE_FUNCTION
1368 int sema_init (ACE_sema_t
*s
,
1371 ACE_condattr_t
*attributes
,
1372 const wchar_t *name
,
1374 int max
= 0x7fffffff,
1375 LPSECURITY_ATTRIBUTES sa
= 0);
1376 # endif /* ACE_HAS_WCHAR */
1378 ACE_NAMESPACE_INLINE_FUNCTION
1379 void sema_avoid_unlink (ACE_sema_t
*s
, bool avoid_unlink
);
1381 ACE_NAMESPACE_INLINE_FUNCTION
1382 int sema_unlink (const char *name
);
1384 ACE_NAMESPACE_INLINE_FUNCTION
1385 int sema_post (ACE_sema_t
*s
);
1387 ACE_NAMESPACE_INLINE_FUNCTION
1388 int sema_post (ACE_sema_t
*s
,
1389 u_int release_count
);
1391 ACE_NAMESPACE_INLINE_FUNCTION
1392 int sema_trywait (ACE_sema_t
*s
);
1394 ACE_NAMESPACE_INLINE_FUNCTION
1395 int sema_wait (ACE_sema_t
*s
);
1397 ACE_NAMESPACE_INLINE_FUNCTION
1398 int sema_wait (ACE_sema_t
*s
,
1399 ACE_Time_Value
&tv
);
1401 ACE_NAMESPACE_INLINE_FUNCTION
1402 int sema_wait (ACE_sema_t
*s
,
1403 ACE_Time_Value
*tv
);
1406 //@{ @name A set of wrappers for System V semaphores.
1407 ACE_NAMESPACE_INLINE_FUNCTION
1408 int semctl (int int_id
,
1413 ACE_NAMESPACE_INLINE_FUNCTION
1414 int semget (key_t key
,
1418 ACE_NAMESPACE_INLINE_FUNCTION
1419 int semop (int int_id
,
1420 struct sembuf
*sops
,
1424 /// Friendly interface to @c priocntl(2).
1426 int set_scheduling_params (const ACE_Sched_Params
&,
1427 ACE_id_t id
= ACE_SELF
);
1429 ACE_NAMESPACE_INLINE_FUNCTION
1430 int sigtimedwait (const sigset_t
*set
,
1432 const ACE_Time_Value
*timeout
);
1434 ACE_NAMESPACE_INLINE_FUNCTION
1435 int sigwait (sigset_t
*set
,
1438 ACE_NAMESPACE_INLINE_FUNCTION
1439 int sigwaitinfo (const sigset_t
*set
,
1442 ACE_NAMESPACE_INLINE_FUNCTION
1443 int thr_cancel (ACE_thread_t t_id
);
1445 ACE_NAMESPACE_INLINE_FUNCTION
1446 int thr_cmp (ACE_hthread_t t1
,
1449 // These are non-portable since they use ACE_thread_t and
1450 // ACE_hthread_t and will go away in a future release.
1451 ACE_NAMESPACE_INLINE_FUNCTION
1452 int thr_continue (ACE_hthread_t target_thread
);
1455 * Creates a new thread having @a flags attributes and running @a func
1456 * with @a args (if @a thread_adapter is non-0 then @a func and @a args
1457 * are ignored and are obtained from @a thread_adapter). @a thr_id
1458 * and @a t_handle are set to the thread's ID and handle (?),
1459 * respectively. The thread runs at @a priority priority (see
1462 * The @a flags are a bitwise-OR of the following:
1464 * THR_CANCEL_DISABLE, THR_CANCEL_ENABLE, THR_CANCEL_DEFERRED,
1465 * THR_CANCEL_ASYNCHRONOUS, THR_BOUND, THR_NEW_LWP, THR_DETACHED,
1466 * THR_SUSPENDED, THR_DAEMON, THR_JOINABLE, THR_SCHED_FIFO,
1467 * THR_SCHED_RR, THR_SCHED_DEFAULT, THR_EXPLICIT_SCHED,
1468 * THR_SCOPE_SYSTEM, THR_SCOPE_PROCESS
1471 * By default, or if @a priority is set to
1472 * ACE_DEFAULT_THREAD_PRIORITY, an "appropriate" priority value for
1473 * the given scheduling policy (specified in @a flags, e.g.,
1474 * @c THR_SCHED_DEFAULT) is used. This value is calculated
1475 * dynamically, and is the median value between the minimum and
1476 * maximum priority values for the given policy. If an explicit
1477 * value is given, it is used. Note that actual priority values are
1478 * EXTREMEMLY implementation-dependent, and are probably best
1481 * Note that @a thread_adapter is always deleted by @c thr_create,
1482 * therefore it must be allocated with global operator new.
1484 * At the moment for @a thr_name a valid string is passed then this
1485 * will be used on VxWorks to set the task name. If we just pass a pointer
1486 * the name of the task is returned
1489 int thr_create (ACE_THR_FUNC func
,
1492 ACE_thread_t
*thr_id
,
1493 ACE_hthread_t
*t_handle
= 0,
1494 long priority
= ACE_DEFAULT_THREAD_PRIORITY
,
1496 size_t stacksize
= ACE_DEFAULT_THREAD_STACKSIZE
,
1497 ACE_Base_Thread_Adapter
*thread_adapter
= 0,
1498 const char** thr_name
= 0);
1500 ACE_NAMESPACE_INLINE_FUNCTION
1501 int thr_equal (ACE_thread_t t1
, ACE_thread_t t2
);
1504 void thr_exit (ACE_THR_FUNC_RETURN status
= 0);
1506 ACE_NAMESPACE_INLINE_FUNCTION
1507 int thr_getconcurrency ();
1509 ACE_NAMESPACE_INLINE_FUNCTION
1510 int thr_getprio (ACE_hthread_t id
,
1513 ACE_NAMESPACE_INLINE_FUNCTION
1514 int thr_getprio (ACE_hthread_t id
,
1518 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
1519 ACE_NAMESPACE_INLINE_FUNCTION
1520 /// for internal use only. Applications should call thr_getspecific
1521 int thr_getspecific_native (ACE_OS_thread_key_t key
, void **data
);
1522 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
1524 ACE_NAMESPACE_INLINE_FUNCTION
1525 int thr_getspecific (ACE_thread_key_t key
, void **data
);
1527 #if defined (ACE_HAS_VXTHREADS)
1530 ACE_NAMESPACE_INLINE_FUNCTION
1531 #endif /* ACE_HAS_VXTHREADS */
1532 int thr_join (ACE_hthread_t waiter_id
, ACE_THR_FUNC_RETURN
*status
);
1534 #if defined (ACE_HAS_VXTHREADS)
1537 ACE_NAMESPACE_INLINE_FUNCTION
1538 #endif /* ACE_HAS_VXTHREADS */
1539 int thr_join (ACE_thread_t waiter_id
,
1540 ACE_thread_t
*thr_id
,
1541 ACE_THR_FUNC_RETURN
*status
);
1544 * Get the thread affinity
1546 * @param thr_id For NPTL-threads, when ACE_HAS_PTHREAD_SETAFFINITY_NP
1547 * defined, this is the thread-id. For linux-threads, when
1548 * ACE_HAS_SCHED_SETAFFINITY defined, it expects a process-id. Since for
1549 * linux-threads a thread is seen as a process, it does the job.
1550 * @param cpu_set_size The size of the cpu_mask, in bytes.
1551 * @param cpu_mask Is a bitmask of CPUs to bind to, e.g value 1 binds the
1552 * thread to the "CPU 0", etc
1555 int thr_get_affinity (ACE_hthread_t thr_id
,
1556 size_t cpu_set_size
,
1557 cpu_set_t
* cpu_mask
);
1561 * Set the thread affinity
1563 * @param thr_id For NPTL-threads, when ACE_HAS_PTHREAD_SETAFFINITY_NP
1564 * defined, this is the thread-id. For linux-threads, when
1565 * ACE_HAS_SCHED_SETAFFINITY defined, it expects a process-id. Since for
1566 * linux-threads a thread is seen as a process, it does the job.
1567 * @param cpu_set_size The size of the cpu_mask, in bytes.
1568 * @param cpu_mask Is a bitmask of CPUs to bind to, e.g value 1 binds the
1569 * thread to the "CPU 0", etc
1572 int thr_set_affinity (ACE_hthread_t thr_id
,
1573 size_t cpu_set_size
,
1574 const cpu_set_t
* cpu_mask
);
1577 int thr_key_detach (ACE_thread_key_t key
);
1580 int thr_key_used (ACE_thread_key_t key
);
1582 # if defined (ACE_HAS_THR_C_DEST)
1583 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
1584 /// @internal Applications should call thr_keycreate
1586 int thr_keycreate_native (ACE_OS_thread_key_t
*key
, ACE_THR_C_DEST
);
1587 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
1590 int thr_keycreate (ACE_thread_key_t
*key
, ACE_THR_C_DEST
);
1593 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
1594 /// @internal Applications should call thr_keycreate instead
1596 int thr_keycreate_native (ACE_OS_thread_key_t
*key
,
1598 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
1601 int thr_keycreate (ACE_thread_key_t
*key
, ACE_THR_DEST
);
1603 # endif /* ACE_HAS_THR_C_DEST */
1605 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
1606 /// @internal Applications should call thr_keyfree instead
1608 int thr_keyfree_native (ACE_OS_thread_key_t key
);
1609 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
1612 int thr_keyfree (ACE_thread_key_t key
);
1614 ACE_NAMESPACE_INLINE_FUNCTION
1615 int thr_kill (ACE_thread_t thr_id
, int signum
);
1617 ACE_NAMESPACE_INLINE_FUNCTION
1618 size_t thr_min_stack ();
1620 ACE_NAMESPACE_INLINE_FUNCTION
1621 ACE_thread_t
thr_self ();
1623 ACE_NAMESPACE_INLINE_FUNCTION
1624 void thr_self (ACE_hthread_t
&);
1626 ACE_NAMESPACE_INLINE_FUNCTION
1627 const char* thr_name ();
1629 /// Stores a string version of the current thread id into buffer and
1630 /// returns the size of this thread id in bytes.
1631 ACE_NAMESPACE_INLINE_FUNCTION
1632 ssize_t
thr_id (char buffer
[], size_t buffer_length
);
1635 * For systems that support it (Only Linux as of writing), this is a wrapper
1636 * for pid_t gettid().
1638 * It returns the system-wide thread id (TID) for the current thread. These
1639 * are similar to PIDs and, for x86 Linux at least, are much shorter than
1640 * what is returned from thr_self(), which is an address.
1642 * For older Linux (pre 2.4.11) and other systems that don't have gettid(),
1643 * this uses ACE_NOTSUP_RETURN (-1).
1645 ACE_NAMESPACE_INLINE_FUNCTION
1646 pid_t
thr_gettid ();
1649 * Puts the string representation of pid_t thr_gettid() into the buffer and
1650 * returns number of bytes added.
1652 ACE_NAMESPACE_INLINE_FUNCTION
1653 ssize_t
thr_gettid (char buffer
[], size_t buffer_length
);
1655 /// State is THR_CANCEL_ENABLE or THR_CANCEL_DISABLE
1656 ACE_NAMESPACE_INLINE_FUNCTION
1657 int thr_setcancelstate (int new_state
, int *old_state
);
1659 /// Type is THR_CANCEL_DEFERRED or THR_CANCEL_ASYNCHRONOUS
1660 ACE_NAMESPACE_INLINE_FUNCTION
1661 int thr_setcanceltype (int new_type
, int *old_type
);
1663 ACE_NAMESPACE_INLINE_FUNCTION
1664 int thr_setconcurrency (int hint
);
1666 ACE_NAMESPACE_INLINE_FUNCTION
1667 int thr_setprio (ACE_hthread_t ht_id
, int priority
, int policy
= -1);
1670 int thr_setprio (const ACE_Sched_Priority prio
);
1672 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
1673 /// @internal Applications should call thr_setspecific
1675 int thr_setspecific_native (ACE_OS_thread_key_t key
, void *data
);
1676 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
1679 int thr_setspecific (ACE_thread_key_t key
, void *data
);
1681 ACE_NAMESPACE_INLINE_FUNCTION
1682 int thr_sigsetmask (int how
, const sigset_t
*nsm
, sigset_t
*osm
);
1684 ACE_NAMESPACE_INLINE_FUNCTION
1685 int thr_suspend (ACE_hthread_t target_thread
);
1687 ACE_NAMESPACE_INLINE_FUNCTION
1688 void thr_testcancel ();
1690 ACE_NAMESPACE_INLINE_FUNCTION
1693 //@{ @name A set of wrappers for mutex locks that only work within a single process.
1695 ACE_NAMESPACE_INLINE_FUNCTION
1696 int thread_mutex_destroy (ACE_thread_mutex_t
*m
);
1698 ACE_NAMESPACE_INLINE_FUNCTION
1699 int thread_mutex_init (ACE_thread_mutex_t
*m
,
1701 const char *name
= 0,
1702 ACE_mutexattr_t
*arg
= 0);
1704 #if defined (ACE_HAS_WCHAR)
1705 ACE_NAMESPACE_INLINE_FUNCTION
1706 int thread_mutex_init (ACE_thread_mutex_t
*m
,
1708 const wchar_t *name
,
1709 ACE_mutexattr_t
*arg
= 0);
1710 #endif /* ACE_HAS_WCHAR */
1712 ACE_NAMESPACE_INLINE_FUNCTION
1713 int thread_mutex_lock (ACE_thread_mutex_t
*m
);
1715 ACE_NAMESPACE_INLINE_FUNCTION
1716 int thread_mutex_lock (ACE_thread_mutex_t
*m
,
1717 const ACE_Time_Value
&timeout
);
1719 ACE_NAMESPACE_INLINE_FUNCTION
1720 int thread_mutex_lock (ACE_thread_mutex_t
*m
,
1721 const ACE_Time_Value
*timeout
);
1723 ACE_NAMESPACE_INLINE_FUNCTION
1724 int thread_mutex_trylock (ACE_thread_mutex_t
*m
);
1726 ACE_NAMESPACE_INLINE_FUNCTION
1727 int thread_mutex_unlock (ACE_thread_mutex_t
*m
);
1732 * This method uses process id and object pointer to come up with a
1733 * machine wide unique name. The process ID will provide uniqueness
1734 * between processes on the same machine. The "this" pointer of the
1735 * @a object will provide uniqueness between other "live" objects in
1736 * the same process. The uniqueness of this name is therefore only
1737 * valid for the life of @a object.
1740 void unique_name (const void *object
,
1743 #if defined (ACE_USES_WCHAR)
1745 void unique_name (const void *object
,
1748 #endif /* ACE_USES_WCHAR */
1749 } /* namespace ACE_OS */
1751 #if !defined (ACE_WIN32)
1753 /// Implementation details of Event emulation on Unix, may be in shared memory
1754 struct ACE_eventdata_t
1756 /// Protect critical section.
1759 /// Keeps track of waiters.
1760 ACE_cond_t condition_
;
1765 /// Specifies if this is an auto- or manual-reset event.
1768 /// "True" if signaled.
1771 /// Special bool for auto_events alone
1773 * The semantics of auto events forces us to introduce this extra
1774 * variable to ensure that the thread is not woken up
1775 * spuriously. Please see event_timedwait () to see
1776 * how this is used for auto_events.
1777 * @todo This is a hack that needs revisiting after x.4
1779 bool auto_event_signaled_
;
1781 /// Number of waiting threads.
1782 unsigned long waiting_threads_
;
1785 unsigned long signal_count_
;
1787 ACE_ALLOC_HOOK_DECLARE
;
1790 # if !defined ACE_USES_FIFO_SEM \
1791 && !(defined ACE_HAS_POSIX_SEM && defined ACE_HAS_POSIX_SEM_TIMEOUT \
1792 && !defined ACE_LACKS_NAMED_POSIX_SEM)
1793 # define ACE_EVENT_NO_FIFO_SEM
1796 # if (defined ACE_HAS_PTHREADS && defined _POSIX_THREAD_PROCESS_SHARED \
1797 && !defined ACE_LACKS_MUTEXATTR_PSHARED) || defined ACE_EVENT_NO_FIFO_SEM
1798 # define ACE_EVENT_USE_MUTEX_PSHARED 1
1800 # define ACE_EVENT_USE_MUTEX_PSHARED 0
1803 # if (defined ACE_HAS_PTHREADS && defined _POSIX_THREAD_PROCESS_SHARED \
1804 && !defined ACE_LACKS_CONDATTR_PSHARED \
1805 && !defined ACE_LACKS_MUTEXATTR_PSHARED) || defined ACE_EVENT_NO_FIFO_SEM
1806 # define ACE_EVENT_USE_COND_PSHARED 1
1808 # define ACE_EVENT_USE_COND_PSHARED 0
1812 * @class ACE_event_t
1814 * @brief Wrapper for NT events on UNIX.
1816 class ACE_Export ACE_event_t
1818 friend int ACE_OS::event_init (ACE_event_t
*, int, int, int, const char *,
1820 friend int ACE_OS::event_init (ACE_event_t
*, int, ACE_condattr_t
*, int,
1821 int, const char *, void *, int);
1822 friend int ACE_OS::event_destroy (ACE_event_t
*);
1823 friend int ACE_OS::event_wait (ACE_event_t
*);
1824 friend int ACE_OS::event_timedwait (ACE_event_t
*, ACE_Time_Value
*, int);
1825 friend int ACE_OS::event_signal (ACE_event_t
*);
1826 friend int ACE_OS::event_pulse (ACE_event_t
*);
1827 friend int ACE_OS::event_reset (ACE_event_t
*);
1830 /// Constructor initializing all pointer fields to null
1834 /// Lock the internal mutex/semaphore
1837 /// Unlock the internal mutex/semaphore
1840 /// Use the internal semaphore or condition variable to unblock one thread
1843 /// Event name if process shared.
1847 ACE_eventdata_t
*eventdata_
;
1849 # if !ACE_EVENT_USE_COND_PSHARED
1850 /// Keeps track of waiters.
1851 ACE_sema_t semaphore_
;
1854 # if !ACE_EVENT_USE_MUTEX_PSHARED
1855 /// Protect critical section.
1860 #endif /* ACE_WIN32 */
1862 ACE_END_VERSIONED_NAMESPACE_DECL
1864 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
1866 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
1869 * @class ACE_OS_Thread_Mutex_Guard
1871 * This data structure is meant to be used within an ACE_OS
1872 * function. It performs automatic aquisition and release of
1873 * an ACE_thread_mutex_t.
1875 * If an object of this class is instantiated before ACE_Object_Manager is
1876 * initialized, it will not do anything. This is because this class is
1877 * used only with the ACE_OS_GUARD macro which is passing a reference to
1878 * one of the preallocated Object Manager locks. If the object manager
1879 * hasn't been initialized yet, the lock reference is bogus. This is an
1880 * acceptable tradeoff since in cases where the lock reference is bogus,
1881 * there isn't multithreaded access. Please see detailed comments in
1882 * Object_Manager.h for further information.
1884 * For internal use only by ACE_OS.
1886 class ACE_OS_Thread_Mutex_Guard
1889 /// Implicitly and automatically acquire the lock.
1890 ACE_OS_Thread_Mutex_Guard (ACE_thread_mutex_t
&m
);
1892 /// Implicitly release the lock.
1893 ~ACE_OS_Thread_Mutex_Guard ();
1895 /// Explicitly acquire the lock.
1898 /// Explicitly release the lock.
1902 /// Reference to the mutex.
1903 ACE_thread_mutex_t
&lock_
;
1905 /// Keeps track of whether we acquired the lock or failed.
1908 ACE_OS_Thread_Mutex_Guard
&operator= (const ACE_OS_Thread_Mutex_Guard
&) = delete;
1909 ACE_OS_Thread_Mutex_Guard (const ACE_OS_Thread_Mutex_Guard
&) = delete;
1913 * @class ACE_OS_Recursive_Thread_Mutex_Guard
1915 * @brief For internal use only by ACE_OS.
1917 * This data structure is meant to be used within an ACE_OS
1918 * function. It performs automatic aquisition and release of
1919 * an ACE_recursive_thread_mutex_t.
1921 * If an object of this class is instantiated before ACE_Object_Manager is
1922 * initialized, it will not do anything. This is because this class is
1923 * used only with the ACE_TSS_GUARD macro which is passing a reference to
1924 * one of the preallocated Object Manager locks. If the object manager
1925 * hasn't been initialized yet, the lock reference is bogus. This is an
1926 * acceptable tradeoff since in cases where the lock reference is bogus,
1927 * there isn't multithreaded access. Please see detailed comments in
1928 * Object_Manager.h for further information.
1930 class ACE_OS_Recursive_Thread_Mutex_Guard
1933 /// Implicitly and automatically acquire the lock.
1934 ACE_OS_Recursive_Thread_Mutex_Guard (ACE_recursive_thread_mutex_t
&m
);
1936 /// Implicitly release the lock.
1937 ~ACE_OS_Recursive_Thread_Mutex_Guard ();
1939 /// Explicitly acquire the lock.
1942 /// Explicitly release the lock.
1946 /// Reference to the mutex.
1947 ACE_recursive_thread_mutex_t
&lock_
;
1949 /// Keeps track of whether we acquired the lock or failed.
1952 ACE_OS_Recursive_Thread_Mutex_Guard
&operator= (const ACE_OS_Recursive_Thread_Mutex_Guard
&) = delete;
1953 ACE_OS_Recursive_Thread_Mutex_Guard (const ACE_OS_Recursive_Thread_Mutex_Guard
&) = delete;
1956 ACE_END_VERSIONED_NAMESPACE_DECL
1958 // used in time and unistd
1959 # define ACE_OS_GUARD \
1960 ACE_OS_Thread_Mutex_Guard ace_os_guard__ (*(ACE_thread_mutex_t *) \
1961 ACE_OS_Object_Manager::preallocated_object[ \
1962 ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]);
1965 # define ACE_TSS_CLEANUP_GUARD \
1966 ACE_OS_Recursive_Thread_Mutex_Guard ace_tss_cleanup_guard__ (*(ACE_recursive_thread_mutex_t *) \
1967 ACE_OS_Object_Manager::preallocated_object[ \
1968 ACE_OS_Object_Manager::ACE_TSS_CLEANUP_LOCK]);
1971 # define ACE_TSS_BASE_GUARD \
1972 ACE_OS_Recursive_Thread_Mutex_Guard ace_tss_base_guard__ (*(ACE_recursive_thread_mutex_t *) \
1973 ACE_OS_Object_Manager::preallocated_object[ \
1974 ACE_OS_Object_Manager::ACE_TSS_BASE_LOCK]);
1976 #else /* ! ACE_MT_SAFE */
1977 # define ACE_OS_GUARD
1978 # define ACE_TSS_CLEANUP_GUARD
1979 # define ACE_TSS_BASE_GUARD
1980 #endif /* ! ACE_MT_SAFE */
1982 # if defined (ACE_HAS_INLINED_OSCALLS)
1983 # if defined (ACE_INLINE)
1985 # endif /* ACE_INLINE */
1986 # define ACE_INLINE inline
1987 # include "ace/OS_NS_Thread.inl"
1988 # endif /* ACE_HAS_INLINED_OSCALLS */
1990 # include /**/ "ace/post.h"
1991 #endif /* ACE_OS_NS_THREAD_H */