2 #include "ace/OS_NS_macros.h"
3 // for timespec_t, perhaps move it to os_time.h
4 #include "ace/Time_Value.h"
5 #include "ace/OS_NS_sys_mman.h"
6 #include "ace/OS_NS_sys_time.h"
7 #include "ace/OS_NS_string.h"
8 #include "ace/OS_NS_unistd.h"
9 #include "ace/OS_NS_stdio.h"
10 #include "ace/OS_NS_errno.h"
12 #if defined (ACE_USES_FIFO_SEM)
13 # include "ace/OS_NS_sys_stat.h"
14 # include "ace/OS_NS_sys_select.h"
15 # include "ace/OS_NS_fcntl.h"
16 # include "ace/Handle_Set.h"
17 # endif /* ACE_USES_FIFO_SEM */
19 #if defined (ACE_HAS_ALLOC_HOOKS)
20 # include "ace/Malloc_Base.h"
21 #endif /* ACE_HAS_ALLOC_HOOKS */
23 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
25 /*****************************************************************************/
27 #if defined (ACE_LACKS_COND_T) && defined (ACE_HAS_THREADS)
29 ACE_cond_t::waiters () const
31 return this->waiters_;
33 #endif /* ACE_LACKS_COND_T && ACE_HAS_THREADS */
35 /*****************************************************************************/
37 #if defined (ACE_HAS_TSS_EMULATION)
39 # if !defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
42 ACE_TSS_Emulation::tss_base ()
44 # if defined (ACE_HAS_VXTHREADS)
45 # if (!defined (_WRS_CONFIG_SMP) && !defined (INCLUDE_AMP_CPU))
46 if (taskVarGet(0, reinterpret_cast<int*>(&ace_tss_keys)) == ERROR)
47 taskVarAdd(0, reinterpret_cast<int*>(&ace_tss_keys));
49 return reinterpret_cast <void **&> (ace_tss_keys);
52 ACE_NOTSUP_RETURN (0);
53 # endif /* ACE_HAS_VXTHREADS */
55 # endif /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
58 ACE_TSS_Emulation::ACE_TSS_DESTRUCTOR
59 ACE_TSS_Emulation::tss_destructor (const ACE_thread_key_t key)
61 return tss_destructor_ [key];
66 ACE_TSS_Emulation::tss_destructor (const ACE_thread_key_t key,
67 ACE_TSS_DESTRUCTOR destructor)
69 tss_destructor_ [key] = destructor;
74 ACE_TSS_Emulation::ts_object (const ACE_thread_key_t key)
76 # if defined (ACE_HAS_VXTHREADS)
77 /* If someone wants tss_base make sure they get one. This
78 gets used if someone spawns a VxWorks task directly, not
79 through ACE. The allocated array will never be deleted! */
80 if (ace_tss_keys == 0)
82 ace_tss_keys = new void *[ACE_TSS_THREAD_KEYS_MAX];
84 // Zero the entire TSS array. Do it manually instead of using
85 // memset, for optimum speed. Though, memset may be faster :-)
86 void **tss_base_p = reinterpret_cast<void **> (ace_tss_keys);
87 for (u_int i = 0; i < ACE_TSS_THREAD_KEYS_MAX; ++i, ++tss_base_p)
92 # endif /* ACE_HAS_VXTHREADS */
94 return tss_base ()[key];
97 #endif /* ACE_HAS_TSS_EMULATION */
99 /*****************************************************************************/
102 ACE_OS::thr_equal (ACE_thread_t t1, ACE_thread_t t2)
104 #if defined (ACE_HAS_PTHREADS)
105 # if defined (pthread_equal)
106 // If it's a macro we can't say "pthread_equal"...
107 return pthread_equal (t1, t2);
109 return pthread_equal (t1, t2);
110 # endif /* pthread_equal */
111 #else /* For both STHREADS and WTHREADS... */
112 // Hum, Do we need to treat WTHREAD differently?
113 // levine 13 oct 98 % I don't think so, ACE_thread_t is a DWORD.
115 #endif /* ACE_HAS_PTHREADS */
119 ACE_OS::condattr_destroy (ACE_condattr_t &attributes)
121 #if defined (ACE_HAS_THREADS) && !defined (ACE_LACKS_CONDATTR)
122 # if defined (ACE_HAS_PTHREADS)
123 pthread_condattr_destroy (&attributes);
126 # endif /* ACE_HAS_PTHREADS */
129 ACE_UNUSED_ARG (attributes);
131 # endif /* ACE_HAS_THREADS */
135 ACE_OS::condattr_init (ACE_condattr_t &attributes, int type)
137 ACE_UNUSED_ARG (type);
138 # if defined (ACE_HAS_THREADS)
139 # if defined (ACE_HAS_PTHREADS)
142 # if !defined (ACE_LACKS_CONDATTR)
143 # if defined (ACE_PTHREAD_CONDATTR_T_INITIALIZE)
144 /* Tests show that VxWorks 6.x pthread lib does not only
145 * require zeroing of mutex/condition objects to function correctly
146 * but also of the attribute objects.
148 ACE_OS::memset (&attributes, 0, sizeof (attributes));
151 ACE_ADAPT_RETVAL (pthread_condattr_init (&attributes), result) == 0
152 # if defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)
153 && ACE_ADAPT_RETVAL (pthread_condattr_setpshared (&attributes, type),
155 # endif /* _POSIX_THREAD_PROCESS_SHARED && ! ACE_LACKS_CONDATTR_PSHARED */
158 if (type == USYNC_THREAD)
159 # endif /* !ACE_LACKS_CONDATTR */
163 ACE_UNUSED_ARG (attributes);
164 result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
169 attributes.type = type;
171 # endif /* ACE_HAS_PTHREADS */
174 ACE_UNUSED_ARG (attributes);
175 ACE_UNUSED_ARG (type);
176 ACE_NOTSUP_RETURN (-1);
177 # endif /* ACE_HAS_THREADS */
181 ACE_OS::condattr_synctype (ACE_condattr_t &attributes, int& type)
183 # if defined (ACE_HAS_THREADS)
184 # if defined (ACE_HAS_PTHREADS)
185 # if !defined (ACE_LACKS_CONDATTR) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)
189 ACE_ADAPT_RETVAL (pthread_condattr_getpshared (&attributes, &type),
196 ACE_UNUSED_ARG (attributes);
199 # endif /* !ACE_LACKS_CONDATTR && _POSIX_THREAD_PROCESS_SHARED && ! ACE_LACKS_CONDATTR_PSHARED */
203 type = attributes.type;
205 # endif /* ACE_HAS_PTHREADS */
208 ACE_UNUSED_ARG (attributes);
209 ACE_UNUSED_ARG (type);
210 ACE_NOTSUP_RETURN (-1);
211 # endif /* ACE_HAS_THREADS */
215 ACE_OS::condattr_setclock (ACE_condattr_t &attributes, clockid_t clock_id)
217 #if defined (ACE_HAS_CONDATTR_SETCLOCK) && !defined (ACE_LACKS_CONDATTR_SETCLOCK)
219 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_condattr_setclock (&attributes, clock_id),
224 ACE_UNUSED_ARG (clock_id);
225 ACE_UNUSED_ARG (attributes);
226 ACE_NOTSUP_RETURN (-1);
230 #if !defined (ACE_LACKS_COND_T)
231 // NOTE: The ACE_OS::cond_* functions for Unix platforms are defined
232 // here because the ACE_OS::sema_* functions below need them.
233 // However, ACE_WIN32 and VXWORKS define the ACE_OS::cond_* functions
234 // using the ACE_OS::sema_* functions. So, they are defined in OS_NS_Tread.cpp.
237 ACE_OS::cond_broadcast (ACE_cond_t *cv)
239 ACE_OS_TRACE ("ACE_OS::cond_broadcast");
240 # if defined (ACE_HAS_THREADS)
241 # if defined (ACE_HAS_PTHREADS)
243 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_broadcast (cv),
246 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
247 ::WakeAllConditionVariable (cv);
249 # endif /* ACE_HAS_PTHREADS */
252 ACE_NOTSUP_RETURN (-1);
253 # endif /* ACE_HAS_THREADS */
257 ACE_OS::cond_destroy (ACE_cond_t *cv)
259 ACE_OS_TRACE ("ACE_OS::cond_destroy");
260 # if defined (ACE_HAS_THREADS)
261 # if defined (ACE_HAS_PTHREADS)
263 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_destroy (cv), result), int);
264 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
265 // Windows doesn't have a destroy
267 # endif /* ACE_HAS_PTHREADS */
270 ACE_NOTSUP_RETURN (-1);
271 # endif /* ACE_HAS_THREADS */
275 ACE_OS::cond_init (ACE_cond_t *cv,
276 ACE_condattr_t &attributes,
280 // ACE_OS_TRACE ("ACE_OS::cond_init");
281 ACE_UNUSED_ARG (name);
282 ACE_UNUSED_ARG (arg);
283 # if defined (ACE_HAS_THREADS)
284 # if defined (ACE_HAS_PTHREADS)
287 # if defined (ACE_PTHREAD_COND_T_INITIALIZE)
288 /* VxWorks 6.x API reference states:
289 * If the memory for the condition variable object has been allocated
290 * dynamically, it is a good policy to always zero out the
291 * block of memory so as to avoid spurious EBUSY return code
292 * when calling this routine.
294 ACE_OS::memset (cv, 0, sizeof (*cv));
297 if (ACE_ADAPT_RETVAL (pthread_cond_init (cv, &attributes), result) == 0)
300 result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
303 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
304 ::InitializeConditionVariable (cv);
306 # endif /* ACE_HAS_PTHREADS */
309 ACE_UNUSED_ARG (attributes);
310 ACE_UNUSED_ARG (name);
311 ACE_UNUSED_ARG (arg);
312 ACE_NOTSUP_RETURN (-1);
313 # endif /* ACE_HAS_THREADS */
316 #if defined (ACE_HAS_WCHAR)
318 ACE_OS::cond_init (ACE_cond_t *cv,
319 ACE_condattr_t &attributes,
323 return ACE_OS::cond_init (cv, attributes, ACE_Wide_To_Ascii (name).char_rep (), arg);
325 #endif /* ACE_HAS_WCHAR */
327 #if defined (ACE_HAS_WCHAR)
329 ACE_OS::cond_init (ACE_cond_t *cv, short type, const wchar_t *name, void *arg)
331 return ACE_OS::cond_init (cv, type, ACE_Wide_To_Ascii (name).char_rep (), arg);
333 #endif /* ACE_HAS_WCHAR */
336 ACE_OS::cond_signal (ACE_cond_t *cv)
338 ACE_OS_TRACE ("ACE_OS::cond_signal");
339 # if defined (ACE_HAS_THREADS)
340 # if defined (ACE_HAS_PTHREADS)
342 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_signal (cv), result),
344 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
345 ::WakeConditionVariable (cv);
347 # endif /* ACE_HAS_PTHREADS */
350 ACE_NOTSUP_RETURN (-1);
351 # endif /* ACE_HAS_THREADS */
355 ACE_OS::cond_wait (ACE_cond_t *cv,
356 ACE_mutex_t *external_mutex)
358 ACE_OS_TRACE ("ACE_OS::cond_wait");
359 # if defined (ACE_HAS_THREADS)
360 # if defined (ACE_HAS_PTHREADS)
362 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_wait (cv, external_mutex), result),
364 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
366 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::SleepConditionVariableCS (cv, &external_mutex->thr_mutex_, INFINITE), result),
368 # endif /* ACE_HAS_PTHREADS */
371 ACE_UNUSED_ARG (external_mutex);
372 ACE_NOTSUP_RETURN (-1);
373 # endif /* ACE_HAS_THREADS */
377 ACE_OS::cond_timedwait (ACE_cond_t *cv,
378 ACE_mutex_t *external_mutex,
379 ACE_Time_Value *timeout)
381 ACE_OS_TRACE ("ACE_OS::cond_timedwait");
382 # if defined (ACE_HAS_THREADS)
387 ts = *timeout; // Calls ACE_Time_Value::operator timespec_t().
389 # if defined (ACE_HAS_PTHREADS)
391 ACE_OSCALL (ACE_ADAPT_RETVAL (timeout == 0
392 ? pthread_cond_wait (cv, external_mutex)
393 : pthread_cond_timedwait (cv, external_mutex,
394 (ACE_TIMESPEC_PTR) &ts),
397 // We need to adjust this to make the POSIX return
398 // values consistent. EAGAIN is from Pthreads DRAFT4
400 (errno == ETIMEDOUT || errno == EAGAIN))
403 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
404 int msec_timeout = 0;
407 ACE_Time_Value relative_time = timeout->to_relative_time ();
408 // Watchout for situations where a context switch has caused the
409 // current time to be > the timeout.
410 if (relative_time > ACE_Time_Value::zero)
411 msec_timeout = relative_time.msec ();
414 ACE_OSCALL (ACE_ADAPT_RETVAL (::SleepConditionVariableCS (cv, &external_mutex->thr_mutex_, msec_timeout),
419 # endif /* ACE_HAS_PTHREADS */
421 timeout->set (ts); // Update the time value before returning.
426 ACE_UNUSED_ARG (external_mutex);
427 ACE_UNUSED_ARG (timeout);
428 ACE_NOTSUP_RETURN (-1);
429 # endif /* ACE_HAS_THREADS */
431 #endif /* !ACE_LACKS_COND_T */
434 ACE_OS::mutex_lock (ACE_mutex_t *m,
435 const ACE_Time_Value *timeout)
437 return timeout == 0 ? ACE_OS::mutex_lock (m) : ACE_OS::mutex_lock (m, *timeout);
441 ACE_OS::event_wait (ACE_event_t *event)
443 return ACE_OS::event_timedwait (event, 0);
447 ACE_OS::event_init (ACE_event_t *event,
453 LPSECURITY_ATTRIBUTES sa)
455 ACE_condattr_t *pattr = 0;
456 return ACE_OS::event_init (event, type, pattr, manual_reset, initial_state, name, arg, sa);
459 #if defined (ACE_HAS_WCHAR)
461 ACE_OS::event_init (ACE_event_t *event,
467 LPSECURITY_ATTRIBUTES sa)
469 #if defined (ACE_WIN32)
470 ACE_UNUSED_ARG (type);
471 ACE_UNUSED_ARG (arg);
472 SECURITY_ATTRIBUTES sa_buffer;
473 SECURITY_DESCRIPTOR sd_buffer;
474 *event = ::CreateEventW (ACE_OS::default_win32_security_attributes_r
475 (sa, &sa_buffer, &sd_buffer),
480 ACE_FAIL_RETURN (-1);
482 // Make sure to set errno to ERROR_ALREADY_EXISTS if necessary.
483 ACE_OS::set_errno_to_last_error ();
485 #else /* ACE_WIN32 */
486 return ACE_OS::event_init (event,
490 ACE_Wide_To_Ascii (name).char_rep (),
493 #endif /* ACE_WIN32 */
497 ACE_OS::event_init (ACE_event_t *event,
499 ACE_condattr_t *attributes,
504 LPSECURITY_ATTRIBUTES sa)
506 #if defined (ACE_WIN32)
507 ACE_UNUSED_ARG (type);
508 ACE_UNUSED_ARG (attributes);
509 ACE_UNUSED_ARG (arg);
510 SECURITY_ATTRIBUTES sa_buffer;
511 SECURITY_DESCRIPTOR sd_buffer;
512 *event = ::CreateEventW (ACE_OS::default_win32_security_attributes_r
513 (sa, &sa_buffer, &sd_buffer),
518 ACE_FAIL_RETURN (-1);
520 // Make sure to set errno to ERROR_ALREADY_EXISTS if necessary.
521 ACE_OS::set_errno_to_last_error ();
523 #else /* ACE_WIN32 */
524 return ACE_OS::event_init (event,
529 ACE_Wide_To_Ascii (name).char_rep (),
532 #endif /* ACE_WIN32 */
534 #endif /* ACE_HAS_WCHAR */
537 ACE_OS::priority_control (ACE_idtype_t /*idtype*/, ACE_id_t /*identifier*/, int /*cmd*/, void * /*arg*/)
539 ACE_OS_TRACE ("ACE_OS::priority_control");
540 ACE_NOTSUP_RETURN (-1);
543 // This method is used to prepare the recursive mutex for releasing
544 // when waiting on a condition variable. If the platform doesn't have
545 // native recursive mutex and condition variable support, then ACE needs
546 // to save the recursion state around the wait and also ensure that the
547 // wait and lock release are atomic. recursive_mutex_cond_relock()
548 // is the inverse of this method.
550 ACE_OS::recursive_mutex_cond_unlock (ACE_recursive_thread_mutex_t *m,
551 ACE_recursive_mutex_state &state)
553 #if defined (ACE_HAS_THREADS)
554 ACE_OS_TRACE ("ACE_OS::recursive_mutex_cond_unlock");
555 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
556 // Windows need special handling since it has recursive mutexes, but
557 // does not integrate them into a condition variable.
558 # if defined (ACE_WIN32)
559 // For Windows, the OS takes care of the mutex and its recursion. We just
560 // need to release the lock one fewer times than this thread has acquired
561 // it. Remember how many times, and reacquire it that many more times when
562 // the condition is signaled.
564 // We're using undocumented fields in the CRITICAL_SECTION structure
565 // and they've been known to change across Windows variants and versions./
566 // So be careful if you need to change these - there may be other
567 // Windows variants that depend on existing values and limits.
569 state.relock_count_ = 0;
570 while (m->LockCount > 0 && m->RecursionCount > 1)
572 // This may fail if the current thread doesn't own the mutex. If it
573 // does fail, it'll be on the first try, so don't worry about resetting
575 if (ACE_OS::recursive_mutex_unlock (m) == -1)
577 ++state.relock_count_;
579 # else /* not ACE_WIN32 */
580 // prevent warnings for unused variables
581 ACE_UNUSED_ARG (state);
583 # endif /* ACE_WIN32 */
585 # else /* ACE_HAS_RECURSIVE_MUTEXES */
586 // For platforms without recursive mutexes, we obtain the nesting mutex
587 // to gain control over the mutex internals. Then set the internals to say
588 // the mutex is available. If there are waiters, signal the condition
589 // to notify them (this is mostly like the recursive_mutex_unlock() method).
590 // Then, return with the nesting mutex still held. The condition wait
591 // will release it atomically, allowing mutex waiters to continue.
592 // Note that this arrangement relies on the fact that on return from
593 // the condition wait, this thread will again own the nesting mutex
594 // and can either set the mutex internals directly or get in line for
595 // the mutex... this part is handled in recursive_mutex_cond_relock().
596 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
599 # if !defined (ACE_NDEBUG)
600 if (m->nesting_level_ == 0
601 || ACE_OS::thr_equal (ACE_OS::thr_self (), m->owner_id_) == 0)
603 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
607 # endif /* ACE_NDEBUG */
609 // To make error recovery a bit easier, signal the condition now. Any
610 // waiter won't regain control until the mutex is released, which won't
611 // be until the caller returns and does the wait on the condition.
612 if (ACE_OS::cond_signal (&m->lock_available_) == -1)
614 // Save/restore errno.
615 ACE_Errno_Guard error (errno);
616 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
620 // Ok, the nesting_mutex_ lock is still held, the condition has been
621 // signaled... reset the nesting info and return _WITH_ the lock
622 // held. The lock will be released when the condition waits, in the
624 state.nesting_level_ = m->nesting_level_;
625 state.owner_id_ = m->owner_id_;
626 m->nesting_level_ = 0;
627 m->owner_id_ = ACE_OS::NULL_thread;
629 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
632 ACE_UNUSED_ARG (state);
633 ACE_NOTSUP_RETURN (-1);
634 #endif /* ACE_HAS_THREADS */
638 // This method is called after waiting on a condition variable when a
639 // recursive mutex must be reacquired. If the platform doesn't natively
640 // integrate recursive mutexes and condition variables, it's taken care
641 // of here (inverse of ACE_OS::recursive_mutex_cond_unlock).
643 ACE_OS::recursive_mutex_cond_relock (ACE_recursive_thread_mutex_t *m,
644 ACE_recursive_mutex_state &state)
646 #if defined (ACE_HAS_THREADS)
647 ACE_OS_TRACE ("ACE_OS::recursive_mutex_cond_relock");
648 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
649 // Windows need special handling since it has recursive mutexes, but
650 // does not integrate them into a condition variable.
651 // On entry, the OS has already reacquired the lock for us. Just
652 // reacquire it the proper number of times so the recursion is the same as
653 // before waiting on the condition.
654 # if defined (ACE_WIN32)
655 while (state.relock_count_ > 0)
657 ACE_OS::recursive_mutex_lock (m);
658 --state.relock_count_;
661 # else /* not ACE_WIN32 */
662 // prevent warnings for unused variables
663 ACE_UNUSED_ARG (state);
666 # endif /* ACE_WIN32 */
668 // Without recursive mutex support, it's somewhat trickier. On entry,
669 // the current thread holds the nesting_mutex_, but another thread may
670 // still be holding the ACE_recursive_mutex_t. If so, mimic the code
671 // in ACE_OS::recursive_mutex_lock that waits to acquire the mutex.
672 // After acquiring it, restore the nesting counts and release the
673 // nesting mutex. This will restore the conditions to what they were
674 // before calling ACE_OS::recursive_mutex_cond_unlock().
675 while (m->nesting_level_ > 0)
676 ACE_OS::cond_wait (&m->lock_available_, &m->nesting_mutex_);
678 // At this point, we still have nesting_mutex_ and the mutex is free.
679 m->nesting_level_ = state.nesting_level_;
680 m->owner_id_ = state.owner_id_;
681 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
683 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
686 ACE_UNUSED_ARG (state);
688 #endif /* ACE_HAS_THREADS */
692 ACE_OS::recursive_mutex_destroy (ACE_recursive_thread_mutex_t *m)
694 #if defined (ACE_HAS_THREADS)
695 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
696 return ACE_OS::thread_mutex_destroy (m);
698 if (ACE_OS::cond_destroy (&m->lock_available_) == -1
699 || ACE_OS::thread_mutex_destroy (&m->nesting_mutex_) == -1)
702 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
705 ACE_NOTSUP_RETURN (-1);
706 #endif /* ACE_HAS_THREADS */
710 ACE_OS::recursive_mutex_init (ACE_recursive_thread_mutex_t *m,
711 const ACE_TCHAR *name,
712 ACE_mutexattr_t *arg,
713 LPSECURITY_ATTRIBUTES sa)
716 #if defined (ACE_HAS_THREADS)
717 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
718 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
719 return ACE_OS::thread_mutex_init (m, PTHREAD_MUTEX_RECURSIVE, name, arg);
721 return ACE_OS::thread_mutex_init (m, 0, name, arg);
722 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
724 if (ACE_OS::thread_mutex_init (&m->nesting_mutex_, 0, name, arg) == -1)
726 else if (ACE_OS::cond_init (&m->lock_available_,
727 (short) USYNC_THREAD,
733 m->nesting_level_ = 0;
734 m->owner_id_ = ACE_OS::NULL_thread;
737 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
740 ACE_UNUSED_ARG (name);
741 ACE_UNUSED_ARG (arg);
742 ACE_NOTSUP_RETURN (-1);
743 #endif /* ACE_HAS_THREADS */
747 ACE_OS::recursive_mutex_lock (ACE_recursive_thread_mutex_t *m)
749 #if defined (ACE_HAS_THREADS)
750 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
751 return ACE_OS::thread_mutex_lock (m);
753 ACE_thread_t const t_id = ACE_OS::thr_self ();
756 // Acquire the guard.
757 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
761 // If there's no contention, just grab the lock immediately
762 // (since this is the common case we'll optimize for it).
763 if (m->nesting_level_ == 0)
765 // If we already own the lock, then increment the nesting level
767 else if (ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
769 // Wait until the nesting level has dropped to zero, at
770 // which point we can acquire the lock.
771 while (m->nesting_level_ > 0)
772 ACE_OS::cond_wait (&m->lock_available_,
775 // At this point the nesting_mutex_ is held...
779 // At this point, we can safely increment the nesting_level_ no
780 // matter how we got here!
785 // Save/restore errno.
786 ACE_Errno_Guard error (errno);
787 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
790 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
793 ACE_NOTSUP_RETURN (-1);
794 #endif /* ACE_HAS_THREADS */
798 ACE_OS::recursive_mutex_lock (ACE_recursive_thread_mutex_t *m,
799 const ACE_Time_Value &timeout)
801 #if defined (ACE_HAS_THREADS)
802 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
803 return ACE_OS::thread_mutex_lock (m, timeout);
805 ACE_thread_t t_id = ACE_OS::thr_self ();
808 // Try to acquire the guard.
809 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_, timeout) == -1)
813 // If there's no contention, just grab the lock immediately
814 // (since this is the common case we'll optimize for it).
815 if (m->nesting_level_ == 0)
817 // If we already own the lock, then increment the nesting level
819 else if (ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
821 // Wait until the nesting level has dropped to zero, at
822 // which point we can acquire the lock.
823 while (m->nesting_level_ > 0)
825 result = ACE_OS::cond_timedwait (&m->lock_available_,
827 const_cast <ACE_Time_Value *> (&timeout));
829 // The mutex is reacquired even in the case of a timeout
830 // release the mutex to prevent a deadlock
833 // Save/restore errno.
834 ACE_Errno_Guard error (errno);
835 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
841 // At this point the nesting_mutex_ is held...
845 // At this point, we can safely increment the nesting_level_ no
846 // matter how we got here!
849 // Save/restore errno.
850 ACE_Errno_Guard error (errno);
851 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
854 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
857 ACE_UNUSED_ARG (timeout);
858 ACE_NOTSUP_RETURN (-1);
859 #endif /* ACE_HAS_THREADS */
863 ACE_OS::recursive_mutex_lock (ACE_recursive_thread_mutex_t *m,
864 const ACE_Time_Value *timeout)
867 ? ACE_OS::recursive_mutex_lock (m)
868 : ACE_OS::recursive_mutex_lock (m, *timeout);
872 ACE_OS::recursive_mutex_trylock (ACE_recursive_thread_mutex_t *m)
874 #if defined (ACE_HAS_THREADS)
875 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
876 return ACE_OS::thread_mutex_trylock (m);
878 ACE_thread_t t_id = ACE_OS::thr_self ();
881 // Acquire the guard.
882 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
886 // If there's no contention, just grab the lock immediately.
887 if (m->nesting_level_ == 0)
890 m->nesting_level_ = 1;
892 // If we already own the lock, then increment the nesting level
894 else if (ACE_OS::thr_equal (t_id, m->owner_id_))
904 // Save/restore errno.
905 ACE_Errno_Guard error (errno);
906 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
909 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
912 ACE_NOTSUP_RETURN (-1);
913 #endif /* ACE_HAS_THREADS */
917 ACE_OS::recursive_mutex_unlock (ACE_recursive_thread_mutex_t *m)
919 #if defined (ACE_HAS_THREADS)
920 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
921 return ACE_OS::thread_mutex_unlock (m);
923 ACE_OS_TRACE ("ACE_OS::recursive_mutex_unlock");
924 # if !defined (ACE_NDEBUG)
925 ACE_thread_t t_id = ACE_OS::thr_self ();
926 # endif /* ACE_NDEBUG */
929 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
933 # if !defined (ACE_NDEBUG)
934 if (m->nesting_level_ == 0
935 || ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
941 # endif /* ACE_NDEBUG */
944 if (m->nesting_level_ == 0)
946 // This may not be strictly necessary, but it does put
947 // the mutex into a known state...
948 m->owner_id_ = ACE_OS::NULL_thread;
950 // Inform a waiter that the lock is free.
951 if (ACE_OS::cond_signal (&m->lock_available_) == -1)
958 // Save/restore errno.
959 ACE_Errno_Guard error (errno);
960 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
963 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
966 ACE_NOTSUP_RETURN (-1);
967 #endif /* ACE_HAS_THREADS */
971 ACE_OS::rw_rdlock (ACE_rwlock_t *rw)
973 ACE_OS_TRACE ("ACE_OS::rw_rdlock");
974 #if defined (ACE_HAS_THREADS)
975 # if !defined (ACE_LACKS_RWLOCK_T)
976 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
978 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_rdlock (rw),
981 # else /* ACE_HAS_PTHREADS_UNIX98_EXT */
983 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_rdlock (rw), result), int);
984 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
985 # else /* NT, POSIX, and VxWorks don't support this natively. */
986 # if defined (ACE_HAS_PTHREADS)
987 ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
988 # endif /* ACE_HAS_PTHREADS */
990 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
991 result = -1; // -1 means didn't get the mutex.
994 // Give preference to writers who are waiting.
995 while (rw->ref_count_ < 0 || rw->num_waiting_writers_ > 0)
997 rw->num_waiting_readers_++;
998 if (ACE_OS::cond_wait (&rw->waiting_readers_, &rw->lock_) == -1)
1000 result = -2; // -2 means that we need to release the mutex.
1003 rw->num_waiting_readers_--;
1009 ACE_OS::mutex_unlock (&rw->lock_);
1010 # if defined (ACE_HAS_PTHREADS)
1011 ACE_PTHREAD_CLEANUP_POP (0);
1012 # endif /* defined (ACE_HAS_PTHREADS) */
1014 # endif /* ! ACE_LACKS_RWLOCK_T */
1016 ACE_UNUSED_ARG (rw);
1017 ACE_NOTSUP_RETURN (-1);
1018 #endif /* ACE_HAS_THREADS */
1022 ACE_OS::rw_tryrdlock (ACE_rwlock_t *rw)
1024 ACE_OS_TRACE ("ACE_OS::rw_tryrdlock");
1025 #if defined (ACE_HAS_THREADS)
1026 # if !defined (ACE_LACKS_RWLOCK_T)
1027 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1029 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_tryrdlock (rw),
1032 # else /* ACE_HAS_PTHREADS_UNIX98_EXT */
1034 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_tryrdlock (rw), result), int);
1035 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1036 # else /* NT, POSIX, and VxWorks don't support this natively. */
1039 if (ACE_OS::mutex_lock (&rw->lock_) != -1)
1041 ACE_Errno_Guard error (errno);
1043 if (rw->ref_count_ == -1 || rw->num_waiting_writers_ > 0)
1054 ACE_OS::mutex_unlock (&rw->lock_);
1057 # endif /* ! ACE_LACKS_RWLOCK_T */
1059 ACE_UNUSED_ARG (rw);
1060 ACE_NOTSUP_RETURN (-1);
1061 #endif /* ACE_HAS_THREADS */
1065 ACE_OS::rw_trywrlock (ACE_rwlock_t *rw)
1067 ACE_OS_TRACE ("ACE_OS::rw_trywrlock");
1068 #if defined (ACE_HAS_THREADS)
1069 # if !defined (ACE_LACKS_RWLOCK_T)
1070 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1072 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_trywrlock (rw),
1075 # else /* ACE_HAS_PTHREADS_UNIX98_EXT */
1077 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_trywrlock (rw), result), int);
1078 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1079 # else /* NT, POSIX, and VxWorks don't support this natively. */
1082 if (ACE_OS::mutex_lock (&rw->lock_) != -1)
1084 ACE_Errno_Guard error (errno);
1086 if (rw->ref_count_ != 0)
1093 rw->ref_count_ = -1;
1097 ACE_OS::mutex_unlock (&rw->lock_);
1100 # endif /* ! ACE_LACKS_RWLOCK_T */
1102 ACE_UNUSED_ARG (rw);
1103 ACE_NOTSUP_RETURN (-1);
1104 #endif /* ACE_HAS_THREADS */
1107 // Note that the caller of this method *must* already possess this
1108 // lock as a read lock.
1109 // return {-1 and no errno set means: error,
1110 // -1 and errno==EBUSY set means: could not upgrade,
1111 // 0 means: upgraded successfully}
1114 ACE_OS::rw_trywrlock_upgrade (ACE_rwlock_t *rw)
1116 ACE_OS_TRACE ("ACE_OS::rw_trywrlock_upgrade");
1117 #if defined (ACE_HAS_THREADS)
1118 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT) && !defined (ACE_LACKS_RWLOCK_T)
1120 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_trywrlock (rw),
1123 # elif !defined (ACE_LACKS_RWLOCK_T)
1124 // Some native rwlocks
1125 ACE_UNUSED_ARG (rw);
1126 ACE_NOTSUP_RETURN (-1);
1127 # else /* NT, POSIX, and VxWorks don't support this natively. */
1128 // The ACE rwlock emulation does support upgrade . . .
1131 # if defined (ACE_HAS_PTHREADS)
1132 ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
1133 # endif /* defined (ACE_HAS_PTHREADS) */
1135 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
1137 // -1 means didn't get the mutex, error
1138 else if (rw->important_writer_)
1139 // an other reader upgrades already
1146 while (rw->ref_count_ > 1) // wait until only I am left
1148 rw->num_waiting_writers_++; // prohibit any more readers
1149 rw->important_writer_ = true;
1151 if (ACE_OS::cond_wait (&rw->waiting_important_writer_, &rw->lock_) == -1)
1154 // we know that we have the lock again, we have this guarantee,
1155 // but something went wrong
1157 rw->important_writer_ = false;
1158 rw->num_waiting_writers_--;
1162 // nothing bad happend
1163 rw->ref_count_ = -1;
1164 // now I am a writer
1165 // everything is O.K.
1169 ACE_OS::mutex_unlock (&rw->lock_);
1171 # if defined (ACE_HAS_PTHREADS)
1172 ACE_PTHREAD_CLEANUP_POP (0);
1173 # endif /* defined (ACE_HAS_PTHREADS) */
1177 # endif /* ! ACE_LACKS_RWLOCK_T */
1179 ACE_UNUSED_ARG (rw);
1180 ACE_NOTSUP_RETURN (-1);
1181 #endif /* ACE_HAS_THREADS */
1185 ACE_OS::rw_unlock (ACE_rwlock_t *rw)
1187 ACE_OS_TRACE ("ACE_OS::rw_unlock");
1188 #if defined (ACE_HAS_THREADS)
1189 # if !defined (ACE_LACKS_RWLOCK_T)
1190 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1192 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_unlock (rw),
1195 # else /* ACE_HAS_PTHREADS_UNIX98_EXT */
1197 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_unlock (rw), result), int);
1198 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1199 # else /* NT, POSIX, and VxWorks don't support this natively. */
1200 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
1203 if (rw->ref_count_ > 0) // Releasing a reader.
1205 else if (rw->ref_count_ == -1) // Releasing a writer.
1209 (void) ACE_OS::mutex_unlock (&rw->lock_);
1210 return -1; // @@ ACE_ASSERT (!"count should not be 0!\n");
1214 ACE_Errno_Guard error (errno);
1216 if (rw->important_writer_ && rw->ref_count_ == 1)
1217 // only the reader requesting to upgrade its lock is left over.
1219 result = ACE_OS::cond_signal (&rw->waiting_important_writer_);
1222 else if (rw->num_waiting_writers_ > 0 && rw->ref_count_ == 0)
1223 // give preference to writers over readers...
1225 result = ACE_OS::cond_signal (&rw->waiting_writers_);
1228 else if (rw->num_waiting_readers_ > 0 && rw->num_waiting_writers_ == 0)
1230 result = ACE_OS::cond_broadcast (&rw->waiting_readers_);
1234 (void) ACE_OS::mutex_unlock (&rw->lock_);
1236 # endif /* ! ace_lacks_rwlock_t */
1238 ACE_UNUSED_ARG (rw);
1239 ACE_NOTSUP_RETURN (-1);
1240 #endif /* ace_has_threads */
1244 ACE_OS::rw_wrlock (ACE_rwlock_t *rw)
1246 ACE_OS_TRACE ("ACE_OS::rw_wrlock");
1247 #if defined (ACE_HAS_THREADS)
1248 # if !defined (ACE_LACKS_RWLOCK_T)
1249 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1251 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_wrlock (rw),
1254 # else /* ACE_HAS_PTHREADS_UNIX98_EXT */
1256 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_wrlock (rw), result), int);
1257 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1258 # else /* NT, POSIX, and VxWorks don't support this natively. */
1259 # if defined (ACE_HAS_PTHREADS)
1260 ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
1261 # endif /* defined (ACE_HAS_PTHREADS) */
1264 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
1265 result = -1; // -1 means didn't get the mutex.
1268 while (rw->ref_count_ != 0)
1270 rw->num_waiting_writers_++;
1272 if (ACE_OS::cond_wait (&rw->waiting_writers_, &rw->lock_) == -1)
1274 result = -2; // -2 means we need to release the mutex.
1278 rw->num_waiting_writers_--;
1282 rw->ref_count_ = -1;
1284 ACE_OS::mutex_unlock (&rw->lock_);
1285 # if defined (ACE_HAS_PTHREADS)
1286 ACE_PTHREAD_CLEANUP_POP (0);
1287 # endif /* defined (ACE_HAS_PTHREADS) */
1289 # endif /* ! ACE_LACKS_RWLOCK_T */
1291 ACE_UNUSED_ARG (rw);
1292 ACE_NOTSUP_RETURN (-1);
1293 #endif /* ACE_HAS_THREADS */
1297 ACE_OS::rwlock_destroy (ACE_rwlock_t *rw)
1299 ACE_OS_TRACE ("ACE_OS::rwlock_destroy");
1300 #if defined (ACE_HAS_THREADS)
1301 # if !defined (ACE_LACKS_RWLOCK_T)
1302 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1304 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_destroy (rw),
1307 # else /* ACE_HAS_PTHREADS_UNIX98_EXT */
1309 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rwlock_destroy (rw), result), int);
1310 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1311 # else /* NT, POSIX, and VxWorks don't support this natively. */
1312 ACE_OS::mutex_destroy (&rw->lock_);
1313 ACE_OS::cond_destroy (&rw->waiting_readers_);
1314 ACE_OS::cond_destroy (&rw->waiting_important_writer_);
1315 return ACE_OS::cond_destroy (&rw->waiting_writers_);
1316 # endif /* !defined (ACE_LACKS_RWLOCK_T) */
1318 ACE_UNUSED_ARG (rw);
1319 ACE_NOTSUP_RETURN (-1);
1320 #endif /* ACE_HAS_THREADS */
1323 #if defined (ACE_HAS_THREADS) && !defined (ACE_LACKS_RWLOCK_T)
1325 ACE_OS::rwlock_init (ACE_rwlock_t *rw,
1327 const ACE_TCHAR *name,
1330 // ACE_OS_TRACE ("ACE_OS::rwlock_init");
1331 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1332 ACE_UNUSED_ARG (name);
1333 ACE_UNUSED_ARG (arg);
1336 pthread_rwlockattr_t attr;
1337 pthread_rwlockattr_init (&attr);
1338 # if !defined (ACE_LACKS_RWLOCKATTR_PSHARED)
1339 pthread_rwlockattr_setpshared (&attr, (type == USYNC_THREAD ?
1340 PTHREAD_PROCESS_PRIVATE :
1341 PTHREAD_PROCESS_SHARED));
1343 ACE_UNUSED_ARG (type);
1344 # endif /* !ACE_LACKS_RWLOCKATTR_PSHARED */
1345 status = ACE_ADAPT_RETVAL (pthread_rwlock_init (rw, &attr), status);
1346 pthread_rwlockattr_destroy (&attr);
1354 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rwlock_init (rw, type, arg), result), int);
1355 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1357 #endif /* ACE_HAS_THREADS && !defined (ACE_LACKS_RWLOCK_T) */
1360 ACE_OS::sema_destroy (ACE_sema_t *s)
1362 ACE_OS_TRACE ("ACE_OS::sema_destroy");
1363 #if defined (ACE_HAS_POSIX_SEM)
1365 # if !defined (ACE_HAS_POSIX_SEM_TIMEOUT) && !defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
1366 ACE_OS::mutex_destroy (&s->lock_);
1367 ACE_OS::cond_destroy (&s->count_nonzero_);
1368 # endif /* !ACE_HAS_POSIX_SEM_TIMEOUT && !ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION */
1369 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1372 // Only destroy the semaphore if we're the ones who
1374 # if !defined (ACE_LACKS_SEM_DESTROY)
1375 ACE_OSCALL (::sem_destroy (s->sema_),int, result);
1376 # endif /* ACE_LACKS_SEM_DESTROY */
1377 ACE_OS::shm_unlink (s->name_);
1384 if (!s->avoid_unlink_)
1385 ACE_OS::sema_unlink (s->name_);
1386 #if defined (ACE_HAS_ALLOC_HOOKS)
1387 ACE_Allocator::instance()->free ((void *) s->name_);
1389 ACE_OS::free ((void *) s->name_);
1390 #endif /* ACE_HAS_ALLOC_HOOKS */
1391 return ::sem_close (s->sema_);
1393 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1396 # if !defined (ACE_LACKS_UNNAMED_SEMAPHORE) && !defined (ACE_LACKS_SEM_DESTROY)
1397 ACE_OSCALL (::sem_destroy (s->sema_), int, result);
1398 # endif /* !ACE_LACKS_UNNAMED_SEMAPHORE && !ACE_LACKS_SEM_DESTROY */
1399 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1401 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1402 #if defined (ACE_HAS_ALLOC_HOOKS)
1403 ACE_Allocator::instance()->free(s->sema_);
1406 #endif /* ACE_HAS_ALLOC_HOOKS */
1410 #elif defined (ACE_USES_FIFO_SEM)
1414 r0 = ACE_OS::unlink (s->name_);
1415 #if defined (ACE_HAS_ALLOC_HOOKS)
1416 ACE_Allocator::instance()->free ((void *) s->name_);
1418 ACE_OS::free ((void *) s->name_);
1419 #endif /* ACE_HAS_ALLOC_HOOKS */
1422 int r1 = ACE_OS::close (s->fd_[0]); /* ignore error */
1423 int r2 = ACE_OS::close (s->fd_[1]); /* ignore error */
1424 return r0 != 0 || r1 != 0 || r2 != 0 ? -1 : 0;
1425 #elif defined (ACE_HAS_THREADS)
1426 # if defined (ACE_HAS_PTHREADS)
1427 int r1 = ACE_OS::mutex_destroy (&s->lock_);
1428 int r2 = ACE_OS::cond_destroy (&s->count_nonzero_);
1429 return r1 != 0 || r2 != 0 ? -1 : 0;
1430 # elif defined (ACE_HAS_WTHREADS)
1431 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (*s), ace_result_), int, -1);
1432 # elif defined (ACE_VXWORKS)
1434 ACE_OSCALL (::semDelete (s->sema_), int, result);
1437 # endif /* ACE_HAS_PTHREADS */
1440 ACE_NOTSUP_RETURN (-1);
1441 #endif /* ACE_HAS_POSIX_SEM */
1444 // NOTE: The previous four function definitions must appear before
1445 // ACE_OS::sema_init ().
1447 ACE_OS::sema_init (ACE_sema_t *s,
1453 LPSECURITY_ATTRIBUTES sa)
1455 ACE_condattr_t *pattr = 0;
1456 return ACE_OS::sema_init (s, count, type, pattr, name, arg, max, sa);
1460 ACE_OS::sema_init (ACE_sema_t *s,
1463 ACE_condattr_t *attributes,
1467 LPSECURITY_ATTRIBUTES sa)
1469 ACE_OS_TRACE ("ACE_OS::sema_init");
1470 #if defined (ACE_HAS_POSIX_SEM)
1471 ACE_UNUSED_ARG (max);
1472 ACE_UNUSED_ARG (sa);
1475 s->avoid_unlink_ = false;
1476 # if defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
1477 ACE_UNUSED_ARG (arg);
1478 ACE_UNUSED_ARG (attributes);
1482 if (ACE_OS::mutex_init (&s->lock_, type, name,
1483 (ACE_mutexattr_t *) arg) == 0
1484 && (attributes == 0 ?
1485 ACE_OS::cond_init (&s->count_nonzero_, (short)type, name, arg) :
1486 ACE_OS::cond_init (&s->count_nonzero_, *attributes, name, arg)) == 0
1487 && ACE_OS::mutex_lock (&s->lock_) == 0)
1489 if (ACE_OS::mutex_unlock (&s->lock_) == 0)
1495 ACE_OS::mutex_destroy (&s->lock_);
1496 ACE_OS::cond_destroy (&s->count_nonzero_);
1499 # endif /* ACE_HAS_POSIX_SEM_TIMEOUT || ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION */
1501 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1502 s->new_sema_ = false;
1503 if (type == USYNC_PROCESS)
1505 // Let's see if it already exists.
1506 ACE_HANDLE fd = ACE_OS::shm_open (ACE_TEXT_CHAR_TO_TCHAR (name),
1507 O_RDWR | O_CREAT | O_EXCL,
1508 ACE_DEFAULT_FILE_PERMS);
1509 if (fd == ACE_INVALID_HANDLE)
1511 if (errno == EEXIST)
1512 fd = ACE_OS::shm_open (ACE_TEXT_CHAR_TO_TCHAR (name),
1514 ACE_DEFAULT_FILE_PERMS);
1520 // We own this shared memory object! Let's set its
1522 if (ACE_OS::ftruncate (fd,
1523 sizeof (ACE_sema_t)) == -1)
1525 s->name_ = ACE_OS::strdup (name);
1532 s->sema_ = (sem_t *)
1534 sizeof (ACE_sema_t),
1540 if (s->sema_ == (sem_t *) MAP_FAILED)
1543 // @@ According UNIX Network Programming V2 by Stevens,
1544 // sem_init() is currently not required to return zero on
1545 // success, but it *does* return -1 upon failure. For
1546 // this reason, check for failure by comparing to -1,
1547 // instead of checking for success by comparing to zero.
1549 // Only initialize it if we're the one who created it.
1550 && ::sem_init (s->sema_, type == USYNC_PROCESS, count) == -1)
1557 ACE_ALLOCATOR_RETURN (s->name_,
1558 ACE_OS::strdup (name),
1560 s->sema_ = ::sem_open (s->name_,
1562 ACE_DEFAULT_FILE_PERMS,
1564 if (s->sema_ == (sem_t *) SEM_FAILED)
1569 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1572 # if defined (ACE_LACKS_UNNAMED_SEMAPHORE)
1573 ACE_NOTSUP_RETURN (-1);
1575 #if defined (ACE_HAS_ALLOC_HOOKS)
1576 ACE_ALLOCATOR_RETURN (s->sema_,
1577 static_cast<sem_t*>(ACE_Allocator::instance()->malloc(sizeof(sem_t))),
1580 ACE_NEW_RETURN (s->sema_,
1583 #endif /* ACE_HAS_ALLOC_HOOKS */
1585 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1586 s->new_sema_ = true;
1587 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1588 ACE_OS::memset(s->sema_, 0, sizeof(*s->sema_));
1589 return ::sem_init (s->sema_, type != USYNC_THREAD, count);
1590 # endif /* ACE_LACKS_UNNAMED_SEMAPHORE */
1593 #elif defined (ACE_USES_FIFO_SEM)
1594 ACE_UNUSED_ARG (arg);
1595 ACE_UNUSED_ARG (max);
1596 ACE_UNUSED_ARG (sa);
1598 mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP;
1600 if (type == USYNC_THREAD)
1602 // Create systemwide unique name for semaphore
1603 char uname[ACE_UNIQUE_NAME_LEN];
1604 ACE_OS::unique_name ((const void *) s,
1606 ACE_UNIQUE_NAME_LEN);
1611 s->fd_[0] = s->fd_[1] = ACE_INVALID_HANDLE;
1612 bool creator = false;
1614 if (ACE_OS::mkfifo (ACE_TEXT_CHAR_TO_TCHAR (name), mode) < 0)
1616 if (errno != EEXIST) /* already exists OK else ERR */
1618 // check if this is a real FIFO, not just some other existing file
1620 if (ACE_OS::stat (name, &fs))
1622 if (!S_ISFIFO (fs.st_mode))
1624 // existing file is not a FIFO
1630 creator = true; // remember we created it for initialization at end
1632 // for processshared semaphores remember who we are to be able to remove
1633 // the FIFO when we're done with it
1634 if (type == USYNC_PROCESS)
1636 s->name_ = ACE_OS::strdup (name);
1640 ACE_OS::unlink (name);
1645 if ((s->fd_[0] = ACE_OS::open (name, O_RDONLY | O_NONBLOCK)) == ACE_INVALID_HANDLE
1646 || (s->fd_[1] = ACE_OS::open (name, O_WRONLY | O_NONBLOCK)) == ACE_INVALID_HANDLE)
1649 /* turn off nonblocking for fd_[0] */
1650 if ((flags = ACE_OS::fcntl (s->fd_[0], F_GETFL, 0)) < 0)
1653 flags &= ~O_NONBLOCK;
1654 if (ACE_OS::fcntl (s->fd_[0], F_SETFL, flags) < 0)
1657 //if (s->name_ && count)
1658 if (creator && count)
1661 for (u_int i=0; i<count ;++i)
1662 if (ACE_OS::write (s->fd_[1], &c, sizeof (char)) != 1)
1666 // In the case of process scope semaphores we can already unlink the FIFO now that
1667 // we completely set it up (the opened handles will keep it active until we close
1668 // thos down). This way we're protected against unexpected crashes as far as removal
1670 // Unfortunately this does not work for processshared FIFOs since as soon as we
1671 // have unlinked the semaphore no other process will be able to open it anymore.
1672 if (type == USYNC_THREAD)
1674 ACE_OS::unlink (name);
1678 #elif defined (ACE_HAS_THREADS)
1679 # if defined (ACE_HAS_PTHREADS)
1680 ACE_UNUSED_ARG (max);
1681 ACE_UNUSED_ARG (sa);
1684 if (ACE_OS::mutex_init (&s->lock_, type, name,
1685 (ACE_mutexattr_t *) arg) == 0
1686 && (attributes == 0 ?
1687 ACE_OS::cond_init (&s->count_nonzero_, (short)type, name, arg) :
1688 ACE_OS::cond_init (&s->count_nonzero_, *attributes, name, arg)) == 0
1689 && ACE_OS::mutex_lock (&s->lock_) == 0)
1694 if (ACE_OS::mutex_unlock (&s->lock_) == 0)
1700 ACE_OS::mutex_destroy (&s->lock_);
1701 ACE_OS::cond_destroy (&s->count_nonzero_);
1704 # elif defined (ACE_HAS_WTHREADS)
1705 ACE_UNUSED_ARG (attributes);
1706 ACE_UNUSED_ARG (type);
1707 ACE_UNUSED_ARG (arg);
1708 // Create the semaphore with its value initialized to <count> and
1709 // its maximum value initialized to <max>.
1710 SECURITY_ATTRIBUTES sa_buffer;
1711 SECURITY_DESCRIPTOR sd_buffer;
1712 *s = ACE_TEXT_CreateSemaphore
1713 (ACE_OS::default_win32_security_attributes_r (sa, &sa_buffer, &sd_buffer),
1716 ACE_TEXT_CHAR_TO_TCHAR (name));
1719 ACE_FAIL_RETURN (-1);
1723 // Make sure to set errno to ERROR_ALREADY_EXISTS if necessary.
1724 ACE_OS::set_errno_to_last_error ();
1727 # elif defined (ACE_VXWORKS)
1728 ACE_UNUSED_ARG (attributes);
1729 ACE_UNUSED_ARG (name);
1730 ACE_UNUSED_ARG (arg);
1731 ACE_UNUSED_ARG (max);
1732 ACE_UNUSED_ARG (sa);
1734 s->sema_ = ::semCCreate (type, count);
1735 return s->sema_ ? 0 : -1;
1736 # endif /* ACE_HAS_PTHREADS */
1739 ACE_UNUSED_ARG (count);
1740 ACE_UNUSED_ARG (type);
1741 ACE_UNUSED_ARG (attributes);
1742 ACE_UNUSED_ARG (name);
1743 ACE_UNUSED_ARG (arg);
1744 ACE_UNUSED_ARG (max);
1745 ACE_UNUSED_ARG (sa);
1746 ACE_NOTSUP_RETURN (-1);
1747 #endif /* ACE_HAS_POSIX_SEM */
1750 #if defined (ACE_HAS_WCHAR)
1752 ACE_OS::sema_init (ACE_sema_t *s,
1755 const wchar_t *name,
1758 LPSECURITY_ATTRIBUTES sa)
1760 ACE_condattr_t *pattr = 0;
1761 return ACE_OS::sema_init (s, count, type, pattr, name, arg, max, sa);
1765 ACE_OS::sema_init (ACE_sema_t *s,
1768 ACE_condattr_t *attributes,
1769 const wchar_t *name,
1772 LPSECURITY_ATTRIBUTES sa)
1774 # if defined (ACE_HAS_WTHREADS)
1775 ACE_UNUSED_ARG (attributes);
1776 ACE_UNUSED_ARG (type);
1777 ACE_UNUSED_ARG (arg);
1778 // Create the semaphore with its value initialized to <count> and
1779 // its maximum value initialized to <max>.
1780 SECURITY_ATTRIBUTES sa_buffer;
1781 SECURITY_DESCRIPTOR sd_buffer;
1782 *s = ::CreateSemaphoreW
1783 (ACE_OS::default_win32_security_attributes_r (sa, &sa_buffer, &sd_buffer),
1789 ACE_FAIL_RETURN (-1);
1793 // Make sure to set errno to ERROR_ALREADY_EXISTS if necessary.
1794 ACE_OS::set_errno_to_last_error ();
1797 # else /* ACE_HAS_WTHREADS */
1798 // Just call the normal char version.
1799 return ACE_OS::sema_init (s, count, type, attributes, ACE_Wide_To_Ascii (name).char_rep (), arg, max, sa);
1800 # endif /* ACE_HAS_WTHREADS */
1802 #endif /* ACE_HAS_WCHAR */
1805 ACE_OS::sema_avoid_unlink (ACE_sema_t *s, bool avoid_unlink)
1807 #if defined (ACE_HAS_POSIX_SEM)
1808 s->avoid_unlink_ = avoid_unlink;
1811 ACE_UNUSED_ARG (avoid_unlink);
1816 ACE_OS::sema_unlink (const char *name)
1818 #if defined (ACE_HAS_POSIX_SEM) && !defined (ACE_LACKS_SEM_UNLINK)
1819 return ::sem_unlink (name);
1821 ACE_UNUSED_ARG (name);
1822 ACE_NOTSUP_RETURN (-1);
1827 ACE_OS::sema_post (ACE_sema_t *s)
1829 ACE_OS_TRACE ("ACE_OS::sema_post");
1830 # if defined (ACE_HAS_POSIX_SEM)
1831 # if defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
1832 return ::sem_post (s->sema_);
1836 if (ACE_OS::mutex_lock (&s->lock_) == 0)
1838 if (::sem_post (s->sema_) == 0)
1839 result = ACE_OS::cond_signal (&s->count_nonzero_);
1841 ACE_OS::mutex_unlock (&s->lock_);
1844 # endif /* ACE_HAS_POSIX_SEM_TIMEOUT || ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION */
1845 # elif defined (ACE_USES_FIFO_SEM)
1847 if (ACE_OS::write (s->fd_[1], &c, sizeof (char)) == sizeof (char))
1850 # elif defined (ACE_HAS_THREADS)
1851 # if defined (ACE_HAS_PTHREADS)
1854 if (ACE_OS::mutex_lock (&s->lock_) == 0)
1856 // Always allow a waiter to continue if there is one.
1857 if (s->waiters_ > 0)
1858 result = ACE_OS::cond_signal (&s->count_nonzero_);
1863 ACE_OS::mutex_unlock (&s->lock_);
1866 # elif defined (ACE_HAS_WTHREADS)
1867 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*s, 1, 0),
1870 # elif defined (ACE_VXWORKS)
1871 return ::semGive (s->sema_);
1872 # endif /* ACE_HAS_PTHREADS */
1875 ACE_NOTSUP_RETURN (-1);
1876 # endif /* ACE_HAS_POSIX_SEM */
1880 ACE_OS::sema_post (ACE_sema_t *s, u_int release_count)
1882 #if defined (ACE_WIN32)
1883 // Win32 supports this natively.
1884 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*s, release_count, 0),
1885 ace_result_), int, -1);
1887 // On POSIX platforms we need to emulate this ourselves.
1888 // @@ We can optimize on this implementation. However,
1889 // the semaphore primitive on Win32 doesn't allow one
1890 // to increase a semaphore to more than the count it was
1891 // first initialized. Posix doesn't seem to have
1892 // this restriction. Should we impose the restriction in
1893 // our semaphore simulation?
1894 for (size_t i = 0; i < release_count; i++)
1895 if (ACE_OS::sema_post (s) == -1)
1899 #endif /* ACE_WIN32 */
1903 ACE_OS::sema_trywait (ACE_sema_t *s)
1905 ACE_OS_TRACE ("ACE_OS::sema_trywait");
1906 # if defined (ACE_HAS_POSIX_SEM)
1907 // POSIX semaphores set errno to EAGAIN if trywait fails
1908 return ::sem_trywait (s->sema_);
1909 # elif defined (ACE_USES_FIFO_SEM)
1913 /* turn on nonblocking for s->fd_[0] */
1914 if ((flags = ACE_OS::fcntl (s->fd_[0], F_GETFL, 0)) < 0)
1916 flags |= O_NONBLOCK;
1917 if (ACE_OS::fcntl (s->fd_[0], F_SETFL, flags) < 0)
1920 // read sets errno to EAGAIN if no input
1921 rc = ACE_OS::read (s->fd_[0], &c, sizeof (char));
1923 /* turn off nonblocking for fd_[0] */
1924 if ((flags = ACE_OS::fcntl (s->fd_[0], F_GETFL, 0)) >= 0)
1926 flags &= ~O_NONBLOCK;
1927 ACE_OS::fcntl (s->fd_[0], F_SETFL, flags);
1930 return rc == 1 ? 0 : (-1);
1931 # elif defined (ACE_HAS_THREADS)
1932 # if defined (ACE_HAS_PTHREADS)
1935 if (ACE_OS::mutex_lock (&s->lock_) == 0)
1945 ACE_OS::mutex_unlock (&s->lock_);
1948 # elif defined (ACE_HAS_WTHREADS)
1949 DWORD result = ::WaitForSingleObject (*s, 0);
1951 if (result == WAIT_OBJECT_0)
1955 if (result == WAIT_TIMEOUT)
1958 ACE_OS::set_errno_to_last_error ();
1959 // This is a hack, we need to find an appropriate mapping...
1962 # elif defined (ACE_VXWORKS)
1963 if (::semTake (s->sema_, NO_WAIT) == ERROR)
1964 if (errno == S_objLib_OBJ_UNAVAILABLE)
1966 // couldn't get the semaphore
1974 // got the semaphore
1976 # endif /* ACE_HAS_PTHREADS */
1979 ACE_NOTSUP_RETURN (-1);
1980 # endif /* ACE_HAS_POSIX_SEM */
1984 ACE_OS::sema_wait (ACE_sema_t *s)
1986 ACE_OS_TRACE ("ACE_OS::sema_wait");
1987 # if defined (ACE_HAS_POSIX_SEM)
1988 return ::sem_wait (s->sema_);
1989 # elif defined (ACE_USES_FIFO_SEM)
1991 if (ACE_OS::read (s->fd_[0], &c, sizeof (char)) == 1)
1994 # elif defined (ACE_HAS_THREADS)
1995 # if defined (ACE_HAS_PTHREADS)
1998 ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
2000 if (ACE_OS::mutex_lock (&s->lock_) != 0)
2004 // Keep track of the number of waiters so that we can signal
2005 // them properly in <ACE_OS::sema_post>.
2008 // Wait until the semaphore count is > 0.
2009 while (s->count_ == 0)
2010 if (ACE_OS::cond_wait (&s->count_nonzero_,
2013 result = -2; // -2 means that we need to release the mutex.
2024 ACE_OS::mutex_unlock (&s->lock_);
2025 ACE_PTHREAD_CLEANUP_POP (0);
2026 return result < 0 ? -1 : result;
2028 # elif defined (ACE_HAS_WTHREADS)
2029 switch (::WaitForSingleObject (*s, INFINITE))
2034 // This is a hack, we need to find an appropriate mapping...
2035 ACE_OS::set_errno_to_last_error ();
2039 # elif defined (ACE_VXWORKS)
2040 return ::semTake (s->sema_, WAIT_FOREVER);
2041 # endif /* ACE_HAS_PTHREADS */
2044 ACE_NOTSUP_RETURN (-1);
2045 # endif /* ACE_HAS_POSIX_SEM */
2049 ACE_OS::sema_wait (ACE_sema_t *s, ACE_Time_Value &tv)
2051 ACE_OS_TRACE ("ACE_OS::sema_wait");
2052 # if defined (ACE_HAS_POSIX_SEM)
2053 # if defined (ACE_HAS_POSIX_SEM_TIMEOUT)
2056 ts = tv; // Calls ACE_Time_Value::operator timespec_t().
2057 ACE_OSCALL (::sem_timedwait (s->sema_, &ts), int, rc);
2058 if (rc == -1 && errno == ETIMEDOUT)
2059 errno = ETIME; /* POSIX returns ETIMEDOUT but we need ETIME */
2061 # elif !defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
2063 bool expired = false;
2064 ACE_Errno_Guard error (errno);
2066 ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
2068 if (ACE_OS::mutex_lock (&s->lock_) != 0)
2072 bool finished = true;
2075 result = ACE_OS::sema_trywait (s);
2076 if (result == -1 && errno == EAGAIN)
2077 expired = (tv.to_relative_time () <= ACE_Time_Value::zero);
2081 finished = result != -1 || expired ||
2082 (result == -1 && errno != EAGAIN);
2085 if (ACE_OS::cond_timedwait (&s->count_nonzero_,
2094 } while (!finished);
2101 ACE_OS::mutex_unlock (&s->lock_);
2102 ACE_PTHREAD_CLEANUP_POP (0);
2103 return result < 0 ? -1 : result;
2104 # else /* No native sem_timedwait(), and emulation disabled */
2106 ACE_UNUSED_ARG (tv);
2107 ACE_NOTSUP_RETURN (-1);
2108 # endif /* ACE_HAS_POSIX_SEM_TIMEOUT */
2109 # elif defined (ACE_USES_FIFO_SEM)
2111 ACE_Time_Value timeout = tv.to_relative_time ();
2113 while (timeout > ACE_Time_Value::zero)
2115 ACE_Handle_Set fds_;
2117 fds_.set_bit (s->fd_[0]);
2118 if ((rc = ACE_OS::select (ACE_Handle_Set::MAXSIZE, fds_, 0, 0, timeout)) != 1)
2120 if (rc == 0 || errno != EAGAIN)
2128 // try to read the signal *but* do *not* block
2129 if (rc == 1 && ACE_OS::sema_trywait (s) == 0)
2132 // we were woken for input but someone beat us to it
2133 // so we wait again if there is still time
2134 timeout = tv.to_relative_time ();
2137 // make sure errno is set right
2141 # elif defined (ACE_HAS_THREADS)
2142 # if defined (ACE_HAS_PTHREADS)
2144 ACE_Errno_Guard error (errno);
2146 ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
2148 if (ACE_OS::mutex_lock (&s->lock_) != 0)
2152 // Keep track of the number of waiters so that we can signal
2153 // them properly in <ACE_OS::sema_post>.
2156 // Wait until the semaphore count is > 0 or until we time out.
2157 while (s->count_ == 0)
2158 if (ACE_OS::cond_timedwait (&s->count_nonzero_,
2163 result = -2; // -2 means that we need to release the mutex.
2176 ACE_OS::mutex_unlock (&s->lock_);
2177 ACE_PTHREAD_CLEANUP_POP (0);
2178 return result < 0 ? -1 : result;
2179 # elif defined (ACE_HAS_WTHREADS)
2182 if (tv == ACE_Time_Value::zero)
2183 msec_timeout = 0; // Do a "poll."
2186 // Note that we must convert between absolute time (which is
2187 // passed as a parameter) and relative time (which is what
2188 // <WaitForSingleObjects> expects).
2189 ACE_Time_Value relative_time = tv.to_relative_time ();
2191 // Watchout for situations where a context switch has caused the
2192 // current time to be > the timeout.
2193 if (relative_time < ACE_Time_Value::zero)
2196 msec_timeout = relative_time.msec ();
2199 switch (::WaitForSingleObject (*s, msec_timeout))
2202 tv = tv.now (); // Update time to when acquired
2208 // This is a hack, we need to find an appropriate mapping...
2209 ACE_OS::set_errno_to_last_error ();
2213 # elif defined (ACE_VXWORKS)
2214 // Note that we must convert between absolute time (which is
2215 // passed as a parameter) and relative time (which is what
2216 // the system call expects).
2217 ACE_Time_Value relative_time = tv.to_relative_time ();
2219 _Vx_freq_t const ticks_per_sec = ::sysClkRateGet ();
2221 int ticks = relative_time.sec () * ticks_per_sec +
2222 relative_time.usec () * ticks_per_sec / ACE_ONE_SECOND_IN_USECS;
2223 if (::semTake (s->sema_, ticks) == ERROR)
2225 if (errno == S_objLib_OBJ_TIMEOUT)
2226 // Convert the VxWorks errno to one that's common for to ACE
2229 else if (errno == S_objLib_OBJ_UNAVAILABLE)
2235 tv = tv.now (); // Update to time acquired
2238 # endif /* ACE_HAS_PTHREADS */
2241 ACE_UNUSED_ARG (tv);
2242 ACE_NOTSUP_RETURN (-1);
2243 # endif /* ACE_HAS_POSIX_SEM */
2247 ACE_OS::sema_wait (ACE_sema_t *s, ACE_Time_Value *tv)
2249 return tv == 0 ? ACE_OS::sema_wait (s) : ACE_OS::sema_wait (s, *tv);
2253 ACE_OS::semctl (int int_id, int semnum, int cmd, semun value)
2255 ACE_OS_TRACE ("ACE_OS::semctl");
2256 #if defined (ACE_HAS_SYSV_IPC)
2257 return ::semctl (int_id, semnum, cmd, value);
2259 ACE_UNUSED_ARG (int_id);
2260 ACE_UNUSED_ARG (semnum);
2261 ACE_UNUSED_ARG (cmd);
2262 ACE_UNUSED_ARG (value);
2264 ACE_NOTSUP_RETURN (-1);
2265 #endif /* ACE_HAS_SYSV_IPC */
2269 ACE_OS::semget (key_t key, int nsems, int flags)
2271 ACE_OS_TRACE ("ACE_OS::semget");
2272 #if defined (ACE_HAS_SYSV_IPC)
2273 return ::semget (key, nsems, flags);
2275 ACE_UNUSED_ARG (key);
2276 ACE_UNUSED_ARG (nsems);
2277 ACE_UNUSED_ARG (flags);
2279 ACE_NOTSUP_RETURN (-1);
2280 #endif /* ACE_HAS_SYSV_IPC */
2284 ACE_OS::semop (int int_id, struct sembuf *sops, size_t nsops)
2286 ACE_OS_TRACE ("ACE_OS::semop");
2287 #if defined (ACE_HAS_SYSV_IPC)
2288 return ::semop (int_id, sops, nsops);
2290 ACE_UNUSED_ARG (int_id);
2291 ACE_UNUSED_ARG (sops);
2292 ACE_UNUSED_ARG (nsops);
2294 ACE_NOTSUP_RETURN (-1);
2295 #endif /* ACE_HAS_SYSV_IPC */
2299 ACE_OS::sigtimedwait (const sigset_t *sset,
2301 const ACE_Time_Value *timeout)
2303 ACE_OS_TRACE ("ACE_OS::sigtimedwait");
2304 #if defined (ACE_HAS_SIGTIMEDWAIT)
2306 timespec_t *tsp = 0;
2310 ts = *timeout; // Calls ACE_Time_Value::operator timespec_t().
2314 return ::sigtimedwait (sset, info, tsp);
2316 ACE_UNUSED_ARG (sset);
2317 ACE_UNUSED_ARG (info);
2318 ACE_UNUSED_ARG (timeout);
2319 ACE_NOTSUP_RETURN (-1);
2320 #endif /* ACE_HAS_SIGTIMEDWAIT */
2324 ACE_OS::sigwait (sigset_t *sset, int *sig)
2326 ACE_OS_TRACE ("ACE_OS::sigwait");
2330 #if defined (ACE_HAS_THREADS)
2331 # if (defined (__FreeBSD__) && (__FreeBSD__ < 3))
2332 ACE_UNUSED_ARG (sset);
2333 ACE_NOTSUP_RETURN (-1);
2334 # elif defined (ACE_HAS_PTHREADS)
2335 # if defined (CYGWIN32)
2336 // Cygwin has sigwait definition, but it is not implemented
2337 ACE_UNUSED_ARG (sset);
2338 ACE_NOTSUP_RETURN (-1);
2339 # else /* this is std */
2340 errno = ::sigwait (sset, sig);
2341 return errno == 0 ? *sig : -1;
2342 # endif /* CYGWIN32 */
2343 # elif defined (ACE_HAS_WTHREADS)
2344 ACE_UNUSED_ARG (sset);
2345 ACE_NOTSUP_RETURN (-1);
2346 # elif defined (ACE_VXWORKS)
2347 // Second arg is a struct siginfo *, which we don't need (the
2348 // selected signal number is returned). Third arg is timeout: 0
2350 *sig = ::sigtimedwait (sset, 0, 0);
2352 # endif /* __FreeBSD__ */
2354 ACE_UNUSED_ARG (sset);
2355 ACE_UNUSED_ARG (sig);
2356 ACE_NOTSUP_RETURN (-1);
2357 #endif /* ACE_HAS_THREADS */
2361 ACE_OS::sigwaitinfo (const sigset_t *sset,
2364 ACE_OS_TRACE ("ACE_OS::sigwaitinfo");
2365 // If this platform has sigtimedwait, it should have sigwaitinfo as well.
2366 // If this isn't true somewhere, let me know and I'll fix this.
2367 // -Steve Huston <shuston@riverace.com>.
2368 #if defined (ACE_HAS_SIGTIMEDWAIT)
2369 return ::sigwaitinfo (sset, info);
2371 ACE_UNUSED_ARG (sset);
2372 ACE_UNUSED_ARG (info);
2373 ACE_NOTSUP_RETURN (-1);
2374 #endif /* ACE_HAS_SIGTIMEDWAIT */
2378 ACE_OS::thr_cancel (ACE_thread_t thr_id)
2380 ACE_OS_TRACE ("ACE_OS::thr_cancel");
2381 #if defined (ACE_HAS_THREADS)
2382 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
2384 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cancel (thr_id),
2387 # elif defined (ACE_HAS_VXTHREADS)
2388 return ::taskDelete (thr_id);
2389 # else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
2390 ACE_UNUSED_ARG (thr_id);
2391 ACE_NOTSUP_RETURN (-1);
2392 # endif /* ACE_HAS_PTHREADS */
2394 ACE_UNUSED_ARG (thr_id);
2395 ACE_NOTSUP_RETURN (-1);
2396 #endif /* ACE_HAS_THREADS */
2400 ACE_OS::thr_cmp (ACE_hthread_t t1, ACE_hthread_t t2)
2402 #if defined (ACE_HAS_PTHREADS)
2403 # if defined (pthread_equal)
2404 // If it's a macro we can't say "pthread_equal"...
2405 return pthread_equal (t1, t2);
2407 return pthread_equal (t1, t2);
2408 # endif /* pthread_equal */
2409 #else /* For STHREADS, WTHREADS, and VXWORKS ... */
2410 // Hum, Do we need to treat WTHREAD differently?
2411 // levine 13 oct 98 % Probably, ACE_hthread_t is a HANDLE.
2413 #endif /* ACE_HAS_PTHREADS */
2417 ACE_OS::thr_continue (ACE_hthread_t target_thread)
2419 ACE_OS_TRACE ("ACE_OS::thr_continue");
2420 #if defined (ACE_HAS_THREADS)
2421 # if defined (ACE_HAS_PTHREADS)
2422 # if defined (ACE_HAS_PTHREAD_CONTINUE)
2424 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_continue (target_thread),
2427 # elif defined (ACE_HAS_PTHREAD_CONTINUE_NP)
2429 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_continue_np (target_thread),
2432 # elif defined (ACE_HAS_PTHREAD_RESUME_NP)
2434 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_resume_np (target_thread),
2438 ACE_UNUSED_ARG (target_thread);
2439 ACE_NOTSUP_RETURN (-1);
2440 # endif /* ACE_HAS_PTHREAD_CONTINUE */
2441 # elif defined (ACE_HAS_WTHREADS)
2442 DWORD result = ::ResumeThread (target_thread);
2443 if (result == ACE_SYSCALL_FAILED)
2444 ACE_FAIL_RETURN (-1);
2447 # elif defined (ACE_HAS_VXTHREADS)
2448 return ::taskResume (target_thread);
2449 # endif /* ACE_HAS_PTHREADS */
2451 ACE_UNUSED_ARG (target_thread);
2452 ACE_NOTSUP_RETURN (-1);
2453 #endif /* ACE_HAS_THREADS */
2457 ACE_OS::thr_getconcurrency ()
2459 ACE_OS_TRACE ("ACE_OS::thr_getconcurrency");
2460 #if defined (ACE_HAS_THREADS)
2461 # if defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_PTHREAD_GETCONCURRENCY)
2462 return pthread_getconcurrency ();
2464 ACE_NOTSUP_RETURN (-1);
2465 # endif /* ACE_HAS_PTHREADS */
2467 ACE_NOTSUP_RETURN (-1);
2468 #endif /* ACE_HAS_THREADS */
2472 ACE_OS::thr_getprio (ACE_hthread_t ht_id, int &priority, int &policy)
2474 ACE_OS_TRACE ("ACE_OS::thr_getprio");
2475 ACE_UNUSED_ARG (policy);
2476 #if defined (ACE_HAS_THREADS)
2477 # if (defined (ACE_HAS_PTHREADS) && \
2478 (!defined (ACE_LACKS_SETSCHED) || defined (ACE_HAS_PTHREAD_SCHEDPARAM)))
2480 struct sched_param param;
2483 ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_getschedparam (ht_id, &policy, ¶m),
2486 priority = param.sched_priority;
2488 # elif defined (ACE_HAS_WTHREADS)
2489 ACE_Errno_Guard error (errno);
2490 priority = ::GetThreadPriority (ht_id);
2491 DWORD const priority_class = ::GetPriorityClass (::GetCurrentProcess ());
2492 if (priority_class == 0 && (error = ::GetLastError ()) != NO_ERROR)
2493 ACE_FAIL_RETURN (-1);
2495 policy = (priority_class == REALTIME_PRIORITY_CLASS) ? ACE_SCHED_FIFO : ACE_SCHED_OTHER;
2497 # elif defined (ACE_HAS_VXTHREADS)
2498 return ::taskPriorityGet (ht_id, &priority);
2500 ACE_UNUSED_ARG (ht_id);
2501 ACE_UNUSED_ARG (priority);
2502 ACE_NOTSUP_RETURN (-1);
2503 # endif /* ACE_HAS_PTHREADS */
2505 ACE_UNUSED_ARG (ht_id);
2506 ACE_UNUSED_ARG (priority);
2507 ACE_NOTSUP_RETURN (-1);
2508 #endif /* ACE_HAS_THREADS */
2512 ACE_OS::thr_getprio (ACE_hthread_t ht_id, int &priority)
2514 ACE_OS_TRACE ("ACE_OS::thr_getprio");
2516 return ACE_OS::thr_getprio (ht_id, priority, policy);
2519 #if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
2521 ACE_OS::thr_getspecific_native (ACE_OS_thread_key_t key, void **data)
2523 // ACE_OS_TRACE ("ACE_OS::thr_getspecific_native");
2524 # if defined (ACE_HAS_PTHREADS)
2525 *data = pthread_getspecific (key);
2527 # elif defined (ACE_HAS_WTHREADS)
2528 *data = ::TlsGetValue (key);
2529 if (*data == 0 && ::GetLastError () != NO_ERROR)
2531 ACE_OS::set_errno_to_last_error ();
2536 # else /* ACE_HAS_PTHREADS etc.*/
2537 ACE_UNUSED_ARG (key);
2538 ACE_UNUSED_ARG (data);
2539 ACE_NOTSUP_RETURN (-1);
2540 # endif /* ACE_HAS_PTHREADS etc.*/
2542 #endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
2545 ACE_OS::thr_getspecific (ACE_thread_key_t key, void **data)
2547 // ACE_OS_TRACE ("ACE_OS::thr_getspecific");
2548 #if defined (ACE_HAS_THREADS)
2549 # if defined (ACE_HAS_TSS_EMULATION)
2550 if (ACE_TSS_Emulation::is_key (key) == 0)
2558 *data = ACE_TSS_Emulation::ts_object (key);
2561 # elif defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
2562 return ACE_OS::thr_getspecific_native (key, data);
2564 ACE_UNUSED_ARG (key);
2565 ACE_UNUSED_ARG (data);
2566 ACE_NOTSUP_RETURN (-1);
2567 # endif /* ACE_HAS_TSS_EMULATION */
2569 ACE_UNUSED_ARG (key);
2570 ACE_UNUSED_ARG (data);
2571 ACE_NOTSUP_RETURN (-1);
2572 #endif /* ACE_HAS_THREADS */
2575 #if !defined (ACE_HAS_VXTHREADS)
2577 ACE_OS::thr_join (ACE_hthread_t thr_handle,
2578 ACE_THR_FUNC_RETURN *status)
2580 ACE_OS_TRACE ("ACE_OS::thr_join");
2581 #if defined (ACE_HAS_THREADS)
2582 # if defined (ACE_HAS_PTHREADS)
2583 # if defined (ACE_LACKS_PTHREAD_JOIN)
2584 ACE_UNUSED_ARG (thr_handle);
2585 ACE_UNUSED_ARG (status);
2586 ACE_NOTSUP_RETURN (-1);
2589 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_join (thr_handle, status), result),
2591 # endif /* ACE_LACKS_PTHREAD_JOIN */
2592 # elif defined (ACE_HAS_WTHREADS)
2593 // Waiting on the calling thread will deadlock, so try to avoid that. The
2594 // direct access to the needed info (GetThreadId) was added at Vista.
2595 // Win Server 2003 is 5.2; Vista is 6.0
2596 # if defined (_WIN32_WINNT) && (_WIN32_WINNT >= 0x0502)
2597 const ACE_TEXT_OSVERSIONINFO &info = ACE_OS::get_win32_versioninfo ();
2598 if (info.dwMajorVersion >= 6 ||
2599 (info.dwMajorVersion == 5 && info.dwMinorVersion == 2))
2601 if (::GetThreadId (thr_handle) == ::GetCurrentThreadId ())
2603 errno = ERROR_POSSIBLE_DEADLOCK;
2607 # endif /* _WIN32_WINNT */
2609 ACE_THR_FUNC_RETURN local_status = 0;
2611 // Make sure that status is non-NULL.
2613 status = &local_status;
2615 if (::WaitForSingleObject (thr_handle, INFINITE) == WAIT_OBJECT_0
2616 && ::GetExitCodeThread (thr_handle, status) != FALSE)
2618 ::CloseHandle (thr_handle);
2621 ACE_FAIL_RETURN (-1);
2624 ACE_UNUSED_ARG (thr_handle);
2625 ACE_UNUSED_ARG (status);
2626 ACE_NOTSUP_RETURN (-1);
2627 # endif /* ACE_HAS_PTHREADS */
2629 ACE_UNUSED_ARG (thr_handle);
2630 ACE_UNUSED_ARG (status);
2631 ACE_NOTSUP_RETURN (-1);
2632 #endif /* ACE_HAS_THREADS */
2636 ACE_OS::thr_join (ACE_thread_t waiter_id,
2637 ACE_thread_t *thr_id,
2638 ACE_THR_FUNC_RETURN *status)
2640 ACE_OS_TRACE ("ACE_OS::thr_join");
2641 #if defined (ACE_HAS_THREADS)
2642 # if defined (ACE_HAS_PTHREADS)
2643 # if defined (ACE_LACKS_PTHREAD_JOIN)
2644 ACE_UNUSED_ARG (waiter_id);
2645 ACE_UNUSED_ARG (thr_id);
2646 ACE_UNUSED_ARG (status);
2647 ACE_NOTSUP_RETURN (-1);
2649 ACE_UNUSED_ARG (thr_id);
2651 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_join (waiter_id, status), result),
2653 # endif /* ACE_LACKS_PTHREAD_JOIN */
2654 # elif defined (ACE_HAS_WTHREADS)
2655 ACE_UNUSED_ARG (waiter_id);
2656 ACE_UNUSED_ARG (thr_id);
2657 ACE_UNUSED_ARG (status);
2659 // This could be implemented if the DLL-Main function or the
2660 // task exit base class some log the threads which have exited
2661 ACE_NOTSUP_RETURN (-1);
2662 # endif /* ACE_HAS_PTHREADS */
2664 ACE_UNUSED_ARG (waiter_id);
2665 ACE_UNUSED_ARG (thr_id);
2666 ACE_UNUSED_ARG (status);
2667 ACE_NOTSUP_RETURN (-1);
2668 #endif /* ACE_HAS_THREADS */
2670 #endif /* !VXWORKS */
2673 ACE_OS::thr_kill (ACE_thread_t thr_id, int signum)
2675 ACE_OS_TRACE ("ACE_OS::thr_kill");
2676 #if defined (ACE_HAS_THREADS)
2677 # if defined (ACE_HAS_PTHREADS)
2678 # if defined (ACE_LACKS_PTHREAD_KILL)
2679 ACE_UNUSED_ARG (signum);
2680 ACE_UNUSED_ARG (thr_id);
2681 ACE_NOTSUP_RETURN (-1);
2684 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_kill (thr_id, signum),
2687 # endif /* ACE_LACKS_PTHREAD_KILL */
2688 # elif defined (ACE_HAS_VXTHREADS)
2689 //FUZZ: disable check_for_lack_ACE_OS
2690 return ::kill (thr_id, signum);
2691 //FUZZ: enable check_for_lack_ACE_OS
2693 ACE_UNUSED_ARG (thr_id);
2694 ACE_UNUSED_ARG (signum);
2695 ACE_NOTSUP_RETURN (-1);
2696 # endif /* ACE_HAS_PTHREADS */
2698 ACE_UNUSED_ARG (thr_id);
2699 ACE_UNUSED_ARG (signum);
2700 ACE_NOTSUP_RETURN (-1);
2701 #endif /* ACE_HAS_THREADS */
2705 ACE_OS::thr_min_stack ()
2707 ACE_OS_TRACE ("ACE_OS::thr_min_stack");
2708 #if defined (ACE_HAS_THREADS)
2709 # if defined (ACE_HAS_PTHREADS)
2710 # if defined (_SC_THREAD_STACK_MIN)
2711 return (size_t) ACE_OS::sysconf (_SC_THREAD_STACK_MIN);
2712 # elif defined (PTHREAD_STACK_MIN)
2713 return PTHREAD_STACK_MIN;
2715 ACE_NOTSUP_RETURN (0);
2716 # endif /* _SC_THREAD_STACK_MIN */
2717 # elif defined (ACE_HAS_WTHREADS)
2718 ACE_NOTSUP_RETURN (0);
2719 # elif defined (ACE_HAS_VXTHREADS)
2723 ACE_thread_t tid = ACE_OS::thr_self ();
2725 ACE_OSCALL (ACE_ADAPT_RETVAL (::taskInfoGet (tid, &taskDesc),
2728 return status == OK ? taskDesc.td_stackSize : 0;
2729 # else /* Should not happen... */
2730 ACE_NOTSUP_RETURN (0);
2731 # endif /* ACE_HAS_PTHREADS */
2733 ACE_NOTSUP_RETURN (0);
2734 #endif /* ACE_HAS_THREADS */
2738 ACE_OS::thr_id (char buffer[], size_t buffer_length)
2740 #if defined (ACE_WIN32)
2741 return ACE_OS::snprintf (buffer,
2744 static_cast <unsigned> (ACE_OS::thr_self ()));
2745 #else /* ACE_WIN32 */
2747 ACE_OS::thr_self (t_id);
2748 #if defined(ACE_HAS_OPAQUE_PTHREAD_T)
2749 return ACE_OS::snprintf (buffer,
2753 #else /* ACE_HAS_OPAQUE_PTHREAD_T */
2754 return ACE_OS::snprintf (buffer,
2757 (unsigned long) t_id);
2758 #endif /* ACE_HAS_OPAQUE_PTHREAD_T */
2763 ACE_OS::thr_gettid (char buffer[], size_t buffer_length)
2765 return ACE_OS::snprintf (buffer, buffer_length, "%d",
2766 static_cast<int> (ACE_OS::thr_gettid ()));
2770 ACE_OS::thr_gettid ()
2772 #ifdef ACE_HAS_GETTID
2773 return syscall (SYS_gettid);
2775 ACE_NOTSUP_RETURN (-1);
2779 ACE_INLINE ACE_thread_t
2782 // ACE_OS_TRACE ("ACE_OS::thr_self");
2783 #if defined (ACE_HAS_THREADS)
2784 # if defined (ACE_HAS_PTHREADS)
2785 // Note, don't use "::" here since the following call is often a macro.
2786 return pthread_self ();
2787 # elif defined (ACE_HAS_WTHREADS)
2788 return ::GetCurrentThreadId ();
2789 # elif defined (ACE_HAS_VXTHREADS)
2790 return ::taskIdSelf ();
2791 # endif /* ACE_HAS_PTHREADS */
2793 return 1; // Might as well make it the first thread ;-)
2794 #endif /* ACE_HAS_THREADS */
2797 ACE_INLINE const char*
2800 #if defined (ACE_HAS_THREADS)
2801 #if defined (ACE_HAS_VXTHREADS)
2802 return ::taskName (ACE_OS::thr_self ());
2804 ACE_NOTSUP_RETURN (0);
2807 ACE_NOTSUP_RETURN (0);
2812 ACE_OS::thr_self (ACE_hthread_t &self)
2814 ACE_OS_TRACE ("ACE_OS::thr_self");
2815 #if defined (ACE_HAS_THREADS)
2816 # if defined (ACE_HAS_PTHREADS)
2817 // Note, don't use "::" here since the following call is often a macro.
2818 self = pthread_self ();
2819 # elif defined (ACE_HAS_THREAD_SELF)
2820 self = ::thread_self ();
2821 # elif defined (ACE_HAS_WTHREADS)
2822 self = ::GetCurrentThread ();
2823 # elif defined (ACE_HAS_VXTHREADS)
2824 self = ::taskIdSelf ();
2825 # endif /* ACE_HAS_PTHREADS */
2827 self = 1; // Might as well make it the main thread ;-)
2828 #endif /* ACE_HAS_THREADS */
2832 ACE_OS::thr_setcancelstate (int new_state, int *old_state)
2834 ACE_OS_TRACE ("ACE_OS::thr_setcancelstate");
2835 #if defined (ACE_HAS_THREADS)
2836 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
2838 int local_new, local_old;
2841 case THR_CANCEL_ENABLE:
2842 local_new = PTHREAD_CANCEL_ENABLE;
2844 case THR_CANCEL_DISABLE:
2845 local_new = PTHREAD_CANCEL_DISABLE;
2851 ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_setcancelstate (local_new,
2859 case PTHREAD_CANCEL_ENABLE:
2860 *old_state = THR_CANCEL_ENABLE;
2862 case PTHREAD_CANCEL_DISABLE:
2863 *old_state = THR_CANCEL_DISABLE;
2867 # elif defined (ACE_HAS_WTHREADS)
2868 ACE_UNUSED_ARG (new_state);
2869 ACE_UNUSED_ARG (old_state);
2870 ACE_NOTSUP_RETURN (-1);
2871 # else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
2872 ACE_UNUSED_ARG (new_state);
2873 ACE_UNUSED_ARG (old_state);
2874 ACE_NOTSUP_RETURN (-1);
2875 # endif /* ACE_HAS_PTHREADS */
2877 ACE_UNUSED_ARG (new_state);
2878 ACE_UNUSED_ARG (old_state);
2879 ACE_NOTSUP_RETURN (-1);
2880 #endif /* ACE_HAS_THREADS */
2884 ACE_OS::thr_setcanceltype (int new_type, int *old_type)
2886 ACE_OS_TRACE ("ACE_OS::thr_setcanceltype");
2887 #if defined (ACE_HAS_THREADS)
2888 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
2890 int local_new, local_old;
2893 case THR_CANCEL_DEFERRED:
2894 local_new = PTHREAD_CANCEL_DEFERRED;
2896 case THR_CANCEL_ASYNCHRONOUS:
2897 local_new = PTHREAD_CANCEL_ASYNCHRONOUS;
2903 ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_setcanceltype (local_new,
2911 case PTHREAD_CANCEL_DEFERRED:
2912 *old_type = THR_CANCEL_DEFERRED;
2914 case PTHREAD_CANCEL_ASYNCHRONOUS:
2915 *old_type = THR_CANCEL_ASYNCHRONOUS;
2919 # else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
2920 ACE_UNUSED_ARG (new_type);
2921 ACE_UNUSED_ARG (old_type);
2922 ACE_NOTSUP_RETURN (-1);
2923 # endif /* ACE_HAS_PTHREADS */
2925 ACE_UNUSED_ARG (new_type);
2926 ACE_UNUSED_ARG (old_type);
2927 ACE_NOTSUP_RETURN (-1);
2928 #endif /* ACE_HAS_THREADS */
2932 ACE_OS::thr_setconcurrency (int hint)
2934 ACE_OS_TRACE ("ACE_OS::thr_setconcurrency");
2935 #if defined (ACE_HAS_THREADS)
2936 # if defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_PTHREAD_SETCONCURRENCY)
2938 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setconcurrency (hint), result), int);
2940 ACE_UNUSED_ARG (hint);
2941 ACE_NOTSUP_RETURN (-1);
2942 # endif /* ACE_HAS_PTHREADS */
2944 ACE_UNUSED_ARG (hint);
2945 ACE_NOTSUP_RETURN (-1);
2946 #endif /* ACE_HAS_THREADS */
2950 ACE_OS::thr_setprio (ACE_hthread_t ht_id, int priority, int policy)
2952 ACE_OS_TRACE ("ACE_OS::thr_setprio");
2953 ACE_UNUSED_ARG (policy);
2954 #if defined (ACE_HAS_THREADS)
2955 # if (defined (ACE_HAS_PTHREADS) && \
2956 (!defined (ACE_LACKS_SETSCHED) || defined (ACE_HAS_PTHREAD_SCHEDPARAM)))
2959 struct sched_param param;
2960 ACE_OS::memset ((void *) ¶m, 0, sizeof param);
2962 // If <policy> is -1, we don't want to use it for
2963 // pthread_setschedparam(). Instead, obtain policy from
2964 // pthread_getschedparam().
2967 ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_getschedparam (ht_id, &policy, ¶m), result), int, result);
2972 param.sched_priority = priority;
2974 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setschedparam (ht_id,
2979 # elif defined (ACE_HAS_WTHREADS)
2980 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::SetThreadPriority (ht_id, priority),
2983 # elif defined (ACE_HAS_VXTHREADS)
2984 ACE_OSCALL_RETURN (::taskPrioritySet (ht_id, priority), int);
2986 // For example, platforms that support Pthreads but LACK_SETSCHED.
2987 ACE_UNUSED_ARG (ht_id);
2988 ACE_UNUSED_ARG (priority);
2989 ACE_NOTSUP_RETURN (-1);
2990 # endif /* ACE_HAS_PTHREADS */
2992 ACE_UNUSED_ARG (ht_id);
2993 ACE_UNUSED_ARG (priority);
2994 ACE_NOTSUP_RETURN (-1);
2995 #endif /* ACE_HAS_THREADS */
2999 ACE_OS::thr_sigsetmask (int how,
3000 const sigset_t *nsm,
3003 ACE_OS_TRACE ("ACE_OS::thr_sigsetmask");
3004 #if defined (ACE_HAS_THREADS)
3005 # if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
3007 ACE_UNUSED_ARG (osm);
3008 ACE_UNUSED_ARG (nsm);
3009 ACE_UNUSED_ARG (how);
3011 ACE_NOTSUP_RETURN (-1);
3012 # elif defined (ACE_HAS_SIGTHREADMASK)
3014 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigthreadmask (how, nsm, osm), result), int);
3015 # elif defined (ACE_HAS_PTHREADS)
3016 # if !defined (ACE_LACKS_PTHREAD_SIGMASK)
3018 //FUZZ: disable check_for_lack_ACE_OS
3019 # if defined (ACE_HAS_NONCONST_PTHREAD_SIGMASK)
3020 sigset_t *ncnsm = const_cast<sigset_t *>(nsm);
3021 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, ncnsm, osm), result), int);
3023 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm), result), int);
3024 # endif /* ACE_HAS_NONCONST__PTHREAD_SIGMASK */
3025 //FUZZ: enable check_for_lack_ACE_OS
3026 # endif /* !ACE_LACKS_PTHREAD_SIGMASK */
3028 # elif defined (ACE_HAS_WTHREADS)
3029 ACE_UNUSED_ARG (osm);
3030 ACE_UNUSED_ARG (nsm);
3031 ACE_UNUSED_ARG (how);
3033 ACE_NOTSUP_RETURN (-1);
3034 # elif defined (ACE_VXWORKS)
3042 old_mask = ::sigsetmask (*nsm);
3043 // create a new mask: the following assumes that sigset_t is 4 bytes,
3044 // which it is on VxWorks 5.2, so bit operations are done simply . . .
3045 ::sigsetmask (how == SIG_BLOCK ? (old_mask |= *nsm) : (old_mask &= ~*nsm));
3051 old_mask = ::sigsetmask (*nsm);
3060 # else /* Should not happen. */
3061 ACE_UNUSED_ARG (how);
3062 ACE_UNUSED_ARG (nsm);
3063 ACE_UNUSED_ARG (osm);
3064 ACE_NOTSUP_RETURN (-1);
3065 # endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
3067 ACE_UNUSED_ARG (how);
3068 ACE_UNUSED_ARG (nsm);
3069 ACE_UNUSED_ARG (osm);
3070 ACE_NOTSUP_RETURN (-1);
3071 #endif /* ACE_HAS_THREADS */
3075 ACE_OS::thr_suspend (ACE_hthread_t target_thread)
3077 ACE_OS_TRACE ("ACE_OS::thr_suspend");
3078 #if defined (ACE_HAS_THREADS)
3079 # if defined (ACE_HAS_PTHREADS)
3080 # if defined (ACE_HAS_PTHREAD_SUSPEND)
3082 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_suspend (target_thread), result), int);
3083 # elif defined (ACE_HAS_PTHREAD_SUSPEND_NP)
3085 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_suspend_np (target_thread), result), int);
3087 ACE_UNUSED_ARG (target_thread);
3088 ACE_NOTSUP_RETURN (-1);
3089 # endif /* ACE_HAS_PTHREAD_SUSPEND */
3090 # elif defined (ACE_HAS_WTHREADS)
3091 if (::SuspendThread (target_thread) != ACE_SYSCALL_FAILED)
3094 ACE_FAIL_RETURN (-1);
3096 # elif defined (ACE_HAS_VXTHREADS)
3097 return ::taskSuspend (target_thread);
3098 # endif /* ACE_HAS_PTHREADS */
3100 ACE_UNUSED_ARG (target_thread);
3101 ACE_NOTSUP_RETURN (-1);
3102 #endif /* ACE_HAS_THREADS */
3106 ACE_OS::thr_testcancel ()
3108 ACE_OS_TRACE ("ACE_OS::thr_testcancel");
3109 #if defined (ACE_HAS_THREADS)
3110 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
3111 pthread_testcancel ();
3113 // no-op: can't use ACE_NOTSUP_RETURN because there is no return value
3114 # endif /* ACE_HAS_PTHREADS */
3116 #endif /* ACE_HAS_THREADS */
3120 ACE_OS::thr_yield ()
3122 ACE_OS_TRACE ("ACE_OS::thr_yield");
3123 #if defined (ACE_HAS_THREADS)
3124 # if defined (ACE_HAS_PTHREADS)
3126 # elif defined (ACE_HAS_WTHREADS)
3128 # elif defined (ACE_HAS_VXTHREADS)
3129 // An argument of 0 to ::taskDelay doesn't appear to yield the
3131 // Now, it does seem to work. The context_switch_time test
3132 // works fine with task_delay set to 0.
3134 # endif /* ACE_HAS_PTHREADS */
3137 #endif /* ACE_HAS_THREADS */
3141 ACE_OS::thread_mutex_destroy (ACE_thread_mutex_t *m)
3143 ACE_OS_TRACE ("ACE_OS::thread_mutex_destroy");
3144 #if defined (ACE_HAS_THREADS)
3145 # if defined (ACE_HAS_WTHREADS)
3146 ::DeleteCriticalSection (m);
3149 return ACE_OS::mutex_destroy (m);
3150 # endif /* ACE_HAS_WTHREADS */
3153 ACE_NOTSUP_RETURN (-1);
3155 #endif /* ACE_HAS_THREADS */
3159 ACE_OS::thread_mutex_init (ACE_thread_mutex_t *m,
3162 ACE_mutexattr_t *arg)
3164 // ACE_OS_TRACE ("ACE_OS::thread_mutex_init");
3165 #if defined (ACE_HAS_THREADS)
3166 # if defined (ACE_HAS_WTHREADS)
3167 ACE_UNUSED_ARG (lock_type);
3168 ACE_UNUSED_ARG (name);
3169 ACE_UNUSED_ARG (arg);
3173 ::InitializeCriticalSection (m);
3175 ACE_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3182 # elif defined (ACE_HAS_PTHREADS)
3183 // Force the use of USYNC_THREAD!
3184 return ACE_OS::mutex_init (m, USYNC_THREAD, name, arg, 0, lock_type);
3185 # elif defined (ACE_HAS_VXTHREADS)
3186 return mutex_init (m, lock_type, name, arg);
3188 # endif /* ACE_HAS_PTHREADS */
3192 ACE_UNUSED_ARG (lock_type);
3193 ACE_UNUSED_ARG (name);
3194 ACE_UNUSED_ARG (arg);
3195 ACE_NOTSUP_RETURN (-1);
3197 #endif /* ACE_HAS_THREADS */
3200 #if defined (ACE_HAS_WCHAR)
3202 ACE_OS::thread_mutex_init (ACE_thread_mutex_t *m,
3204 const wchar_t *name,
3205 ACE_mutexattr_t *arg)
3207 // ACE_OS_TRACE ("ACE_OS::thread_mutex_init");
3208 #if defined (ACE_HAS_THREADS)
3209 # if defined (ACE_HAS_WTHREADS)
3210 ACE_UNUSED_ARG (lock_type);
3211 ACE_UNUSED_ARG (name);
3212 ACE_UNUSED_ARG (arg);
3216 ::InitializeCriticalSection (m);
3218 ACE_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3225 # elif defined (ACE_HAS_PTHREADS)
3226 // Force the use of USYNC_THREAD!
3227 return ACE_OS::mutex_init (m, USYNC_THREAD, name, arg, 0, lock_type);
3228 # elif defined (ACE_HAS_VXTHREADS)
3229 return mutex_init (m, lock_type, name, arg);
3230 # endif /* ACE_HAS_PTHREADS */
3233 ACE_UNUSED_ARG (lock_type);
3234 ACE_UNUSED_ARG (name);
3235 ACE_UNUSED_ARG (arg);
3236 ACE_NOTSUP_RETURN (-1);
3238 #endif /* ACE_HAS_THREADS */
3240 #endif /* ACE_HAS_WCHAR */
3243 ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m)
3245 // ACE_OS_TRACE ("ACE_OS::thread_mutex_lock");
3246 #if defined (ACE_HAS_THREADS)
3247 # if defined (ACE_HAS_WTHREADS)
3248 ::EnterCriticalSection (m);
3251 return ACE_OS::mutex_lock (m);
3252 # endif /* ACE_HAS_WTHREADS */
3255 ACE_NOTSUP_RETURN (-1);
3256 #endif /* ACE_HAS_THREADS */
3260 ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m,
3261 const ACE_Time_Value &timeout)
3263 // ACE_OS_TRACE ("ACE_OS::thread_mutex_lock");
3265 // For all platforms, except MS Windows, this method is equivalent
3266 // to calling ACE_OS::mutex_lock() since ACE_thread_mutex_t and
3267 // ACE_mutex_t are the same type. However, those typedefs evaluate
3268 // to different types on MS Windows. The "thread mutex"
3269 // implementation in ACE for MS Windows cannot readily support
3270 // timeouts due to a lack of timeout features for this type of MS
3271 // Windows synchronization mechanism.
3273 #if defined (ACE_HAS_THREADS) && !defined (ACE_HAS_WTHREADS)
3274 return ACE_OS::mutex_lock (m, timeout);
3277 ACE_UNUSED_ARG (timeout);
3278 ACE_NOTSUP_RETURN (-1);
3279 #endif /* ACE_HAS_THREADS */
3283 ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m,
3284 const ACE_Time_Value *timeout)
3287 ? ACE_OS::thread_mutex_lock (m)
3288 : ACE_OS::thread_mutex_lock (m, *timeout);
3292 ACE_OS::thread_mutex_trylock (ACE_thread_mutex_t *m)
3294 ACE_OS_TRACE ("ACE_OS::thread_mutex_trylock");
3296 #if defined (ACE_HAS_THREADS)
3297 # if defined (ACE_HAS_WTHREADS)
3298 # if defined (ACE_HAS_WIN32_TRYLOCK)
3299 BOOL result = ::TryEnterCriticalSection (m);
3311 ACE_NOTSUP_RETURN (-1);
3312 # endif /* ACE_HAS_WIN32_TRYLOCK */
3313 # elif defined (ACE_HAS_PTHREADS) || defined (ACE_VXWORKS)
3314 return ACE_OS::mutex_trylock (m);
3315 #endif /* Threads variety case */
3319 ACE_NOTSUP_RETURN (-1);
3320 #endif /* ACE_HAS_THREADS */
3324 ACE_OS::thread_mutex_unlock (ACE_thread_mutex_t *m)
3326 ACE_OS_TRACE ("ACE_OS::thread_mutex_unlock");
3327 #if defined (ACE_HAS_THREADS)
3328 # if defined (ACE_HAS_WTHREADS)
3329 ::LeaveCriticalSection (m);
3332 return ACE_OS::mutex_unlock (m);
3333 # endif /* ACE_HAS_WTHREADS */
3336 ACE_NOTSUP_RETURN (-1);
3337 #endif /* ACE_HAS_THREADS */
3340 /*****************************************************************************/
3342 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
3346 ACE_OS_Thread_Mutex_Guard::acquire ()
3348 return owner_ = ACE_OS::thread_mutex_lock (&lock_);
3353 ACE_OS_Thread_Mutex_Guard::release ()
3360 return ACE_OS::thread_mutex_unlock (&lock_);
3365 ACE_OS_Thread_Mutex_Guard::ACE_OS_Thread_Mutex_Guard (ACE_thread_mutex_t &m)
3366 : lock_ (m), owner_ (-1)
3368 if (!ACE_OS_Object_Manager::starting_up ())
3373 ACE_OS_Thread_Mutex_Guard::~ACE_OS_Thread_Mutex_Guard ()
3378 /*****************************************************************************/
3382 ACE_OS_Recursive_Thread_Mutex_Guard::acquire ()
3384 return owner_ = ACE_OS::recursive_mutex_lock (&lock_);
3389 ACE_OS_Recursive_Thread_Mutex_Guard::release ()
3396 return ACE_OS::recursive_mutex_unlock (&lock_);
3401 ACE_OS_Recursive_Thread_Mutex_Guard::ACE_OS_Recursive_Thread_Mutex_Guard (
3402 ACE_recursive_thread_mutex_t &m)
3406 if (!ACE_OS_Object_Manager::starting_up ())
3411 ACE_OS_Recursive_Thread_Mutex_Guard::~ACE_OS_Recursive_Thread_Mutex_Guard ()
3416 #endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */
3419 /*****************************************************************************/
3422 ACE_Thread_ID::ACE_Thread_ID (ACE_thread_t thread_id,
3423 ACE_hthread_t thread_handle)
3424 : thread_id_ (thread_id),
3425 thread_handle_ (thread_handle)
3430 ACE_Thread_ID::ACE_Thread_ID (const ACE_Thread_ID &id)
3431 : thread_id_ (id.thread_id_),
3432 thread_handle_ (id.thread_handle_)
3438 ACE_Thread_ID::operator= (const ACE_Thread_ID &id)
3442 this->thread_id_ = id.thread_id_;
3443 this->thread_handle_ = id.thread_handle_;
3449 ACE_Thread_ID::ACE_Thread_ID ()
3450 : thread_id_ (ACE_OS::thr_self ())
3452 ACE_OS::thr_self (thread_handle_);
3457 ACE_Thread_ID::id () const
3459 return this->thread_id_;
3463 ACE_Thread_ID::id (ACE_thread_t thread_id)
3465 this->thread_id_ = thread_id;
3468 ACE_INLINE ACE_hthread_t
3469 ACE_Thread_ID::handle () const
3471 return this->thread_handle_;
3475 ACE_Thread_ID::handle (ACE_hthread_t thread_handle)
3477 this->thread_handle_ = thread_handle;
3481 ACE_Thread_ID::operator== (const ACE_Thread_ID &rhs) const
3484 ACE_OS::thr_cmp (this->thread_handle_, rhs.thread_handle_)
3485 && ACE_OS::thr_equal (this->thread_id_, rhs.thread_id_);
3489 ACE_Thread_ID::operator!= (const ACE_Thread_ID &rhs) const
3491 return !(*this == rhs);
3494 #if !defined (ACE_WIN32)
3497 ACE_event_t::ACE_event_t () :
3503 #endif /* !ACE_WIN32 */
3505 ACE_END_VERSIONED_NAMESPACE_DECL