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_PRIOCNTL)
20 # include /**/ <sys/priocntl.h>
21 #endif /* ACE_HAS_PRIOCNTL */
23 #if defined (ACE_HAS_ALLOC_HOOKS)
24 # include "ace/Malloc_Base.h"
25 #endif /* ACE_HAS_ALLOC_HOOKS */
27 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
29 /*****************************************************************************/
31 #if defined (ACE_LACKS_COND_T) && defined (ACE_HAS_THREADS)
33 ACE_cond_t::waiters (void) const
35 return this->waiters_;
37 #endif /* ACE_LACKS_COND_T && ACE_HAS_THREADS */
39 /*****************************************************************************/
41 #if defined (ACE_HAS_TSS_EMULATION)
43 # if !defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
46 ACE_TSS_Emulation::tss_base ()
48 # if defined (ACE_HAS_VXTHREADS)
49 # if (!defined (_WRS_CONFIG_SMP) && !defined (INCLUDE_AMP_CPU))
50 if (taskVarGet(0, reinterpret_cast<int*>(&ace_tss_keys)) == ERROR)
51 taskVarAdd(0, reinterpret_cast<int*>(&ace_tss_keys));
53 return reinterpret_cast <void **&> (ace_tss_keys);
56 ACE_NOTSUP_RETURN (0);
57 # endif /* ACE_HAS_VXTHREADS */
59 # endif /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
62 ACE_TSS_Emulation::ACE_TSS_DESTRUCTOR
63 ACE_TSS_Emulation::tss_destructor (const ACE_thread_key_t key)
65 return tss_destructor_ [key];
70 ACE_TSS_Emulation::tss_destructor (const ACE_thread_key_t key,
71 ACE_TSS_DESTRUCTOR destructor)
73 tss_destructor_ [key] = destructor;
78 ACE_TSS_Emulation::ts_object (const ACE_thread_key_t key)
80 # if defined (ACE_HAS_VXTHREADS)
81 /* If someone wants tss_base make sure they get one. This
82 gets used if someone spawns a VxWorks task directly, not
83 through ACE. The allocated array will never be deleted! */
84 if (ace_tss_keys == 0)
86 ace_tss_keys = new void *[ACE_TSS_THREAD_KEYS_MAX];
88 // Zero the entire TSS array. Do it manually instead of using
89 // memset, for optimum speed. Though, memset may be faster :-)
90 void **tss_base_p = reinterpret_cast<void **> (ace_tss_keys);
91 for (u_int i = 0; i < ACE_TSS_THREAD_KEYS_MAX; ++i, ++tss_base_p)
96 # endif /* ACE_HAS_VXTHREADS */
98 return tss_base ()[key];
101 #endif /* ACE_HAS_TSS_EMULATION */
103 /*****************************************************************************/
106 ACE_OS::thr_equal (ACE_thread_t t1, ACE_thread_t t2)
108 #if defined (ACE_HAS_PTHREADS)
109 # if defined (pthread_equal)
110 // If it's a macro we can't say "pthread_equal"...
111 return pthread_equal (t1, t2);
113 return pthread_equal (t1, t2);
114 # endif /* pthread_equal */
115 #else /* For both STHREADS and WTHREADS... */
116 // Hum, Do we need to treat WTHREAD differently?
117 // levine 13 oct 98 % I don't think so, ACE_thread_t is a DWORD.
119 #endif /* ACE_HAS_PTHREADS */
123 ACE_OS::condattr_destroy (ACE_condattr_t &attributes)
125 #if defined (ACE_HAS_THREADS) && !defined (ACE_LACKS_CONDATTR)
126 # if defined (ACE_HAS_PTHREADS)
127 pthread_condattr_destroy (&attributes);
130 # endif /* ACE_HAS_PTHREADS */
133 ACE_UNUSED_ARG (attributes);
135 # endif /* ACE_HAS_THREADS */
139 ACE_OS::condattr_init (ACE_condattr_t &attributes, int type)
141 ACE_UNUSED_ARG (type);
142 # if defined (ACE_HAS_THREADS)
143 # if defined (ACE_HAS_PTHREADS)
146 # if !defined (ACE_LACKS_CONDATTR)
147 # if defined (ACE_PTHREAD_CONDATTR_T_INITIALIZE)
148 /* Tests show that VxWorks 6.x pthread lib does not only
149 * require zeroing of mutex/condition objects to function correctly
150 * but also of the attribute objects.
152 ACE_OS::memset (&attributes, 0, sizeof (attributes));
155 ACE_ADAPT_RETVAL (pthread_condattr_init (&attributes), result) == 0
156 # if defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)
157 && ACE_ADAPT_RETVAL (pthread_condattr_setpshared (&attributes, type),
159 # endif /* _POSIX_THREAD_PROCESS_SHARED && ! ACE_LACKS_CONDATTR_PSHARED */
162 if (type == USYNC_THREAD)
163 # endif /* !ACE_LACKS_CONDATTR */
167 ACE_UNUSED_ARG (attributes);
168 result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
173 attributes.type = type;
175 # endif /* ACE_HAS_PTHREADS */
178 ACE_UNUSED_ARG (attributes);
179 ACE_UNUSED_ARG (type);
180 ACE_NOTSUP_RETURN (-1);
181 # endif /* ACE_HAS_THREADS */
185 ACE_OS::condattr_synctype (ACE_condattr_t &attributes, int& type)
187 # if defined (ACE_HAS_THREADS)
188 # if defined (ACE_HAS_PTHREADS)
189 # if !defined (ACE_LACKS_CONDATTR) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)
193 ACE_ADAPT_RETVAL (pthread_condattr_getpshared (&attributes, &type),
200 ACE_UNUSED_ARG (attributes);
203 # endif /* !ACE_LACKS_CONDATTR && _POSIX_THREAD_PROCESS_SHARED && ! ACE_LACKS_CONDATTR_PSHARED */
207 type = attributes.type;
209 # endif /* ACE_HAS_PTHREADS */
212 ACE_UNUSED_ARG (attributes);
213 ACE_UNUSED_ARG (type);
214 ACE_NOTSUP_RETURN (-1);
215 # endif /* ACE_HAS_THREADS */
219 ACE_OS::condattr_setclock (ACE_condattr_t &attributes, clockid_t clock_id)
221 #if defined (ACE_HAS_CONDATTR_SETCLOCK) && !defined (ACE_LACKS_CONDATTR_SETCLOCK) && \
222 !defined (ACE_LACKS_CONDATTR_SETCLOCK)
224 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_condattr_setclock (&attributes, clock_id),
229 ACE_UNUSED_ARG (clock_id);
230 ACE_UNUSED_ARG (attributes);
231 ACE_NOTSUP_RETURN (-1);
235 #if !defined (ACE_LACKS_COND_T)
236 // NOTE: The ACE_OS::cond_* functions for Unix platforms are defined
237 // here because the ACE_OS::sema_* functions below need them.
238 // However, ACE_WIN32 and VXWORKS define the ACE_OS::cond_* functions
239 // using the ACE_OS::sema_* functions. So, they are defined in OS_NS_Tread.cpp.
242 ACE_OS::cond_broadcast (ACE_cond_t *cv)
244 ACE_OS_TRACE ("ACE_OS::cond_broadcast");
245 # if defined (ACE_HAS_THREADS)
246 # if defined (ACE_HAS_PTHREADS)
248 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_broadcast (cv),
251 # elif defined (ACE_HAS_STHREADS)
253 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_broadcast (cv),
256 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
257 ::WakeAllConditionVariable (cv);
259 # endif /* ACE_HAS_STHREADS */
262 ACE_NOTSUP_RETURN (-1);
263 # endif /* ACE_HAS_THREADS */
267 ACE_OS::cond_destroy (ACE_cond_t *cv)
269 ACE_OS_TRACE ("ACE_OS::cond_destroy");
270 # if defined (ACE_HAS_THREADS)
271 # if defined (ACE_HAS_PTHREADS)
273 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_destroy (cv), result), int, -1);
274 # elif defined (ACE_HAS_STHREADS)
276 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_destroy (cv), result), int, -1);
277 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
278 // Windows doesn't have a destroy
280 # endif /* ACE_HAS_STHREADS */
283 ACE_NOTSUP_RETURN (-1);
284 # endif /* ACE_HAS_THREADS */
288 ACE_OS::cond_init (ACE_cond_t *cv,
289 ACE_condattr_t &attributes,
293 // ACE_OS_TRACE ("ACE_OS::cond_init");
294 ACE_UNUSED_ARG (name);
295 ACE_UNUSED_ARG (arg);
296 # if defined (ACE_HAS_THREADS)
297 # if defined (ACE_HAS_PTHREADS)
300 # if defined (ACE_PTHREAD_COND_T_INITIALIZE)
301 /* VxWorks 6.x API reference states:
302 * If the memory for the condition variable object has been allocated
303 * dynamically, it is a good policy to always zero out the
304 * block of memory so as to avoid spurious EBUSY return code
305 * when calling this routine.
307 ACE_OS::memset (cv, 0, sizeof (*cv));
310 if (ACE_ADAPT_RETVAL (pthread_cond_init (cv, &attributes), result) == 0)
313 result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
316 # elif defined (ACE_HAS_STHREADS)
318 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_init (cv,
323 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
324 ::InitializeConditionVariable (cv);
326 # endif /* ACE_HAS_PTHREADS vs. ACE_HAS_STHREADS */
329 ACE_UNUSED_ARG (attributes);
330 ACE_UNUSED_ARG (name);
331 ACE_UNUSED_ARG (arg);
332 ACE_NOTSUP_RETURN (-1);
333 # endif /* ACE_HAS_THREADS */
336 #if defined (ACE_HAS_WCHAR)
338 ACE_OS::cond_init (ACE_cond_t *cv,
339 ACE_condattr_t &attributes,
343 return ACE_OS::cond_init (cv, attributes, ACE_Wide_To_Ascii (name).char_rep (), arg);
345 #endif /* ACE_HAS_WCHAR */
347 #if defined (ACE_HAS_WCHAR)
349 ACE_OS::cond_init (ACE_cond_t *cv, short type, const wchar_t *name, void *arg)
351 return ACE_OS::cond_init (cv, type, ACE_Wide_To_Ascii (name).char_rep (), arg);
353 #endif /* ACE_HAS_WCHAR */
356 ACE_OS::cond_signal (ACE_cond_t *cv)
358 ACE_OS_TRACE ("ACE_OS::cond_signal");
359 # if defined (ACE_HAS_THREADS)
360 # if defined (ACE_HAS_PTHREADS)
362 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_signal (cv), result),
364 # elif defined (ACE_HAS_STHREADS)
366 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_signal (cv), result), int, -1);
367 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
368 ::WakeConditionVariable (cv);
370 # endif /* ACE_HAS_STHREADS */
373 ACE_NOTSUP_RETURN (-1);
374 # endif /* ACE_HAS_THREADS */
378 ACE_OS::cond_wait (ACE_cond_t *cv,
379 ACE_mutex_t *external_mutex)
381 ACE_OS_TRACE ("ACE_OS::cond_wait");
382 # if defined (ACE_HAS_THREADS)
383 # if defined (ACE_HAS_PTHREADS)
385 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_wait (cv, external_mutex), result),
387 # elif defined (ACE_HAS_STHREADS)
389 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_wait (cv, external_mutex), result),
391 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
393 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::SleepConditionVariableCS (cv, &external_mutex->thr_mutex_, INFINITE), result),
395 # endif /* ACE_HAS_PTHREADS */
398 ACE_UNUSED_ARG (external_mutex);
399 ACE_NOTSUP_RETURN (-1);
400 # endif /* ACE_HAS_THREADS */
404 ACE_OS::cond_timedwait (ACE_cond_t *cv,
405 ACE_mutex_t *external_mutex,
406 ACE_Time_Value *timeout)
408 ACE_OS_TRACE ("ACE_OS::cond_timedwait");
409 # if defined (ACE_HAS_THREADS)
414 ts = *timeout; // Calls ACE_Time_Value::operator timespec_t().
416 # if defined (ACE_HAS_PTHREADS)
418 ACE_OSCALL (ACE_ADAPT_RETVAL (timeout == 0
419 ? pthread_cond_wait (cv, external_mutex)
420 : pthread_cond_timedwait (cv, external_mutex,
421 (ACE_TIMESPEC_PTR) &ts),
424 // We need to adjust this to make the POSIX and Solaris return
425 // values consistent. EAGAIN is from Pthreads DRAFT4 (HP-UX 10.20 and down)
427 (errno == ETIMEDOUT || errno == EAGAIN))
430 # elif defined (ACE_HAS_STHREADS)
431 ACE_OSCALL (ACE_ADAPT_RETVAL (timeout == 0
432 ? ::cond_wait (cv, external_mutex)
433 : ::cond_timedwait (cv,
438 # elif defined (ACE_HAS_WTHREADS) && defined (ACE_HAS_WTHREADS_CONDITION_VARIABLE)
439 int msec_timeout = 0;
442 ACE_Time_Value relative_time = timeout->to_relative_time ();
443 // Watchout for situations where a context switch has caused the
444 // current time to be > the timeout.
445 if (relative_time > ACE_Time_Value::zero)
446 msec_timeout = relative_time.msec ();
449 ACE_OSCALL (ACE_ADAPT_RETVAL (::SleepConditionVariableCS (cv, &external_mutex->thr_mutex_, msec_timeout),
454 # endif /* ACE_HAS_STHREADS */
456 timeout->set (ts); // Update the time value before returning.
461 ACE_UNUSED_ARG (external_mutex);
462 ACE_UNUSED_ARG (timeout);
463 ACE_NOTSUP_RETURN (-1);
464 # endif /* ACE_HAS_THREADS */
466 #endif /* !ACE_LACKS_COND_T */
469 ACE_OS::mutex_lock (ACE_mutex_t *m,
470 const ACE_Time_Value *timeout)
472 return timeout == 0 ? ACE_OS::mutex_lock (m) : ACE_OS::mutex_lock (m, *timeout);
476 ACE_OS::event_wait (ACE_event_t *event)
478 return ACE_OS::event_timedwait (event, 0);
482 ACE_OS::event_init (ACE_event_t *event,
488 LPSECURITY_ATTRIBUTES sa)
490 ACE_condattr_t *pattr = 0;
491 return ACE_OS::event_init (event, type, pattr, manual_reset, initial_state, name, arg, sa);
494 #if defined (ACE_HAS_WCHAR)
496 ACE_OS::event_init (ACE_event_t *event,
502 LPSECURITY_ATTRIBUTES sa)
504 #if defined (ACE_WIN32)
505 ACE_UNUSED_ARG (type);
506 ACE_UNUSED_ARG (arg);
507 SECURITY_ATTRIBUTES sa_buffer;
508 SECURITY_DESCRIPTOR sd_buffer;
509 *event = ::CreateEventW (ACE_OS::default_win32_security_attributes_r
510 (sa, &sa_buffer, &sd_buffer),
515 ACE_FAIL_RETURN (-1);
517 // Make sure to set errno to ERROR_ALREADY_EXISTS if necessary.
518 ACE_OS::set_errno_to_last_error ();
520 #else /* ACE_WIN32 */
521 return ACE_OS::event_init (event,
525 ACE_Wide_To_Ascii (name).char_rep (),
528 #endif /* ACE_WIN32 */
532 ACE_OS::event_init (ACE_event_t *event,
534 ACE_condattr_t *attributes,
539 LPSECURITY_ATTRIBUTES sa)
541 #if defined (ACE_WIN32)
542 ACE_UNUSED_ARG (type);
543 ACE_UNUSED_ARG (attributes);
544 ACE_UNUSED_ARG (arg);
545 SECURITY_ATTRIBUTES sa_buffer;
546 SECURITY_DESCRIPTOR sd_buffer;
547 *event = ::CreateEventW (ACE_OS::default_win32_security_attributes_r
548 (sa, &sa_buffer, &sd_buffer),
553 ACE_FAIL_RETURN (-1);
555 // Make sure to set errno to ERROR_ALREADY_EXISTS if necessary.
556 ACE_OS::set_errno_to_last_error ();
558 #else /* ACE_WIN32 */
559 return ACE_OS::event_init (event,
564 ACE_Wide_To_Ascii (name).char_rep (),
567 #endif /* ACE_WIN32 */
569 #endif /* ACE_HAS_WCHAR */
572 ACE_OS::priority_control (ACE_idtype_t idtype, ACE_id_t identifier, int cmd, void *arg)
574 ACE_OS_TRACE ("ACE_OS::priority_control");
575 #if defined (ACE_HAS_PRIOCNTL)
576 ACE_OSCALL_RETURN (priocntl (idtype, identifier, cmd, static_cast<caddr_t> (arg)),
578 #else /* ! ACE_HAS_PRIOCNTL*/
579 ACE_UNUSED_ARG (idtype);
580 ACE_UNUSED_ARG (identifier);
581 ACE_UNUSED_ARG (cmd);
582 ACE_UNUSED_ARG (arg);
583 ACE_NOTSUP_RETURN (-1);
584 #endif /* ! ACE_HAS_PRIOCNTL*/
587 // This method is used to prepare the recursive mutex for releasing
588 // when waiting on a condition variable. If the platform doesn't have
589 // native recursive mutex and condition variable support, then ACE needs
590 // to save the recursion state around the wait and also ensure that the
591 // wait and lock release are atomic. recursive_mutex_cond_relock()
592 // is the inverse of this method.
594 ACE_OS::recursive_mutex_cond_unlock (ACE_recursive_thread_mutex_t *m,
595 ACE_recursive_mutex_state &state)
597 #if defined (ACE_HAS_THREADS)
598 ACE_OS_TRACE ("ACE_OS::recursive_mutex_cond_unlock");
599 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
600 // Windows need special handling since it has recursive mutexes, but
601 // does not integrate them into a condition variable.
602 # if defined (ACE_WIN32)
603 // For Windows, the OS takes care of the mutex and its recursion. We just
604 // need to release the lock one fewer times than this thread has acquired
605 // it. Remember how many times, and reacquire it that many more times when
606 // the condition is signaled.
608 // We're using undocumented fields in the CRITICAL_SECTION structure
609 // and they've been known to change across Windows variants and versions./
610 // So be careful if you need to change these - there may be other
611 // Windows variants that depend on existing values and limits.
613 state.relock_count_ = 0;
615 # if !defined (ACE_HAS_WINCE)
616 m->LockCount > 0 && m->RecursionCount > 1
618 // WinCE doesn't have RecursionCount and the LockCount semantic
619 // Mobile 5 has it 1-indexed.
621 # endif /* ACE_HAS_WINCE */
624 // This may fail if the current thread doesn't own the mutex. If it
625 // does fail, it'll be on the first try, so don't worry about resetting
627 if (ACE_OS::recursive_mutex_unlock (m) == -1)
629 ++state.relock_count_;
631 # else /* not ACE_WIN32 */
632 // prevent warnings for unused variables
633 ACE_UNUSED_ARG (state);
635 # endif /* ACE_WIN32 */
637 # else /* ACE_HAS_RECURSIVE_MUTEXES */
638 // For platforms without recursive mutexes, we obtain the nesting mutex
639 // to gain control over the mutex internals. Then set the internals to say
640 // the mutex is available. If there are waiters, signal the condition
641 // to notify them (this is mostly like the recursive_mutex_unlock() method).
642 // Then, return with the nesting mutex still held. The condition wait
643 // will release it atomically, allowing mutex waiters to continue.
644 // Note that this arrangement relies on the fact that on return from
645 // the condition wait, this thread will again own the nesting mutex
646 // and can either set the mutex internals directly or get in line for
647 // the mutex... this part is handled in recursive_mutex_cond_relock().
648 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
651 # if !defined (ACE_NDEBUG)
652 if (m->nesting_level_ == 0
653 || ACE_OS::thr_equal (ACE_OS::thr_self (), m->owner_id_) == 0)
655 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
659 # endif /* ACE_NDEBUG */
661 // To make error recovery a bit easier, signal the condition now. Any
662 // waiter won't regain control until the mutex is released, which won't
663 // be until the caller returns and does the wait on the condition.
664 if (ACE_OS::cond_signal (&m->lock_available_) == -1)
666 // Save/restore errno.
667 ACE_Errno_Guard error (errno);
668 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
672 // Ok, the nesting_mutex_ lock is still held, the condition has been
673 // signaled... reset the nesting info and return _WITH_ the lock
674 // held. The lock will be released when the condition waits, in the
676 state.nesting_level_ = m->nesting_level_;
677 state.owner_id_ = m->owner_id_;
678 m->nesting_level_ = 0;
679 m->owner_id_ = ACE_OS::NULL_thread;
681 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
684 ACE_UNUSED_ARG (state);
685 ACE_NOTSUP_RETURN (-1);
686 #endif /* ACE_HAS_THREADS */
690 // This method is called after waiting on a condition variable when a
691 // recursive mutex must be reacquired. If the platform doesn't natively
692 // integrate recursive mutexes and condition variables, it's taken care
693 // of here (inverse of ACE_OS::recursive_mutex_cond_unlock).
695 ACE_OS::recursive_mutex_cond_relock (ACE_recursive_thread_mutex_t *m,
696 ACE_recursive_mutex_state &state)
698 #if defined (ACE_HAS_THREADS)
699 ACE_OS_TRACE ("ACE_OS::recursive_mutex_cond_relock");
700 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
701 // Windows need special handling since it has recursive mutexes, but
702 // does not integrate them into a condition variable.
703 // On entry, the OS has already reacquired the lock for us. Just
704 // reacquire it the proper number of times so the recursion is the same as
705 // before waiting on the condition.
706 # if defined (ACE_WIN32)
707 while (state.relock_count_ > 0)
709 ACE_OS::recursive_mutex_lock (m);
710 --state.relock_count_;
713 # else /* not ACE_WIN32 */
714 // prevent warnings for unused variables
715 ACE_UNUSED_ARG (state);
718 # endif /* ACE_WIN32 */
720 // Without recursive mutex support, it's somewhat trickier. On entry,
721 // the current thread holds the nesting_mutex_, but another thread may
722 // still be holding the ACE_recursive_mutex_t. If so, mimic the code
723 // in ACE_OS::recursive_mutex_lock that waits to acquire the mutex.
724 // After acquiring it, restore the nesting counts and release the
725 // nesting mutex. This will restore the conditions to what they were
726 // before calling ACE_OS::recursive_mutex_cond_unlock().
727 while (m->nesting_level_ > 0)
728 ACE_OS::cond_wait (&m->lock_available_, &m->nesting_mutex_);
730 // At this point, we still have nesting_mutex_ and the mutex is free.
731 m->nesting_level_ = state.nesting_level_;
732 m->owner_id_ = state.owner_id_;
733 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
735 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
738 ACE_UNUSED_ARG (state);
740 #endif /* ACE_HAS_THREADS */
744 ACE_OS::recursive_mutex_destroy (ACE_recursive_thread_mutex_t *m)
746 #if defined (ACE_HAS_THREADS)
747 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
748 return ACE_OS::thread_mutex_destroy (m);
750 if (ACE_OS::cond_destroy (&m->lock_available_) == -1
751 || ACE_OS::thread_mutex_destroy (&m->nesting_mutex_) == -1)
754 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
757 ACE_NOTSUP_RETURN (-1);
758 #endif /* ACE_HAS_THREADS */
762 ACE_OS::recursive_mutex_init (ACE_recursive_thread_mutex_t *m,
763 const ACE_TCHAR *name,
764 ACE_mutexattr_t *arg,
765 LPSECURITY_ATTRIBUTES sa)
768 #if defined (ACE_HAS_THREADS)
769 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
770 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
771 return ACE_OS::thread_mutex_init (m, PTHREAD_MUTEX_RECURSIVE, name, arg);
773 return ACE_OS::thread_mutex_init (m, 0, name, arg);
774 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
776 if (ACE_OS::thread_mutex_init (&m->nesting_mutex_, 0, name, arg) == -1)
778 else if (ACE_OS::cond_init (&m->lock_available_,
779 (short) USYNC_THREAD,
785 m->nesting_level_ = 0;
786 m->owner_id_ = ACE_OS::NULL_thread;
789 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
792 ACE_UNUSED_ARG (name);
793 ACE_UNUSED_ARG (arg);
794 ACE_NOTSUP_RETURN (-1);
795 #endif /* ACE_HAS_THREADS */
799 ACE_OS::recursive_mutex_lock (ACE_recursive_thread_mutex_t *m)
801 #if defined (ACE_HAS_THREADS)
802 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
803 return ACE_OS::thread_mutex_lock (m);
805 ACE_thread_t const t_id = ACE_OS::thr_self ();
808 // Acquire the guard.
809 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -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)
824 ACE_OS::cond_wait (&m->lock_available_,
827 // At this point the nesting_mutex_ is held...
831 // At this point, we can safely increment the nesting_level_ no
832 // matter how we got here!
837 // Save/restore errno.
838 ACE_Errno_Guard error (errno);
839 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
842 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
845 ACE_NOTSUP_RETURN (-1);
846 #endif /* ACE_HAS_THREADS */
850 ACE_OS::recursive_mutex_lock (ACE_recursive_thread_mutex_t *m,
851 const ACE_Time_Value &timeout)
853 #if defined (ACE_HAS_THREADS)
854 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
855 return ACE_OS::thread_mutex_lock (m, timeout);
857 ACE_thread_t t_id = ACE_OS::thr_self ();
860 // Try to acquire the guard.
861 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_, timeout) == -1)
865 // If there's no contention, just grab the lock immediately
866 // (since this is the common case we'll optimize for it).
867 if (m->nesting_level_ == 0)
869 // If we already own the lock, then increment the nesting level
871 else if (ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
873 // Wait until the nesting level has dropped to zero, at
874 // which point we can acquire the lock.
875 while (m->nesting_level_ > 0)
877 result = ACE_OS::cond_timedwait (&m->lock_available_,
879 const_cast <ACE_Time_Value *> (&timeout));
881 // The mutex is reacquired even in the case of a timeout
882 // release the mutex to prevent a deadlock
885 // Save/restore errno.
886 ACE_Errno_Guard error (errno);
887 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
893 // At this point the nesting_mutex_ is held...
897 // At this point, we can safely increment the nesting_level_ no
898 // matter how we got here!
901 // Save/restore errno.
902 ACE_Errno_Guard error (errno);
903 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
906 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
909 ACE_UNUSED_ARG (timeout);
910 ACE_NOTSUP_RETURN (-1);
911 #endif /* ACE_HAS_THREADS */
915 ACE_OS::recursive_mutex_lock (ACE_recursive_thread_mutex_t *m,
916 const ACE_Time_Value *timeout)
919 ? ACE_OS::recursive_mutex_lock (m)
920 : ACE_OS::recursive_mutex_lock (m, *timeout);
924 ACE_OS::recursive_mutex_trylock (ACE_recursive_thread_mutex_t *m)
926 #if defined (ACE_HAS_THREADS)
927 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
928 return ACE_OS::thread_mutex_trylock (m);
930 ACE_thread_t t_id = ACE_OS::thr_self ();
933 // Acquire the guard.
934 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
938 // If there's no contention, just grab the lock immediately.
939 if (m->nesting_level_ == 0)
942 m->nesting_level_ = 1;
944 // If we already own the lock, then increment the nesting level
946 else if (ACE_OS::thr_equal (t_id, m->owner_id_))
956 // Save/restore errno.
957 ACE_Errno_Guard error (errno);
958 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
961 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
964 ACE_NOTSUP_RETURN (-1);
965 #endif /* ACE_HAS_THREADS */
969 ACE_OS::recursive_mutex_unlock (ACE_recursive_thread_mutex_t *m)
971 #if defined (ACE_HAS_THREADS)
972 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
973 return ACE_OS::thread_mutex_unlock (m);
975 ACE_OS_TRACE ("ACE_OS::recursive_mutex_unlock");
976 # if !defined (ACE_NDEBUG)
977 ACE_thread_t t_id = ACE_OS::thr_self ();
978 # endif /* ACE_NDEBUG */
981 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
985 # if !defined (ACE_NDEBUG)
986 if (m->nesting_level_ == 0
987 || ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
993 # endif /* ACE_NDEBUG */
996 if (m->nesting_level_ == 0)
998 // This may not be strictly necessary, but it does put
999 // the mutex into a known state...
1000 m->owner_id_ = ACE_OS::NULL_thread;
1002 // Inform a waiter that the lock is free.
1003 if (ACE_OS::cond_signal (&m->lock_available_) == -1)
1010 // Save/restore errno.
1011 ACE_Errno_Guard error (errno);
1012 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
1015 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
1018 ACE_NOTSUP_RETURN (-1);
1019 #endif /* ACE_HAS_THREADS */
1023 ACE_OS::rw_rdlock (ACE_rwlock_t *rw)
1025 ACE_OS_TRACE ("ACE_OS::rw_rdlock");
1026 #if defined (ACE_HAS_THREADS)
1027 # if !defined (ACE_LACKS_RWLOCK_T)
1028 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1030 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_rdlock (rw),
1033 # else /* Solaris */
1035 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_rdlock (rw), result), int, -1);
1036 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1037 # else /* NT, POSIX, and VxWorks don't support this natively. */
1038 # if defined (ACE_HAS_PTHREADS)
1039 ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
1040 # endif /* ACE_HAS_PTHREADS */
1042 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
1043 result = -1; // -1 means didn't get the mutex.
1046 // Give preference to writers who are waiting.
1047 while (rw->ref_count_ < 0 || rw->num_waiting_writers_ > 0)
1049 rw->num_waiting_readers_++;
1050 if (ACE_OS::cond_wait (&rw->waiting_readers_, &rw->lock_) == -1)
1052 result = -2; // -2 means that we need to release the mutex.
1055 rw->num_waiting_readers_--;
1061 ACE_OS::mutex_unlock (&rw->lock_);
1062 # if defined (ACE_HAS_PTHREADS)
1063 ACE_PTHREAD_CLEANUP_POP (0);
1064 # endif /* defined (ACE_HAS_PTHREADS) */
1066 # endif /* ! ACE_LACKS_RWLOCK_T */
1068 ACE_UNUSED_ARG (rw);
1069 ACE_NOTSUP_RETURN (-1);
1070 #endif /* ACE_HAS_THREADS */
1074 ACE_OS::rw_tryrdlock (ACE_rwlock_t *rw)
1076 ACE_OS_TRACE ("ACE_OS::rw_tryrdlock");
1077 #if defined (ACE_HAS_THREADS)
1078 # if !defined (ACE_LACKS_RWLOCK_T)
1079 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1081 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_tryrdlock (rw),
1084 # else /* Solaris */
1086 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_tryrdlock (rw), result), int, -1);
1087 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1088 # else /* NT, POSIX, and VxWorks don't support this natively. */
1091 if (ACE_OS::mutex_lock (&rw->lock_) != -1)
1093 ACE_Errno_Guard error (errno);
1095 if (rw->ref_count_ == -1 || rw->num_waiting_writers_ > 0)
1106 ACE_OS::mutex_unlock (&rw->lock_);
1109 # endif /* ! ACE_LACKS_RWLOCK_T */
1111 ACE_UNUSED_ARG (rw);
1112 ACE_NOTSUP_RETURN (-1);
1113 #endif /* ACE_HAS_THREADS */
1117 ACE_OS::rw_trywrlock (ACE_rwlock_t *rw)
1119 ACE_OS_TRACE ("ACE_OS::rw_trywrlock");
1120 #if defined (ACE_HAS_THREADS)
1121 # if !defined (ACE_LACKS_RWLOCK_T)
1122 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1124 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_trywrlock (rw),
1127 # else /* Solaris */
1129 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_trywrlock (rw), result), int, -1);
1130 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1131 # else /* NT, POSIX, and VxWorks don't support this natively. */
1134 if (ACE_OS::mutex_lock (&rw->lock_) != -1)
1136 ACE_Errno_Guard error (errno);
1138 if (rw->ref_count_ != 0)
1145 rw->ref_count_ = -1;
1149 ACE_OS::mutex_unlock (&rw->lock_);
1152 # endif /* ! ACE_LACKS_RWLOCK_T */
1154 ACE_UNUSED_ARG (rw);
1155 ACE_NOTSUP_RETURN (-1);
1156 #endif /* ACE_HAS_THREADS */
1159 // Note that the caller of this method *must* already possess this
1160 // lock as a read lock.
1161 // return {-1 and no errno set means: error,
1162 // -1 and errno==EBUSY set means: could not upgrade,
1163 // 0 means: upgraded successfully}
1166 ACE_OS::rw_trywrlock_upgrade (ACE_rwlock_t *rw)
1168 ACE_OS_TRACE ("ACE_OS::rw_trywrlock_upgrade");
1169 #if defined (ACE_HAS_THREADS)
1170 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT) && !defined (ACE_LACKS_RWLOCK_T)
1172 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_trywrlock (rw),
1175 # elif !defined (ACE_LACKS_RWLOCK_T)
1176 // Some native rwlocks, such as those on Solaris, don't
1177 // support the upgrade feature . . .
1178 ACE_UNUSED_ARG (rw);
1179 ACE_NOTSUP_RETURN (-1);
1180 # else /* NT, POSIX, and VxWorks don't support this natively. */
1181 // The ACE rwlock emulation does support upgrade . . .
1184 # if defined (ACE_HAS_PTHREADS)
1185 ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
1186 # endif /* defined (ACE_HAS_PTHREADS) */
1188 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
1190 // -1 means didn't get the mutex, error
1191 else if (rw->important_writer_)
1192 // an other reader upgrades already
1199 while (rw->ref_count_ > 1) // wait until only I am left
1201 rw->num_waiting_writers_++; // prohibit any more readers
1202 rw->important_writer_ = true;
1204 if (ACE_OS::cond_wait (&rw->waiting_important_writer_, &rw->lock_) == -1)
1207 // we know that we have the lock again, we have this guarantee,
1208 // but something went wrong
1210 rw->important_writer_ = false;
1211 rw->num_waiting_writers_--;
1215 // nothing bad happend
1216 rw->ref_count_ = -1;
1217 // now I am a writer
1218 // everything is O.K.
1222 ACE_OS::mutex_unlock (&rw->lock_);
1224 # if defined (ACE_HAS_PTHREADS)
1225 ACE_PTHREAD_CLEANUP_POP (0);
1226 # endif /* defined (ACE_HAS_PTHREADS) */
1230 # endif /* ! ACE_LACKS_RWLOCK_T */
1232 ACE_UNUSED_ARG (rw);
1233 ACE_NOTSUP_RETURN (-1);
1234 #endif /* ACE_HAS_THREADS */
1238 ACE_OS::rw_unlock (ACE_rwlock_t *rw)
1240 ACE_OS_TRACE ("ACE_OS::rw_unlock");
1241 #if defined (ACE_HAS_THREADS)
1242 # if !defined (ACE_LACKS_RWLOCK_T)
1243 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1245 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_unlock (rw),
1248 # else /* Solaris */
1250 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_unlock (rw), result), int, -1);
1251 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1252 # else /* NT, POSIX, and VxWorks don't support this natively. */
1253 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
1256 if (rw->ref_count_ > 0) // Releasing a reader.
1258 else if (rw->ref_count_ == -1) // Releasing a writer.
1262 (void) ACE_OS::mutex_unlock (&rw->lock_);
1263 return -1; // @@ ACE_ASSERT (!"count should not be 0!\n");
1267 ACE_Errno_Guard error (errno);
1269 if (rw->important_writer_ && rw->ref_count_ == 1)
1270 // only the reader requesting to upgrade its lock is left over.
1272 result = ACE_OS::cond_signal (&rw->waiting_important_writer_);
1275 else if (rw->num_waiting_writers_ > 0 && rw->ref_count_ == 0)
1276 // give preference to writers over readers...
1278 result = ACE_OS::cond_signal (&rw->waiting_writers_);
1281 else if (rw->num_waiting_readers_ > 0 && rw->num_waiting_writers_ == 0)
1283 result = ACE_OS::cond_broadcast (&rw->waiting_readers_);
1287 (void) ACE_OS::mutex_unlock (&rw->lock_);
1289 # endif /* ! ace_lacks_rwlock_t */
1291 ACE_UNUSED_ARG (rw);
1292 ACE_NOTSUP_RETURN (-1);
1293 #endif /* ace_has_threads */
1297 ACE_OS::rw_wrlock (ACE_rwlock_t *rw)
1299 ACE_OS_TRACE ("ACE_OS::rw_wrlock");
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_wrlock (rw),
1307 # else /* Solaris */
1309 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_wrlock (rw), result), int, -1);
1310 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1311 # else /* NT, POSIX, and VxWorks don't support this natively. */
1312 # if defined (ACE_HAS_PTHREADS)
1313 ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
1314 # endif /* defined (ACE_HAS_PTHREADS) */
1317 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
1318 result = -1; // -1 means didn't get the mutex.
1321 while (rw->ref_count_ != 0)
1323 rw->num_waiting_writers_++;
1325 if (ACE_OS::cond_wait (&rw->waiting_writers_, &rw->lock_) == -1)
1327 result = -2; // -2 means we need to release the mutex.
1331 rw->num_waiting_writers_--;
1335 rw->ref_count_ = -1;
1337 ACE_OS::mutex_unlock (&rw->lock_);
1338 # if defined (ACE_HAS_PTHREADS)
1339 ACE_PTHREAD_CLEANUP_POP (0);
1340 # endif /* defined (ACE_HAS_PTHREADS) */
1342 # endif /* ! ACE_LACKS_RWLOCK_T */
1344 ACE_UNUSED_ARG (rw);
1345 ACE_NOTSUP_RETURN (-1);
1346 #endif /* ACE_HAS_THREADS */
1350 ACE_OS::rwlock_destroy (ACE_rwlock_t *rw)
1352 ACE_OS_TRACE ("ACE_OS::rwlock_destroy");
1353 #if defined (ACE_HAS_THREADS)
1354 # if !defined (ACE_LACKS_RWLOCK_T)
1355 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1357 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_destroy (rw),
1360 # else /* Solaris */
1362 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rwlock_destroy (rw), result), int, -1);
1363 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1364 # else /* NT, POSIX, and VxWorks don't support this natively. */
1365 ACE_OS::mutex_destroy (&rw->lock_);
1366 ACE_OS::cond_destroy (&rw->waiting_readers_);
1367 ACE_OS::cond_destroy (&rw->waiting_important_writer_);
1368 return ACE_OS::cond_destroy (&rw->waiting_writers_);
1369 # endif /* ACE_HAS_STHREADS && !defined (ACE_LACKS_RWLOCK_T) */
1371 ACE_UNUSED_ARG (rw);
1372 ACE_NOTSUP_RETURN (-1);
1373 #endif /* ACE_HAS_THREADS */
1376 #if defined (ACE_HAS_THREADS) && !defined (ACE_LACKS_RWLOCK_T)
1378 ACE_OS::rwlock_init (ACE_rwlock_t *rw,
1380 const ACE_TCHAR *name,
1383 // ACE_OS_TRACE ("ACE_OS::rwlock_init");
1384 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1385 ACE_UNUSED_ARG (name);
1386 ACE_UNUSED_ARG (arg);
1389 pthread_rwlockattr_t attr;
1390 pthread_rwlockattr_init (&attr);
1391 # if !defined (ACE_LACKS_RWLOCKATTR_PSHARED)
1392 pthread_rwlockattr_setpshared (&attr, (type == USYNC_THREAD ?
1393 PTHREAD_PROCESS_PRIVATE :
1394 PTHREAD_PROCESS_SHARED));
1396 ACE_UNUSED_ARG (type);
1397 # endif /* !ACE_LACKS_RWLOCKATTR_PSHARED */
1398 status = ACE_ADAPT_RETVAL (pthread_rwlock_init (rw, &attr), status);
1399 pthread_rwlockattr_destroy (&attr);
1407 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rwlock_init (rw, type, arg), result), int, -1);
1408 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1410 #endif /* ACE_HAS_THREADS && !defined (ACE_LACKS_RWLOCK_T) */
1413 ACE_OS::sema_destroy (ACE_sema_t *s)
1415 ACE_OS_TRACE ("ACE_OS::sema_destroy");
1416 #if defined (ACE_HAS_POSIX_SEM)
1418 # if !defined (ACE_HAS_POSIX_SEM_TIMEOUT) && !defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
1419 ACE_OS::mutex_destroy (&s->lock_);
1420 ACE_OS::cond_destroy (&s->count_nonzero_);
1421 # endif /* !ACE_HAS_POSIX_SEM_TIMEOUT && !ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION */
1422 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1425 // Only destroy the semaphore if we're the ones who
1427 # if !defined (ACE_LACKS_SEM_DESTROY)
1428 ACE_OSCALL (::sem_destroy (s->sema_),int, -1, result);
1429 # endif /* ACE_LACKS_SEM_DESTROY */
1430 ACE_OS::shm_unlink (s->name_);
1437 if (!s->avoid_unlink_)
1438 ACE_OS::sema_unlink (s->name_);
1439 #if defined (ACE_HAS_ALLOC_HOOKS)
1440 ACE_Allocator::instance()->free ((void *) s->name_);
1442 ACE_OS::free ((void *) s->name_);
1443 #endif /* ACE_HAS_ALLOC_HOOKS */
1444 ACE_OSCALL_RETURN (::sem_close (s->sema_), int, -1);
1446 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1449 # if !defined (ACE_LACKS_UNNAMED_SEMAPHORE) && !defined (ACE_LACKS_SEM_DESTROY)
1450 ACE_OSCALL (::sem_destroy (s->sema_), int, -1, result);
1451 # endif /* !ACE_LACKS_UNNAMED_SEMAPHORE && !ACE_LACKS_SEM_DESTROY */
1452 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1454 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1455 #if defined (ACE_HAS_ALLOC_HOOKS)
1456 ACE_Allocator::instance()->free(s->sema_);
1459 #endif /* ACE_HAS_ALLOC_HOOKS */
1463 #elif defined (ACE_USES_FIFO_SEM)
1467 r0 = ACE_OS::unlink (s->name_);
1468 #if defined (ACE_HAS_ALLOC_HOOKS)
1469 ACE_Allocator::instance()->free ((void *) s->name_);
1471 ACE_OS::free ((void *) s->name_);
1472 #endif /* ACE_HAS_ALLOC_HOOKS */
1475 int r1 = ACE_OS::close (s->fd_[0]); /* ignore error */
1476 int r2 = ACE_OS::close (s->fd_[1]); /* ignore error */
1477 return r0 != 0 || r1 != 0 || r2 != 0 ? -1 : 0;
1478 #elif defined (ACE_HAS_THREADS)
1479 # if defined (ACE_HAS_STHREADS)
1481 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_destroy (s), result), int, -1);
1482 # elif defined (ACE_HAS_PTHREADS)
1483 int r1 = ACE_OS::mutex_destroy (&s->lock_);
1484 int r2 = ACE_OS::cond_destroy (&s->count_nonzero_);
1485 return r1 != 0 || r2 != 0 ? -1 : 0;
1486 # elif defined (ACE_HAS_WTHREADS)
1487 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
1488 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (*s), ace_result_), int, -1);
1489 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
1490 // Free up underlying objects of the simulated semaphore.
1491 int const r1 = ACE_OS::thread_mutex_destroy (&s->lock_);
1492 int const r2 = ACE_OS::event_destroy (&s->count_nonzero_);
1493 return r1 != 0 || r2 != 0 ? -1 : 0;
1494 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
1495 # elif defined (ACE_VXWORKS)
1497 ACE_OSCALL (::semDelete (s->sema_), int, -1, result);
1500 # endif /* ACE_HAS_STHREADS */
1503 ACE_NOTSUP_RETURN (-1);
1504 #endif /* ACE_HAS_POSIX_SEM */
1507 // NOTE: The previous four function definitions must appear before
1508 // ACE_OS::sema_init ().
1511 ACE_OS::sema_init (ACE_sema_t *s,
1517 LPSECURITY_ATTRIBUTES sa)
1519 ACE_condattr_t *pattr = 0;
1520 return ACE_OS::sema_init (s, count, type, pattr, name, arg, max, sa);
1524 ACE_OS::sema_init (ACE_sema_t *s,
1527 ACE_condattr_t *attributes,
1531 LPSECURITY_ATTRIBUTES sa)
1533 ACE_OS_TRACE ("ACE_OS::sema_init");
1534 #if defined (ACE_HAS_POSIX_SEM)
1535 ACE_UNUSED_ARG (max);
1536 ACE_UNUSED_ARG (sa);
1539 s->avoid_unlink_ = false;
1540 # if defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
1541 ACE_UNUSED_ARG (arg);
1542 ACE_UNUSED_ARG (attributes);
1546 if (ACE_OS::mutex_init (&s->lock_, type, name,
1547 (ACE_mutexattr_t *) arg) == 0
1548 && (attributes == 0 ?
1549 ACE_OS::cond_init (&s->count_nonzero_, (short)type, name, arg) :
1550 ACE_OS::cond_init (&s->count_nonzero_, *attributes, name, arg)) == 0
1551 && ACE_OS::mutex_lock (&s->lock_) == 0)
1553 if (ACE_OS::mutex_unlock (&s->lock_) == 0)
1559 ACE_OS::mutex_destroy (&s->lock_);
1560 ACE_OS::cond_destroy (&s->count_nonzero_);
1563 # endif /* ACE_HAS_POSIX_SEM_TIMEOUT || ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION */
1565 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1566 s->new_sema_ = false;
1567 if (type == USYNC_PROCESS)
1569 // Let's see if it already exists.
1570 ACE_HANDLE fd = ACE_OS::shm_open (ACE_TEXT_CHAR_TO_TCHAR (name),
1571 O_RDWR | O_CREAT | O_EXCL,
1572 ACE_DEFAULT_FILE_PERMS);
1573 if (fd == ACE_INVALID_HANDLE)
1575 if (errno == EEXIST)
1576 fd = ACE_OS::shm_open (ACE_TEXT_CHAR_TO_TCHAR (name),
1578 ACE_DEFAULT_FILE_PERMS);
1584 // We own this shared memory object! Let's set its
1586 if (ACE_OS::ftruncate (fd,
1587 sizeof (ACE_sema_t)) == -1)
1589 s->name_ = ACE_OS::strdup (name);
1596 s->sema_ = (sem_t *)
1598 sizeof (ACE_sema_t),
1604 if (s->sema_ == (sem_t *) MAP_FAILED)
1607 // @@ According UNIX Network Programming V2 by Stevens,
1608 // sem_init() is currently not required to return zero on
1609 // success, but it *does* return -1 upon failure. For
1610 // this reason, check for failure by comparing to -1,
1611 // instead of checking for success by comparing to zero.
1613 // Only initialize it if we're the one who created it.
1614 && ::sem_init (s->sema_, type == USYNC_PROCESS, count) == -1)
1621 # if defined (sun) || defined (HPUX)
1622 // Solaris and HP-UX require the name to start with a slash. Solaris
1623 // further requires that there be no other slashes than the first.
1624 const char *last_slash = ACE_OS::strrchr (name, '/');
1625 char name2[MAXPATHLEN];
1626 if (0 == last_slash)
1628 ACE_OS::strcpy (name2, "/");
1629 ACE_OS::strcat (name2, name);
1634 name = last_slash; // Chop off chars preceding last slash
1636 # endif /* sun || HPUX */
1638 ACE_ALLOCATOR_RETURN (s->name_,
1639 ACE_OS::strdup (name),
1641 s->sema_ = ::sem_open (s->name_,
1643 ACE_DEFAULT_FILE_PERMS,
1645 if (s->sema_ == (sem_t *) SEM_FAILED)
1650 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1653 # if defined (ACE_LACKS_UNNAMED_SEMAPHORE)
1654 ACE_NOTSUP_RETURN (-1);
1656 #if defined (ACE_HAS_ALLOC_HOOKS)
1657 ACE_ALLOCATOR_RETURN (s->sema_,
1658 static_cast<sem_t*>(ACE_Allocator::instance()->malloc(sizeof(sem_t))),
1661 ACE_NEW_RETURN (s->sema_,
1664 #endif /* ACE_HAS_ALLOC_HOOKS */
1666 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1667 s->new_sema_ = true;
1668 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1669 ACE_OS::memset(s->sema_, 0, sizeof(*s->sema_));
1670 ACE_OSCALL_RETURN (::sem_init (s->sema_,
1671 type != USYNC_THREAD,
1673 # endif /* ACE_LACKS_UNNAMED_SEMAPHORE */
1676 #elif defined (ACE_USES_FIFO_SEM)
1677 ACE_UNUSED_ARG (arg);
1678 ACE_UNUSED_ARG (max);
1679 ACE_UNUSED_ARG (sa);
1681 mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP;
1683 if (type == USYNC_THREAD)
1685 // Create systemwide unique name for semaphore
1686 char uname[ACE_UNIQUE_NAME_LEN];
1687 ACE_OS::unique_name ((const void *) s,
1689 ACE_UNIQUE_NAME_LEN);
1694 s->fd_[0] = s->fd_[1] = ACE_INVALID_HANDLE;
1695 bool creator = false;
1697 if (ACE_OS::mkfifo (ACE_TEXT_CHAR_TO_TCHAR (name), mode) < 0)
1699 if (errno != EEXIST) /* already exists OK else ERR */
1701 // check if this is a real FIFO, not just some other existing file
1703 if (ACE_OS::stat (name, &fs))
1705 if (!S_ISFIFO (fs.st_mode))
1707 // existing file is not a FIFO
1713 creator = true; // remember we created it for initialization at end
1715 // for processshared semaphores remember who we are to be able to remove
1716 // the FIFO when we're done with it
1717 if (type == USYNC_PROCESS)
1719 s->name_ = ACE_OS::strdup (name);
1723 ACE_OS::unlink (name);
1728 if ((s->fd_[0] = ACE_OS::open (name, O_RDONLY | O_NONBLOCK)) == ACE_INVALID_HANDLE
1729 || (s->fd_[1] = ACE_OS::open (name, O_WRONLY | O_NONBLOCK)) == ACE_INVALID_HANDLE)
1732 /* turn off nonblocking for fd_[0] */
1733 if ((flags = ACE_OS::fcntl (s->fd_[0], F_GETFL, 0)) < 0)
1736 flags &= ~O_NONBLOCK;
1737 if (ACE_OS::fcntl (s->fd_[0], F_SETFL, flags) < 0)
1740 //if (s->name_ && count)
1741 if (creator && count)
1744 for (u_int i=0; i<count ;++i)
1745 if (ACE_OS::write (s->fd_[1], &c, sizeof (char)) != 1)
1749 // In the case of process scope semaphores we can already unlink the FIFO now that
1750 // we completely set it up (the opened handles will keep it active until we close
1751 // thos down). This way we're protected against unexpected crashes as far as removal
1753 // Unfortunately this does not work for processshared FIFOs since as soon as we
1754 // have unlinked the semaphore no other process will be able to open it anymore.
1755 if (type == USYNC_THREAD)
1757 ACE_OS::unlink (name);
1761 #elif defined (ACE_HAS_THREADS)
1762 # if defined (ACE_HAS_STHREADS)
1763 ACE_UNUSED_ARG (name);
1764 ACE_UNUSED_ARG (max);
1765 ACE_UNUSED_ARG (sa);
1766 ACE_UNUSED_ARG (attributes);
1768 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_init (s, count, type, arg), result),
1770 # elif defined (ACE_HAS_PTHREADS)
1771 ACE_UNUSED_ARG (max);
1772 ACE_UNUSED_ARG (sa);
1775 if (ACE_OS::mutex_init (&s->lock_, type, name,
1776 (ACE_mutexattr_t *) arg) == 0
1777 && (attributes == 0 ?
1778 ACE_OS::cond_init (&s->count_nonzero_, (short)type, name, arg) :
1779 ACE_OS::cond_init (&s->count_nonzero_, *attributes, name, arg)) == 0
1780 && ACE_OS::mutex_lock (&s->lock_) == 0)
1785 if (ACE_OS::mutex_unlock (&s->lock_) == 0)
1791 ACE_OS::mutex_destroy (&s->lock_);
1792 ACE_OS::cond_destroy (&s->count_nonzero_);
1795 # elif defined (ACE_HAS_WTHREADS)
1796 ACE_UNUSED_ARG (attributes);
1797 # if ! defined (ACE_USES_WINCE_SEMA_SIMULATION)
1798 ACE_UNUSED_ARG (type);
1799 ACE_UNUSED_ARG (arg);
1800 // Create the semaphore with its value initialized to <count> and
1801 // its maximum value initialized to <max>.
1802 SECURITY_ATTRIBUTES sa_buffer;
1803 SECURITY_DESCRIPTOR sd_buffer;
1804 *s = ACE_TEXT_CreateSemaphore
1805 (ACE_OS::default_win32_security_attributes_r (sa, &sa_buffer, &sd_buffer),
1808 ACE_TEXT_CHAR_TO_TCHAR (name));
1811 ACE_FAIL_RETURN (-1);
1815 // Make sure to set errno to ERROR_ALREADY_EXISTS if necessary.
1816 ACE_OS::set_errno_to_last_error ();
1819 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
1822 // Initialize internal object for semaphore simulation.
1823 // Grab the lock as soon as possible when we initializing
1824 // the semaphore count. Notice that we initialize the
1825 // event object as "manually reset" so we can amortize the
1826 // cost for singling/reseting the event.
1827 // @@ I changed the mutex type to thread_mutex. Notice that this
1828 // is basically a CriticalSection object and doesn't not has
1829 // any security attribute whatsoever. However, since this
1830 // semaphore implementation only works within a process, there
1831 // shouldn't any security issue at all.
1832 if (ACE_OS::thread_mutex_init (&s->lock_, type, name, (ACE_mutexattr_t *)arg) == 0
1833 && ACE_OS::event_init (&s->count_nonzero_, 1,
1834 count > 0, type, name, arg, sa) == 0
1835 && ACE_OS::thread_mutex_lock (&s->lock_) == 0)
1839 if (ACE_OS::thread_mutex_unlock (&s->lock_) == 0)
1843 // Destroy the internal objects if we didn't initialize
1844 // either of them successfully. Don't bother to check
1848 ACE_OS::thread_mutex_destroy (&s->lock_);
1849 ACE_OS::event_destroy (&s->count_nonzero_);
1852 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
1853 # elif defined (ACE_VXWORKS)
1854 ACE_UNUSED_ARG (attributes);
1855 ACE_UNUSED_ARG (name);
1856 ACE_UNUSED_ARG (arg);
1857 ACE_UNUSED_ARG (max);
1858 ACE_UNUSED_ARG (sa);
1860 s->sema_ = ::semCCreate (type, count);
1861 return s->sema_ ? 0 : -1;
1862 # endif /* ACE_HAS_STHREADS */
1865 ACE_UNUSED_ARG (count);
1866 ACE_UNUSED_ARG (type);
1867 ACE_UNUSED_ARG (attributes);
1868 ACE_UNUSED_ARG (name);
1869 ACE_UNUSED_ARG (arg);
1870 ACE_UNUSED_ARG (max);
1871 ACE_UNUSED_ARG (sa);
1872 ACE_NOTSUP_RETURN (-1);
1873 #endif /* ACE_HAS_POSIX_SEM */
1876 #if defined (ACE_HAS_WCHAR)
1878 ACE_OS::sema_init (ACE_sema_t *s,
1881 const wchar_t *name,
1884 LPSECURITY_ATTRIBUTES sa)
1886 ACE_condattr_t *pattr = 0;
1887 return ACE_OS::sema_init (s, count, type, pattr, name, arg, max, sa);
1891 ACE_OS::sema_init (ACE_sema_t *s,
1894 ACE_condattr_t *attributes,
1895 const wchar_t *name,
1898 LPSECURITY_ATTRIBUTES sa)
1900 # if defined (ACE_HAS_WTHREADS)
1901 ACE_UNUSED_ARG (attributes);
1902 # if ! defined (ACE_USES_WINCE_SEMA_SIMULATION)
1903 ACE_UNUSED_ARG (type);
1904 ACE_UNUSED_ARG (arg);
1905 // Create the semaphore with its value initialized to <count> and
1906 // its maximum value initialized to <max>.
1907 SECURITY_ATTRIBUTES sa_buffer;
1908 SECURITY_DESCRIPTOR sd_buffer;
1909 *s = ::CreateSemaphoreW
1910 (ACE_OS::default_win32_security_attributes_r (sa, &sa_buffer, &sd_buffer),
1916 ACE_FAIL_RETURN (-1);
1920 // Make sure to set errno to ERROR_ALREADY_EXISTS if necessary.
1921 ACE_OS::set_errno_to_last_error ();
1924 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
1927 // Initialize internal object for semaphore simulation.
1928 // Grab the lock as soon as possible when we initializing
1929 // the semaphore count. Notice that we initialize the
1930 // event object as "manually reset" so we can amortize the
1931 // cost for singling/reseting the event.
1932 // @@ I changed the mutex type to thread_mutex. Notice that this
1933 // is basically a CriticalSection object and doesn't not has
1934 // any security attribute whatsoever. However, since this
1935 // semaphore implementation only works within a process, there
1936 // shouldn't any security issue at all.
1937 if (ACE_OS::thread_mutex_init (&s->lock_, type, name, (ACE_mutexattr_t *)arg) == 0
1938 && ACE_OS::event_init (&s->count_nonzero_, 1,
1939 count > 0, type, name, arg, sa) == 0
1940 && ACE_OS::thread_mutex_lock (&s->lock_) == 0)
1944 if (ACE_OS::thread_mutex_unlock (&s->lock_) == 0)
1948 // Destroy the internal objects if we didn't initialize
1949 // either of them successfully. Don't bother to check
1953 ACE_OS::thread_mutex_destroy (&s->lock_);
1954 ACE_OS::event_destroy (&s->count_nonzero_);
1957 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
1958 # else /* ACE_HAS_WTHREADS */
1959 // Just call the normal char version.
1960 return ACE_OS::sema_init (s, count, type, attributes, ACE_Wide_To_Ascii (name).char_rep (), arg, max, sa);
1961 # endif /* ACE_HAS_WTHREADS */
1963 #endif /* ACE_HAS_WCHAR */
1966 ACE_OS::sema_avoid_unlink (ACE_sema_t *s, bool avoid_unlink)
1968 #if defined (ACE_HAS_POSIX_SEM)
1969 s->avoid_unlink_ = avoid_unlink;
1972 ACE_UNUSED_ARG (avoid_unlink);
1977 ACE_OS::sema_unlink (const char *name)
1979 #if defined (ACE_HAS_POSIX_SEM) && !defined (ACE_LACKS_SEM_UNLINK)
1980 ACE_OSCALL_RETURN (::sem_unlink (name), int, -1);
1982 ACE_UNUSED_ARG (name);
1983 ACE_NOTSUP_RETURN (-1);
1988 ACE_OS::sema_post (ACE_sema_t *s)
1990 ACE_OS_TRACE ("ACE_OS::sema_post");
1991 # if defined (ACE_HAS_POSIX_SEM)
1992 # if defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
1993 ACE_OSCALL_RETURN (::sem_post (s->sema_), int, -1);
1997 if (ACE_OS::mutex_lock (&s->lock_) == 0)
1999 if (::sem_post (s->sema_) == 0)
2000 result = ACE_OS::cond_signal (&s->count_nonzero_);
2002 ACE_OS::mutex_unlock (&s->lock_);
2005 # endif /* ACE_HAS_POSIX_SEM_TIMEOUT || ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION */
2006 # elif defined (ACE_USES_FIFO_SEM)
2008 if (ACE_OS::write (s->fd_[1], &c, sizeof (char)) == sizeof (char))
2011 # elif defined (ACE_HAS_THREADS)
2012 # if defined (ACE_HAS_STHREADS)
2014 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_post (s), result), int, -1);
2015 # elif defined (ACE_HAS_PTHREADS)
2018 if (ACE_OS::mutex_lock (&s->lock_) == 0)
2020 // Always allow a waiter to continue if there is one.
2021 if (s->waiters_ > 0)
2022 result = ACE_OS::cond_signal (&s->count_nonzero_);
2027 ACE_OS::mutex_unlock (&s->lock_);
2030 # elif defined (ACE_HAS_WTHREADS)
2031 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
2032 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*s, 1, 0),
2035 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
2038 // Since we are simulating semaphores, we need to update semaphore
2039 // count manually. Grab the lock to prevent race condition first.
2040 if (ACE_OS::thread_mutex_lock (&s->lock_) == 0)
2042 // Check the original state of event object. Single the event
2043 // object in transition from semaphore not available to
2044 // semaphore available.
2045 if (s->count_++ <= 0)
2046 result = ACE_OS::event_signal (&s->count_nonzero_);
2050 ACE_OS::thread_mutex_unlock (&s->lock_);
2053 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
2054 # elif defined (ACE_VXWORKS)
2055 ACE_OSCALL_RETURN (::semGive (s->sema_), int, -1);
2056 # endif /* ACE_HAS_STHREADS */
2059 ACE_NOTSUP_RETURN (-1);
2060 # endif /* ACE_HAS_POSIX_SEM */
2064 ACE_OS::sema_post (ACE_sema_t *s, u_int release_count)
2066 #if defined (ACE_WIN32) && !defined (ACE_USES_WINCE_SEMA_SIMULATION)
2067 // Win32 supports this natively.
2068 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*s, release_count, 0),
2069 ace_result_), int, -1);
2071 // On POSIX platforms we need to emulate this ourselves.
2072 // @@ We can optimize on this implementation. However,
2073 // the semaphore promitive on Win32 doesn't allow one
2074 // to increase a semaphore to more than the count it was
2075 // first initialized. Posix and solaris don't seem to have
2076 // this restriction. Should we impose the restriction in
2077 // our semaphore simulation?
2078 for (size_t i = 0; i < release_count; i++)
2079 if (ACE_OS::sema_post (s) == -1)
2083 #endif /* ACE_WIN32 */
2087 ACE_OS::sema_trywait (ACE_sema_t *s)
2089 ACE_OS_TRACE ("ACE_OS::sema_trywait");
2090 # if defined (ACE_HAS_POSIX_SEM)
2091 // POSIX semaphores set errno to EAGAIN if trywait fails
2092 ACE_OSCALL_RETURN (::sem_trywait (s->sema_), int, -1);
2093 # elif defined (ACE_USES_FIFO_SEM)
2097 /* turn on nonblocking for s->fd_[0] */
2098 if ((flags = ACE_OS::fcntl (s->fd_[0], F_GETFL, 0)) < 0)
2100 flags |= O_NONBLOCK;
2101 if (ACE_OS::fcntl (s->fd_[0], F_SETFL, flags) < 0)
2104 // read sets errno to EAGAIN if no input
2105 rc = ACE_OS::read (s->fd_[0], &c, sizeof (char));
2107 /* turn off nonblocking for fd_[0] */
2108 if ((flags = ACE_OS::fcntl (s->fd_[0], F_GETFL, 0)) >= 0)
2110 flags &= ~O_NONBLOCK;
2111 ACE_OS::fcntl (s->fd_[0], F_SETFL, flags);
2114 return rc == 1 ? 0 : (-1);
2115 # elif defined (ACE_HAS_THREADS)
2116 # if defined (ACE_HAS_STHREADS)
2117 // STHREADS semaphores set errno to EBUSY if trywait fails.
2119 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_trywait (s),
2122 # elif defined (ACE_HAS_PTHREADS)
2126 if (ACE_OS::mutex_lock (&s->lock_) == 0)
2136 ACE_OS::mutex_unlock (&s->lock_);
2139 # elif defined (ACE_HAS_WTHREADS)
2140 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
2141 DWORD result = ::WaitForSingleObject (*s, 0);
2143 if (result == WAIT_OBJECT_0)
2147 if (result == WAIT_TIMEOUT)
2150 ACE_OS::set_errno_to_last_error ();
2151 // This is a hack, we need to find an appropriate mapping...
2154 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
2155 // Check the status of semaphore first. Return immediately
2156 // if the semaphore is not available and avoid grabing the
2158 DWORD result = ::WaitForSingleObject (s->count_nonzero_, 0);
2160 if (result == WAIT_OBJECT_0) // Proceed when it is available.
2162 ACE_OS::thread_mutex_lock (&s->lock_);
2164 // Need to double check if the semaphore is still available.
2165 // The double checking scheme will slightly affect the
2166 // efficiency if most of the time semaphores are not blocked.
2167 result = ::WaitForSingleObject (s->count_nonzero_, 0);
2168 if (result == WAIT_OBJECT_0)
2170 // Adjust the semaphore count. Only update the event
2171 // object status when the state changed.
2174 ACE_OS::event_reset (&s->count_nonzero_);
2178 ACE_OS::thread_mutex_unlock (&s->lock_);
2181 // Translate error message to errno used by ACE.
2182 if (result == WAIT_TIMEOUT)
2185 ACE_OS::set_errno_to_last_error ();
2186 // This is taken from the hack above. ;)
2188 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
2189 # elif defined (ACE_VXWORKS)
2190 if (::semTake (s->sema_, NO_WAIT) == ERROR)
2191 if (errno == S_objLib_OBJ_UNAVAILABLE)
2193 // couldn't get the semaphore
2201 // got the semaphore
2203 # endif /* ACE_HAS_STHREADS */
2206 ACE_NOTSUP_RETURN (-1);
2207 # endif /* ACE_HAS_POSIX_SEM */
2211 ACE_OS::sema_wait (ACE_sema_t *s)
2213 ACE_OS_TRACE ("ACE_OS::sema_wait");
2214 # if defined (ACE_HAS_POSIX_SEM)
2215 ACE_OSCALL_RETURN (::sem_wait (s->sema_), int, -1);
2216 # elif defined (ACE_USES_FIFO_SEM)
2218 if (ACE_OS::read (s->fd_[0], &c, sizeof (char)) == 1)
2221 # elif defined (ACE_HAS_THREADS)
2222 # if defined (ACE_HAS_STHREADS)
2224 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_wait (s), result), int, -1);
2225 # elif defined (ACE_HAS_PTHREADS)
2228 ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
2230 if (ACE_OS::mutex_lock (&s->lock_) != 0)
2234 // Keep track of the number of waiters so that we can signal
2235 // them properly in <ACE_OS::sema_post>.
2238 // Wait until the semaphore count is > 0.
2239 while (s->count_ == 0)
2240 if (ACE_OS::cond_wait (&s->count_nonzero_,
2243 result = -2; // -2 means that we need to release the mutex.
2254 ACE_OS::mutex_unlock (&s->lock_);
2255 ACE_PTHREAD_CLEANUP_POP (0);
2256 return result < 0 ? -1 : result;
2258 # elif defined (ACE_HAS_WTHREADS)
2259 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
2260 switch (::WaitForSingleObject (*s, INFINITE))
2265 // This is a hack, we need to find an appropriate mapping...
2266 ACE_OS::set_errno_to_last_error ();
2270 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
2274 // Check if the semaphore is avialable or not and wait forever.
2275 // Don't bother to grab the lock if it is not available (to avoid
2277 switch (::WaitForSingleObject (s->count_nonzero_, INFINITE))
2280 ACE_OS::thread_mutex_lock (&s->lock_);
2282 // Need to double check if the semaphore is still available.
2283 // This time, we shouldn't wait at all.
2284 if (::WaitForSingleObject (s->count_nonzero_, 0) == WAIT_OBJECT_0)
2286 // Decrease the internal counter. Only update the event
2287 // object's status when the state changed.
2290 ACE_OS::event_reset (&s->count_nonzero_);
2294 ACE_OS::thread_mutex_unlock (&s->lock_);
2295 // if we didn't get a hold on the semaphore, the result won't
2296 // be 0 and thus, we'll start from the beginning again.
2302 // Since we wait indefinitely, anything other than
2303 // WAIT_OBJECT_O indicates an error.
2304 ACE_OS::set_errno_to_last_error ();
2305 // This is taken from the hack above. ;)
2309 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
2310 # elif defined (ACE_VXWORKS)
2311 ACE_OSCALL_RETURN (::semTake (s->sema_, WAIT_FOREVER), int, -1);
2312 # endif /* ACE_HAS_STHREADS */
2315 ACE_NOTSUP_RETURN (-1);
2316 # endif /* ACE_HAS_POSIX_SEM */
2320 ACE_OS::sema_wait (ACE_sema_t *s, ACE_Time_Value &tv)
2322 ACE_OS_TRACE ("ACE_OS::sema_wait");
2323 # if defined (ACE_HAS_POSIX_SEM)
2324 # if defined (ACE_HAS_POSIX_SEM_TIMEOUT)
2327 ts = tv; // Calls ACE_Time_Value::operator timespec_t().
2328 ACE_OSCALL (::sem_timedwait (s->sema_, &ts), int, -1, rc);
2329 if (rc == -1 && errno == ETIMEDOUT)
2330 errno = ETIME; /* POSIX returns ETIMEDOUT but we need ETIME */
2332 # elif !defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
2334 bool expired = false;
2335 ACE_Errno_Guard error (errno);
2337 ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
2339 if (ACE_OS::mutex_lock (&s->lock_) != 0)
2343 bool finished = true;
2346 result = ACE_OS::sema_trywait (s);
2347 if (result == -1 && errno == EAGAIN)
2348 expired = (tv.to_relative_time () <= ACE_Time_Value::zero);
2352 finished = result != -1 || expired ||
2353 (result == -1 && errno != EAGAIN);
2356 if (ACE_OS::cond_timedwait (&s->count_nonzero_,
2365 } while (!finished);
2370 # if defined (ACE_LACKS_COND_TIMEDWAIT_RESET)
2372 # endif /* ACE_LACKS_COND_TIMEDWAIT_RESET */
2376 ACE_OS::mutex_unlock (&s->lock_);
2377 ACE_PTHREAD_CLEANUP_POP (0);
2378 return result < 0 ? -1 : result;
2379 # else /* No native sem_timedwait(), and emulation disabled */
2381 ACE_UNUSED_ARG (tv);
2382 ACE_NOTSUP_RETURN (-1);
2383 # endif /* ACE_HAS_POSIX_SEM_TIMEOUT */
2384 # elif defined (ACE_USES_FIFO_SEM)
2386 ACE_Time_Value timeout = tv.to_relative_time ();
2388 while (timeout > ACE_Time_Value::zero)
2390 ACE_Handle_Set fds_;
2392 fds_.set_bit (s->fd_[0]);
2393 if ((rc = ACE_OS::select (ACE_Handle_Set::MAXSIZE, fds_, 0, 0, timeout)) != 1)
2395 if (rc == 0 || errno != EAGAIN)
2403 // try to read the signal *but* do *not* block
2404 if (rc == 1 && ACE_OS::sema_trywait (s) == 0)
2407 // we were woken for input but someone beat us to it
2408 // so we wait again if there is still time
2409 timeout = tv.to_relative_time ();
2412 // make sure errno is set right
2416 # elif defined (ACE_HAS_THREADS)
2417 # if defined (ACE_HAS_STHREADS)
2419 ACE_UNUSED_ARG (tv);
2420 ACE_NOTSUP_RETURN (-1);
2421 # elif defined (ACE_HAS_PTHREADS)
2423 ACE_Errno_Guard error (errno);
2425 ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
2427 if (ACE_OS::mutex_lock (&s->lock_) != 0)
2431 // Keep track of the number of waiters so that we can signal
2432 // them properly in <ACE_OS::sema_post>.
2435 // Wait until the semaphore count is > 0 or until we time out.
2436 while (s->count_ == 0)
2437 if (ACE_OS::cond_timedwait (&s->count_nonzero_,
2442 result = -2; // -2 means that we need to release the mutex.
2451 # if defined (ACE_LACKS_COND_TIMEDWAIT_RESET)
2453 # endif /* ACE_LACKS_COND_TIMEDWAIT_RESET */
2458 ACE_OS::mutex_unlock (&s->lock_);
2459 ACE_PTHREAD_CLEANUP_POP (0);
2460 return result < 0 ? -1 : result;
2461 # elif defined (ACE_HAS_WTHREADS)
2462 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
2465 if (tv == ACE_Time_Value::zero)
2466 msec_timeout = 0; // Do a "poll."
2469 // Note that we must convert between absolute time (which is
2470 // passed as a parameter) and relative time (which is what
2471 // <WaitForSingleObjects> expects).
2472 ACE_Time_Value relative_time = tv.to_relative_time ();
2474 // Watchout for situations where a context switch has caused the
2475 // current time to be > the timeout.
2476 if (relative_time < ACE_Time_Value::zero)
2479 msec_timeout = relative_time.msec ();
2482 switch (::WaitForSingleObject (*s, msec_timeout))
2485 tv = tv.now (); // Update time to when acquired
2491 // This is a hack, we need to find an appropriate mapping...
2492 ACE_OS::set_errno_to_last_error ();
2496 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
2497 // Note that in this mode, the acquire is done in two steps, and
2498 // we may get signaled but cannot grab the semaphore before
2499 // timeout. In that case, we'll need to restart the process with
2500 // updated timeout value.
2502 // tv is an absolute time, but we need relative to work with the Windows
2503 // API. Also, some users have become accustomed to using a 0 time value
2504 // as a shortcut for "now", which works on non-Windows because 0 is
2505 // always earlier than now. However, the need to convert to relative time
2506 // means we need to watch out for this case.
2507 ACE_Time_Value relative_time (ACE_Time_Value::zero);
2508 if (tv != ACE_Time_Value::zero)
2509 relative_time = tv.to_relative_time ();
2512 // While we are not timeout yet. >= 0 will let this go through once
2513 // and if not able to get the object, it should hit WAIT_TIMEOUT
2515 while (relative_time >= ACE_Time_Value::zero)
2517 // Wait for our turn to get the object.
2518 switch (::WaitForSingleObject (s->count_nonzero_, relative_time.msec ()))
2521 ACE_OS::thread_mutex_lock (&s->lock_);
2523 // Need to double check if the semaphore is still available.
2524 // We can only do a "try lock" styled wait here to avoid
2525 // blocking threads that want to signal the semaphore.
2526 if (::WaitForSingleObject (s->count_nonzero_, 0) == WAIT_OBJECT_0)
2528 // As before, only reset the object when the semaphore
2529 // is no longer available.
2532 ACE_OS::event_reset (&s->count_nonzero_);
2536 ACE_OS::thread_mutex_unlock (&s->lock_);
2538 // Only return when we successfully get the semaphore.
2541 tv = tv.now (); // Update to time acquired
2546 // We have timed out.
2553 ACE_OS::set_errno_to_last_error ();
2554 // This is taken from the hack above. ;)
2558 // Haven't been able to get the semaphore yet, update the
2559 // timeout value to reflect the remaining time we want to wait.
2560 // in case of tv == 0 relative_time will now be < 0 and we will be out of time
2561 relative_time = tv.to_relative_time ();
2564 // We have timed out.
2567 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
2568 # elif defined (ACE_VXWORKS)
2569 // Note that we must convert between absolute time (which is
2570 // passed as a parameter) and relative time (which is what
2571 // the system call expects).
2572 ACE_Time_Value relative_time = tv.to_relative_time ();
2574 int ticks_per_sec = ::sysClkRateGet ();
2576 int ticks = relative_time.sec () * ticks_per_sec +
2577 relative_time.usec () * ticks_per_sec / ACE_ONE_SECOND_IN_USECS;
2578 if (::semTake (s->sema_, ticks) == ERROR)
2580 if (errno == S_objLib_OBJ_TIMEOUT)
2581 // Convert the VxWorks errno to one that's common for to ACE
2584 else if (errno == S_objLib_OBJ_UNAVAILABLE)
2590 tv = tv.now (); // Update to time acquired
2593 # endif /* ACE_HAS_STHREADS */
2596 ACE_UNUSED_ARG (tv);
2597 ACE_NOTSUP_RETURN (-1);
2598 # endif /* ACE_HAS_POSIX_SEM */
2602 ACE_OS::sema_wait (ACE_sema_t *s, ACE_Time_Value *tv)
2604 return tv == 0 ? ACE_OS::sema_wait (s) : ACE_OS::sema_wait (s, *tv);
2608 ACE_OS::semctl (int int_id, int semnum, int cmd, semun value)
2610 ACE_OS_TRACE ("ACE_OS::semctl");
2611 #if defined (ACE_HAS_SYSV_IPC)
2612 ACE_OSCALL_RETURN (::semctl (int_id, semnum, cmd, value), int, -1);
2614 ACE_UNUSED_ARG (int_id);
2615 ACE_UNUSED_ARG (semnum);
2616 ACE_UNUSED_ARG (cmd);
2617 ACE_UNUSED_ARG (value);
2619 ACE_NOTSUP_RETURN (-1);
2620 #endif /* ACE_HAS_SYSV_IPC */
2624 ACE_OS::semget (key_t key, int nsems, int flags)
2626 ACE_OS_TRACE ("ACE_OS::semget");
2627 #if defined (ACE_HAS_SYSV_IPC)
2628 ACE_OSCALL_RETURN (::semget (key, nsems, flags), int, -1);
2630 ACE_UNUSED_ARG (key);
2631 ACE_UNUSED_ARG (nsems);
2632 ACE_UNUSED_ARG (flags);
2634 ACE_NOTSUP_RETURN (-1);
2635 #endif /* ACE_HAS_SYSV_IPC */
2639 ACE_OS::semop (int int_id, struct sembuf *sops, size_t nsops)
2641 ACE_OS_TRACE ("ACE_OS::semop");
2642 #if defined (ACE_HAS_SYSV_IPC)
2643 ACE_OSCALL_RETURN (::semop (int_id, sops, nsops), int, -1);
2645 ACE_UNUSED_ARG (int_id);
2646 ACE_UNUSED_ARG (sops);
2647 ACE_UNUSED_ARG (nsops);
2649 ACE_NOTSUP_RETURN (-1);
2650 #endif /* ACE_HAS_SYSV_IPC */
2654 ACE_OS::sigtimedwait (const sigset_t *sset,
2656 const ACE_Time_Value *timeout)
2658 ACE_OS_TRACE ("ACE_OS::sigtimedwait");
2659 #if defined (ACE_HAS_SIGTIMEDWAIT)
2661 timespec_t *tsp = 0;
2665 ts = *timeout; // Calls ACE_Time_Value::operator timespec_t().
2669 ACE_OSCALL_RETURN (::sigtimedwait (sset, info, tsp),
2672 ACE_UNUSED_ARG (sset);
2673 ACE_UNUSED_ARG (info);
2674 ACE_UNUSED_ARG (timeout);
2675 ACE_NOTSUP_RETURN (-1);
2676 #endif /* ACE_HAS_SIGTIMEDWAIT */
2680 ACE_OS::sigwait (sigset_t *sset, int *sig)
2682 ACE_OS_TRACE ("ACE_OS::sigwait");
2686 #if defined (ACE_HAS_THREADS)
2687 # if (defined (__FreeBSD__) && (__FreeBSD__ < 3))
2688 ACE_UNUSED_ARG (sset);
2689 ACE_NOTSUP_RETURN (-1);
2690 # elif defined (ACE_HAS_STHREADS)
2691 # if (_POSIX_C_SOURCE - 0 >= 199506L) || defined (_POSIX_PTHREAD_SEMANTICS)
2692 errno = ::sigwait (sset, sig);
2693 return errno == 0 ? *sig : -1;
2695 *sig = ::sigwait (sset);
2697 #endif /* _POSIX_C_SOURCE - 0 >= 199506L || _POSIX_PTHREAD_SEMANTICS */
2698 # elif defined (ACE_HAS_PTHREADS)
2699 # if defined (CYGWIN32)
2700 // Cygwin has sigwait definition, but it is not implemented
2701 ACE_UNUSED_ARG (sset);
2702 ACE_NOTSUP_RETURN (-1);
2703 # else /* this is std */
2704 errno = ::sigwait (sset, sig);
2705 return errno == 0 ? *sig : -1;
2706 # endif /* CYGWIN32 */
2707 # elif defined (ACE_HAS_WTHREADS)
2708 ACE_UNUSED_ARG (sset);
2709 ACE_NOTSUP_RETURN (-1);
2710 # elif defined (ACE_VXWORKS)
2711 // Second arg is a struct siginfo *, which we don't need (the
2712 // selected signal number is returned). Third arg is timeout: 0
2714 *sig = ::sigtimedwait (sset, 0, 0);
2716 # endif /* __FreeBSD__ */
2718 ACE_UNUSED_ARG (sset);
2719 ACE_UNUSED_ARG (sig);
2720 ACE_NOTSUP_RETURN (-1);
2721 #endif /* ACE_HAS_THREADS */
2725 ACE_OS::sigwaitinfo (const sigset_t *sset,
2728 ACE_OS_TRACE ("ACE_OS::sigwaitinfo");
2729 // If this platform has sigtimedwait, it should have sigwaitinfo as well.
2730 // If this isn't true somewhere, let me know and I'll fix this.
2731 // -Steve Huston <shuston@riverace.com>.
2732 #if defined (ACE_HAS_SIGTIMEDWAIT)
2733 ACE_OSCALL_RETURN (::sigwaitinfo (sset, info), int, -1);
2735 ACE_UNUSED_ARG (sset);
2736 ACE_UNUSED_ARG (info);
2737 ACE_NOTSUP_RETURN (-1);
2738 #endif /* ACE_HAS_SIGTIMEDWAIT */
2742 ACE_OS::thr_cancel (ACE_thread_t thr_id)
2744 ACE_OS_TRACE ("ACE_OS::thr_cancel");
2745 #if defined (ACE_HAS_THREADS)
2746 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
2748 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cancel (thr_id),
2751 # elif defined (ACE_HAS_VXTHREADS)
2752 ACE_OSCALL_RETURN (::taskDelete (thr_id), int, -1);
2753 # else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
2754 ACE_UNUSED_ARG (thr_id);
2755 ACE_NOTSUP_RETURN (-1);
2756 # endif /* ACE_HAS_PTHREADS */
2758 ACE_UNUSED_ARG (thr_id);
2759 ACE_NOTSUP_RETURN (-1);
2760 #endif /* ACE_HAS_THREADS */
2764 ACE_OS::thr_cmp (ACE_hthread_t t1, ACE_hthread_t t2)
2766 #if defined (ACE_HAS_PTHREADS)
2767 # if defined (pthread_equal)
2768 // If it's a macro we can't say "pthread_equal"...
2769 return pthread_equal (t1, t2);
2771 return pthread_equal (t1, t2);
2772 # endif /* pthread_equal */
2773 #else /* For STHREADS, WTHREADS, and VXWORKS ... */
2774 // Hum, Do we need to treat WTHREAD differently?
2775 // levine 13 oct 98 % Probably, ACE_hthread_t is a HANDLE.
2777 #endif /* ACE_HAS_PTHREADS */
2781 ACE_OS::thr_continue (ACE_hthread_t target_thread)
2783 ACE_OS_TRACE ("ACE_OS::thr_continue");
2784 #if defined (ACE_HAS_THREADS)
2785 # if defined (ACE_HAS_STHREADS)
2787 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_continue (target_thread), result), int, -1);
2788 # elif defined (ACE_HAS_PTHREADS)
2789 # if defined (ACE_HAS_PTHREAD_CONTINUE)
2791 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_continue (target_thread),
2794 # elif defined (ACE_HAS_PTHREAD_CONTINUE_NP)
2796 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_continue_np (target_thread),
2799 # elif defined (ACE_HAS_PTHREAD_RESUME_NP)
2801 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_resume_np (target_thread),
2805 ACE_UNUSED_ARG (target_thread);
2806 ACE_NOTSUP_RETURN (-1);
2807 # endif /* ACE_HAS_PTHREAD_CONTINUE */
2808 # elif defined (ACE_HAS_WTHREADS)
2809 DWORD result = ::ResumeThread (target_thread);
2810 if (result == ACE_SYSCALL_FAILED)
2811 ACE_FAIL_RETURN (-1);
2814 # elif defined (ACE_HAS_VXTHREADS)
2815 ACE_OSCALL_RETURN (::taskResume (target_thread), int, -1);
2816 # endif /* ACE_HAS_STHREADS */
2818 ACE_UNUSED_ARG (target_thread);
2819 ACE_NOTSUP_RETURN (-1);
2820 #endif /* ACE_HAS_THREADS */
2824 ACE_OS::thr_getconcurrency (void)
2826 ACE_OS_TRACE ("ACE_OS::thr_getconcurrency");
2827 #if defined (ACE_HAS_THREADS)
2828 # if defined (ACE_HAS_STHREADS)
2829 return ::thr_getconcurrency ();
2830 # elif defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_PTHREAD_GETCONCURRENCY)
2831 return pthread_getconcurrency ();
2833 ACE_NOTSUP_RETURN (-1);
2834 # endif /* ACE_HAS_STHREADS */
2836 ACE_NOTSUP_RETURN (-1);
2837 #endif /* ACE_HAS_THREADS */
2841 ACE_OS::thr_getprio (ACE_hthread_t ht_id, int &priority, int &policy)
2843 ACE_OS_TRACE ("ACE_OS::thr_getprio");
2844 ACE_UNUSED_ARG (policy);
2845 #if defined (ACE_HAS_THREADS)
2846 # if (defined (ACE_HAS_PTHREADS) && \
2847 (!defined (ACE_LACKS_SETSCHED) || defined (ACE_HAS_PTHREAD_SCHEDPARAM)))
2849 struct sched_param param;
2852 ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_getschedparam (ht_id, &policy, ¶m),
2855 priority = param.sched_priority;
2857 # elif defined (ACE_HAS_STHREADS)
2859 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_getprio (ht_id, &priority), result), int, -1);
2860 # elif defined (ACE_HAS_WTHREADS)
2861 ACE_Errno_Guard error (errno);
2863 # if defined (ACE_HAS_WINCE) && !defined (ACE_LACKS_CE_THREAD_PRIORITY)
2864 priority = ::CeGetThreadPriority (ht_id);
2866 priority = ::GetThreadPriority (ht_id);
2867 # endif /* defined (ACE_HAS_WINCE) && !defined (ACE_LACKS_CE_THREAD_PRIORITY) */
2869 # if defined (ACE_HAS_PHARLAP)
2870 # if defined (ACE_PHARLAP_LABVIEW_RT)
2871 policy = ACE_SCHED_FIFO;
2873 DWORD timeslice = ::EtsGetTimeSlice ();
2874 policy = timeslice == 0 ? ACE_SCHED_OTHER : ACE_SCHED_FIFO;
2875 # endif /* ACE_PHARLAP_LABVIEW_RT */
2876 # elif !defined (ACE_HAS_WINCE)
2877 DWORD priority_class = ::GetPriorityClass (::GetCurrentProcess ());
2878 if (priority_class == 0 && (error = ::GetLastError ()) != NO_ERROR)
2879 ACE_FAIL_RETURN (-1);
2883 REALTIME_PRIORITY_CLASS) ? ACE_SCHED_FIFO : ACE_SCHED_OTHER;
2884 # endif /* ACE_HAS_PHARLAP */
2887 # elif defined (ACE_HAS_VXTHREADS)
2888 ACE_OSCALL_RETURN (::taskPriorityGet (ht_id, &priority), int, -1);
2890 ACE_UNUSED_ARG (ht_id);
2891 ACE_UNUSED_ARG (priority);
2892 ACE_NOTSUP_RETURN (-1);
2893 # endif /* ACE_HAS_STHREADS */
2895 ACE_UNUSED_ARG (ht_id);
2896 ACE_UNUSED_ARG (priority);
2897 ACE_NOTSUP_RETURN (-1);
2898 #endif /* ACE_HAS_THREADS */
2902 ACE_OS::thr_getprio (ACE_hthread_t ht_id, int &priority)
2904 ACE_OS_TRACE ("ACE_OS::thr_getprio");
2906 return ACE_OS::thr_getprio (ht_id, priority, policy);
2909 #if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
2911 ACE_OS::thr_getspecific_native (ACE_OS_thread_key_t key, void **data)
2913 // ACE_OS_TRACE ("ACE_OS::thr_getspecific_native");
2914 # if defined (ACE_HAS_PTHREADS)
2915 *data = pthread_getspecific (key);
2917 # elif defined (ACE_HAS_STHREADS)
2919 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_getspecific (key, data), result), int, -1);
2920 # elif defined (ACE_HAS_WTHREADS)
2921 *data = ::TlsGetValue (key);
2922 if (*data == 0 && ::GetLastError () != NO_ERROR)
2924 ACE_OS::set_errno_to_last_error ();
2929 # else /* ACE_HAS_PTHREADS etc.*/
2930 ACE_UNUSED_ARG (key);
2931 ACE_UNUSED_ARG (data);
2932 ACE_NOTSUP_RETURN (-1);
2933 # endif /* ACE_HAS_PTHREADS etc.*/
2935 #endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
2938 ACE_OS::thr_getspecific (ACE_thread_key_t key, void **data)
2940 // ACE_OS_TRACE ("ACE_OS::thr_getspecific");
2941 #if defined (ACE_HAS_THREADS)
2942 # if defined (ACE_HAS_TSS_EMULATION)
2943 if (ACE_TSS_Emulation::is_key (key) == 0)
2951 *data = ACE_TSS_Emulation::ts_object (key);
2954 # elif defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
2955 return ACE_OS::thr_getspecific_native (key, data);
2957 ACE_UNUSED_ARG (key);
2958 ACE_UNUSED_ARG (data);
2959 ACE_NOTSUP_RETURN (-1);
2960 # endif /* ACE_HAS_TSS_EMULATION */
2962 ACE_UNUSED_ARG (key);
2963 ACE_UNUSED_ARG (data);
2964 ACE_NOTSUP_RETURN (-1);
2965 #endif /* ACE_HAS_THREADS */
2968 #if !defined (ACE_HAS_VXTHREADS)
2970 ACE_OS::thr_join (ACE_hthread_t thr_handle,
2971 ACE_THR_FUNC_RETURN *status)
2973 ACE_OS_TRACE ("ACE_OS::thr_join");
2974 #if defined (ACE_HAS_THREADS)
2975 # if defined (ACE_HAS_STHREADS)
2977 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_join (thr_handle, 0, status), result),
2979 # elif defined (ACE_HAS_PTHREADS)
2980 # if defined (ACE_LACKS_PTHREAD_JOIN)
2981 ACE_UNUSED_ARG (thr_handle);
2982 ACE_UNUSED_ARG (status);
2983 ACE_NOTSUP_RETURN (-1);
2986 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_join (thr_handle, status), result),
2988 # endif /* ACE_LACKS_PTHREAD_JOIN */
2989 # elif defined (ACE_HAS_WTHREADS)
2990 // Waiting on the calling thread will deadlock, so try to avoid that. The
2991 // direct access to the needed info (GetThreadId) was added at Vista.
2992 // Win Server 2003 is 5.2; Vista is 6.0
2993 # if defined (_WIN32_WINNT) && (_WIN32_WINNT >= 0x0502)
2994 const ACE_TEXT_OSVERSIONINFO &info = ACE_OS::get_win32_versioninfo ();
2995 if (info.dwMajorVersion >= 6 ||
2996 (info.dwMajorVersion == 5 && info.dwMinorVersion == 2))
2998 if (::GetThreadId (thr_handle) == ::GetCurrentThreadId ())
3000 errno = ERROR_POSSIBLE_DEADLOCK;
3004 # endif /* _WIN32_WINNT */
3006 ACE_THR_FUNC_RETURN local_status = 0;
3008 // Make sure that status is non-NULL.
3010 status = &local_status;
3012 if (::WaitForSingleObject (thr_handle, INFINITE) == WAIT_OBJECT_0
3013 && ::GetExitCodeThread (thr_handle, status) != FALSE)
3015 ::CloseHandle (thr_handle);
3018 ACE_FAIL_RETURN (-1);
3021 ACE_UNUSED_ARG (thr_handle);
3022 ACE_UNUSED_ARG (status);
3023 ACE_NOTSUP_RETURN (-1);
3024 # endif /* ACE_HAS_STHREADS */
3026 ACE_UNUSED_ARG (thr_handle);
3027 ACE_UNUSED_ARG (status);
3028 ACE_NOTSUP_RETURN (-1);
3029 #endif /* ACE_HAS_THREADS */
3033 ACE_OS::thr_join (ACE_thread_t waiter_id,
3034 ACE_thread_t *thr_id,
3035 ACE_THR_FUNC_RETURN *status)
3037 ACE_OS_TRACE ("ACE_OS::thr_join");
3038 #if defined (ACE_HAS_THREADS)
3039 # if defined (ACE_HAS_STHREADS)
3041 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_join (waiter_id, thr_id, status), result),
3043 # elif defined (ACE_HAS_PTHREADS)
3044 # if defined (ACE_LACKS_PTHREAD_JOIN)
3045 ACE_UNUSED_ARG (waiter_id);
3046 ACE_UNUSED_ARG (thr_id);
3047 ACE_UNUSED_ARG (status);
3048 ACE_NOTSUP_RETURN (-1);
3050 ACE_UNUSED_ARG (thr_id);
3052 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_join (waiter_id, status), result),
3054 # endif /* ACE_LACKS_PTHREAD_JOIN */
3055 # elif defined (ACE_HAS_WTHREADS)
3056 ACE_UNUSED_ARG (waiter_id);
3057 ACE_UNUSED_ARG (thr_id);
3058 ACE_UNUSED_ARG (status);
3060 // This could be implemented if the DLL-Main function or the
3061 // task exit base class some log the threads which have exited
3062 ACE_NOTSUP_RETURN (-1);
3063 # endif /* ACE_HAS_STHREADS */
3065 ACE_UNUSED_ARG (waiter_id);
3066 ACE_UNUSED_ARG (thr_id);
3067 ACE_UNUSED_ARG (status);
3068 ACE_NOTSUP_RETURN (-1);
3069 #endif /* ACE_HAS_THREADS */
3071 #endif /* !VXWORKS */
3074 ACE_OS::thr_kill (ACE_thread_t thr_id, int signum)
3076 ACE_OS_TRACE ("ACE_OS::thr_kill");
3077 #if defined (ACE_HAS_THREADS)
3078 # if defined (ACE_HAS_PTHREADS)
3079 # if defined (ACE_LACKS_PTHREAD_KILL)
3080 ACE_UNUSED_ARG (signum);
3081 ACE_UNUSED_ARG (thr_id);
3082 ACE_NOTSUP_RETURN (-1);
3085 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_kill (thr_id, signum),
3088 # endif /* ACE_LACKS_PTHREAD_KILL */
3089 # elif defined (ACE_HAS_STHREADS)
3091 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_kill (thr_id, signum),
3094 # elif defined (ACE_HAS_VXTHREADS)
3095 //FUZZ: disable check_for_lack_ACE_OS
3096 ACE_OSCALL_RETURN (::kill (thr_id, signum), int, -1);
3097 //FUZZ: enable check_for_lack_ACE_OS
3099 ACE_UNUSED_ARG (thr_id);
3100 ACE_UNUSED_ARG (signum);
3101 ACE_NOTSUP_RETURN (-1);
3102 # endif /* ACE_HAS_STHREADS */
3104 ACE_UNUSED_ARG (thr_id);
3105 ACE_UNUSED_ARG (signum);
3106 ACE_NOTSUP_RETURN (-1);
3107 #endif /* ACE_HAS_THREADS */
3111 ACE_OS::thr_min_stack (void)
3113 ACE_OS_TRACE ("ACE_OS::thr_min_stack");
3114 #if defined (ACE_HAS_THREADS)
3115 # if defined (ACE_HAS_STHREADS)
3116 # if defined (ACE_HAS_THR_MINSTACK)
3117 // Tandem did some weirdo mangling of STHREAD names...
3118 return ::thr_minstack ();
3120 return ::thr_min_stack ();
3121 # endif /* !ACE_HAS_THR_MINSTACK */
3122 # elif defined (ACE_HAS_PTHREADS)
3123 # if defined (_SC_THREAD_STACK_MIN)
3124 return (size_t) ACE_OS::sysconf (_SC_THREAD_STACK_MIN);
3125 # elif defined (PTHREAD_STACK_MIN)
3126 return PTHREAD_STACK_MIN;
3128 ACE_NOTSUP_RETURN (0);
3129 # endif /* _SC_THREAD_STACK_MIN */
3130 # elif defined (ACE_HAS_WTHREADS)
3131 ACE_NOTSUP_RETURN (0);
3132 # elif defined (ACE_HAS_VXTHREADS)
3136 ACE_thread_t tid = ACE_OS::thr_self ();
3138 ACE_OSCALL (ACE_ADAPT_RETVAL (::taskInfoGet (tid, &taskDesc),
3140 STATUS, -1, status);
3141 return status == OK ? taskDesc.td_stackSize : 0;
3142 # else /* Should not happen... */
3143 ACE_NOTSUP_RETURN (0);
3144 # endif /* ACE_HAS_STHREADS */
3146 ACE_NOTSUP_RETURN (0);
3147 #endif /* ACE_HAS_THREADS */
3151 ACE_OS::thr_id (char buffer[], size_t buffer_length)
3153 #if defined (ACE_WIN32)
3154 return ACE_OS::snprintf (buffer,
3157 static_cast <unsigned> (ACE_OS::thr_self ()));
3158 #else /* ACE_WIN32 */
3160 ACE_OS::thr_self (t_id);
3161 #if defined(ACE_HAS_OPAQUE_PTHREAD_T)
3162 return ACE_OS::snprintf (buffer,
3166 #else /* ACE_HAS_OPAQUE_PTHREAD_T */
3167 return ACE_OS::snprintf (buffer,
3170 (unsigned long) t_id);
3171 #endif /* ACE_HAS_OPAQUE_PTHREAD_T */
3176 ACE_OS::thr_gettid (char buffer[], size_t buffer_length)
3178 return ACE_OS::snprintf (buffer, buffer_length, "%d",
3179 static_cast<int> (ACE_OS::thr_gettid ()));
3182 ACE_INLINE ACE_thread_t
3183 ACE_OS::thr_self (void)
3185 // ACE_OS_TRACE ("ACE_OS::thr_self");
3186 #if defined (ACE_HAS_THREADS)
3187 # if defined (ACE_HAS_PTHREADS)
3188 // Note, don't use "::" here since the following call is often a macro.
3189 return pthread_self ();
3190 # elif defined (ACE_HAS_STHREADS)
3191 ACE_OSCALL_RETURN (::thr_self (), int, -1);
3192 # elif defined (ACE_HAS_WTHREADS)
3193 return ::GetCurrentThreadId ();
3194 # elif defined (ACE_HAS_VXTHREADS)
3195 return ::taskIdSelf ();
3196 # endif /* ACE_HAS_STHREADS */
3198 return 1; // Might as well make it the first thread ;-)
3199 #endif /* ACE_HAS_THREADS */
3202 ACE_INLINE const char*
3203 ACE_OS::thr_name (void)
3205 #if defined (ACE_HAS_THREADS)
3206 #if defined (ACE_HAS_VXTHREADS)
3207 return ::taskName (ACE_OS::thr_self ());
3209 ACE_NOTSUP_RETURN (0);
3212 ACE_NOTSUP_RETURN (0);
3217 ACE_OS::thr_self (ACE_hthread_t &self)
3219 ACE_OS_TRACE ("ACE_OS::thr_self");
3220 #if defined (ACE_HAS_THREADS)
3221 # if defined (ACE_HAS_PTHREADS)
3222 // Note, don't use "::" here since the following call is often a macro.
3223 self = pthread_self ();
3224 # elif defined (ACE_HAS_THREAD_SELF)
3225 self = ::thread_self ();
3226 # elif defined (ACE_HAS_STHREADS)
3227 self = ::thr_self ();
3228 # elif defined (ACE_HAS_WTHREADS)
3229 self = ::GetCurrentThread ();
3230 # elif defined (ACE_HAS_VXTHREADS)
3231 self = ::taskIdSelf ();
3232 # endif /* ACE_HAS_STHREADS */
3234 self = 1; // Might as well make it the main thread ;-)
3235 #endif /* ACE_HAS_THREADS */
3239 ACE_OS::thr_setcancelstate (int new_state, int *old_state)
3241 ACE_OS_TRACE ("ACE_OS::thr_setcancelstate");
3242 #if defined (ACE_HAS_THREADS)
3243 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
3245 int local_new, local_old;
3248 case THR_CANCEL_ENABLE:
3249 local_new = PTHREAD_CANCEL_ENABLE;
3251 case THR_CANCEL_DISABLE:
3252 local_new = PTHREAD_CANCEL_DISABLE;
3258 ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_setcancelstate (local_new,
3266 case PTHREAD_CANCEL_ENABLE:
3267 *old_state = THR_CANCEL_ENABLE;
3269 case PTHREAD_CANCEL_DISABLE:
3270 *old_state = THR_CANCEL_DISABLE;
3274 # elif defined (ACE_HAS_STHREADS)
3275 ACE_UNUSED_ARG (new_state);
3276 ACE_UNUSED_ARG (old_state);
3277 ACE_NOTSUP_RETURN (-1);
3278 # elif defined (ACE_HAS_WTHREADS)
3279 ACE_UNUSED_ARG (new_state);
3280 ACE_UNUSED_ARG (old_state);
3281 ACE_NOTSUP_RETURN (-1);
3282 # else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
3283 ACE_UNUSED_ARG (new_state);
3284 ACE_UNUSED_ARG (old_state);
3285 ACE_NOTSUP_RETURN (-1);
3286 # endif /* ACE_HAS_PTHREADS */
3288 ACE_UNUSED_ARG (new_state);
3289 ACE_UNUSED_ARG (old_state);
3290 ACE_NOTSUP_RETURN (-1);
3291 #endif /* ACE_HAS_THREADS */
3295 ACE_OS::thr_setcanceltype (int new_type, int *old_type)
3297 ACE_OS_TRACE ("ACE_OS::thr_setcanceltype");
3298 #if defined (ACE_HAS_THREADS)
3299 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
3301 int local_new, local_old;
3304 case THR_CANCEL_DEFERRED:
3305 local_new = PTHREAD_CANCEL_DEFERRED;
3307 case THR_CANCEL_ASYNCHRONOUS:
3308 local_new = PTHREAD_CANCEL_ASYNCHRONOUS;
3314 ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_setcanceltype (local_new,
3322 case PTHREAD_CANCEL_DEFERRED:
3323 *old_type = THR_CANCEL_DEFERRED;
3325 case PTHREAD_CANCEL_ASYNCHRONOUS:
3326 *old_type = THR_CANCEL_ASYNCHRONOUS;
3330 # else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
3331 ACE_UNUSED_ARG (new_type);
3332 ACE_UNUSED_ARG (old_type);
3333 ACE_NOTSUP_RETURN (-1);
3334 # endif /* ACE_HAS_PTHREADS */
3336 ACE_UNUSED_ARG (new_type);
3337 ACE_UNUSED_ARG (old_type);
3338 ACE_NOTSUP_RETURN (-1);
3339 #endif /* ACE_HAS_THREADS */
3343 ACE_OS::thr_setconcurrency (int hint)
3345 ACE_OS_TRACE ("ACE_OS::thr_setconcurrency");
3346 #if defined (ACE_HAS_THREADS)
3347 # if defined (ACE_HAS_STHREADS)
3349 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setconcurrency (hint),
3352 # elif defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_PTHREAD_SETCONCURRENCY)
3354 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setconcurrency (hint),
3358 ACE_UNUSED_ARG (hint);
3359 ACE_NOTSUP_RETURN (-1);
3360 # endif /* ACE_HAS_STHREADS */
3362 ACE_UNUSED_ARG (hint);
3363 ACE_NOTSUP_RETURN (-1);
3364 #endif /* ACE_HAS_THREADS */
3368 ACE_OS::thr_setprio (ACE_hthread_t ht_id, int priority, int policy)
3370 ACE_OS_TRACE ("ACE_OS::thr_setprio");
3371 ACE_UNUSED_ARG (policy);
3372 #if defined (ACE_HAS_THREADS)
3373 # if (defined (ACE_HAS_PTHREADS) && \
3374 (!defined (ACE_LACKS_SETSCHED) || defined (ACE_HAS_PTHREAD_SCHEDPARAM)))
3377 struct sched_param param;
3378 ACE_OS::memset ((void *) ¶m, 0, sizeof param);
3380 // If <policy> is -1, we don't want to use it for
3381 // pthread_setschedparam(). Instead, obtain policy from
3382 // pthread_getschedparam().
3385 ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_getschedparam (ht_id, &policy, ¶m),
3392 param.sched_priority = priority;
3394 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setschedparam (ht_id,
3399 # elif defined (ACE_HAS_STHREADS)
3401 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setprio (ht_id, priority),
3404 # elif defined (ACE_HAS_WTHREADS)
3406 # if defined (ACE_HAS_WINCE) && !defined (ACE_LACKS_CE_THREAD_PRIORITY)
3407 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CeSetThreadPriority (ht_id, priority),
3411 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::SetThreadPriority (ht_id, priority),
3414 # endif /* defined (ACE_HAS_WINCE) && !defined (ACE_LACKS_CE_THREAD_PRIORITY) */
3416 # elif defined (ACE_HAS_VXTHREADS)
3417 ACE_OSCALL_RETURN (::taskPrioritySet (ht_id, priority), int, -1);
3419 // For example, platforms that support Pthreads but LACK_SETSCHED.
3420 ACE_UNUSED_ARG (ht_id);
3421 ACE_UNUSED_ARG (priority);
3422 ACE_NOTSUP_RETURN (-1);
3423 # endif /* ACE_HAS_STHREADS */
3425 ACE_UNUSED_ARG (ht_id);
3426 ACE_UNUSED_ARG (priority);
3427 ACE_NOTSUP_RETURN (-1);
3428 #endif /* ACE_HAS_THREADS */
3432 ACE_OS::thr_sigsetmask (int how,
3433 const sigset_t *nsm,
3436 ACE_OS_TRACE ("ACE_OS::thr_sigsetmask");
3437 #if defined (ACE_HAS_THREADS)
3438 # if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
3439 // DCE threads and Solaris 2.4 have no such function.
3440 ACE_UNUSED_ARG (osm);
3441 ACE_UNUSED_ARG (nsm);
3442 ACE_UNUSED_ARG (how);
3444 ACE_NOTSUP_RETURN (-1);
3445 # elif defined (ACE_HAS_SIGTHREADMASK)
3447 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigthreadmask (how, nsm, osm),
3449 # elif defined (ACE_HAS_STHREADS)
3451 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_sigsetmask (how, nsm, osm),
3454 # elif defined (ACE_HAS_PTHREADS)
3455 # if !defined (ACE_LACKS_PTHREAD_SIGMASK)
3457 //FUZZ: disable check_for_lack_ACE_OS
3458 # if defined (ACE_HAS_NONCONST_PTHREAD_SIGMASK)
3459 sigset_t *ncnsm = const_cast<sigset_t *>(nsm);
3460 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, ncnsm, osm),
3465 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm),
3469 # endif /* ACE_HAS_NONCONST__PTHREAD_SIGMASK */
3470 //FUZZ: enable check_for_lack_ACE_OS
3471 # endif /* !ACE_LACKS_PTHREAD_SIGMASK */
3473 # elif defined (ACE_HAS_WTHREADS)
3474 ACE_UNUSED_ARG (osm);
3475 ACE_UNUSED_ARG (nsm);
3476 ACE_UNUSED_ARG (how);
3478 ACE_NOTSUP_RETURN (-1);
3479 # elif defined (ACE_VXWORKS)
3487 old_mask = ::sigsetmask (*nsm);
3488 // create a new mask: the following assumes that sigset_t is 4 bytes,
3489 // which it is on VxWorks 5.2, so bit operations are done simply . . .
3490 ::sigsetmask (how == SIG_BLOCK ? (old_mask |= *nsm) : (old_mask &= ~*nsm));
3496 old_mask = ::sigsetmask (*nsm);
3505 # else /* Should not happen. */
3506 ACE_UNUSED_ARG (how);
3507 ACE_UNUSED_ARG (nsm);
3508 ACE_UNUSED_ARG (osm);
3509 ACE_NOTSUP_RETURN (-1);
3510 # endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
3512 ACE_UNUSED_ARG (how);
3513 ACE_UNUSED_ARG (nsm);
3514 ACE_UNUSED_ARG (osm);
3515 ACE_NOTSUP_RETURN (-1);
3516 #endif /* ACE_HAS_THREADS */
3520 ACE_OS::thr_suspend (ACE_hthread_t target_thread)
3522 ACE_OS_TRACE ("ACE_OS::thr_suspend");
3523 #if defined (ACE_HAS_THREADS)
3524 # if defined (ACE_HAS_STHREADS)
3526 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_suspend (target_thread), result), int, -1);
3527 # elif defined (ACE_HAS_PTHREADS)
3528 # if defined (ACE_HAS_PTHREAD_SUSPEND)
3530 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_suspend (target_thread),
3533 # elif defined (ACE_HAS_PTHREAD_SUSPEND_NP)
3535 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_suspend_np (target_thread),
3539 ACE_UNUSED_ARG (target_thread);
3540 ACE_NOTSUP_RETURN (-1);
3541 # endif /* ACE_HAS_PTHREAD_SUSPEND */
3542 # elif defined (ACE_HAS_WTHREADS)
3543 if (::SuspendThread (target_thread) != ACE_SYSCALL_FAILED)
3546 ACE_FAIL_RETURN (-1);
3548 # elif defined (ACE_HAS_VXTHREADS)
3549 ACE_OSCALL_RETURN (::taskSuspend (target_thread), int, -1);
3550 # endif /* ACE_HAS_STHREADS */
3552 ACE_UNUSED_ARG (target_thread);
3553 ACE_NOTSUP_RETURN (-1);
3554 #endif /* ACE_HAS_THREADS */
3558 ACE_OS::thr_testcancel (void)
3560 ACE_OS_TRACE ("ACE_OS::thr_testcancel");
3561 #if defined (ACE_HAS_THREADS)
3562 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
3563 pthread_testcancel ();
3564 # elif defined (ACE_HAS_STHREADS)
3565 # elif defined (ACE_HAS_WTHREADS)
3566 # elif defined (ACE_HAS_VXTHREADS)
3568 // no-op: can't use ACE_NOTSUP_RETURN because there is no return value
3569 # endif /* ACE_HAS_PTHREADS */
3571 #endif /* ACE_HAS_THREADS */
3575 ACE_OS::thr_yield (void)
3577 ACE_OS_TRACE ("ACE_OS::thr_yield");
3578 #if defined (ACE_HAS_THREADS)
3579 # if defined (ACE_HAS_PTHREADS)
3581 # elif defined (ACE_HAS_STHREADS)
3583 # elif defined (ACE_HAS_WTHREADS)
3585 # elif defined (ACE_HAS_VXTHREADS)
3586 // An argument of 0 to ::taskDelay doesn't appear to yield the
3588 // Now, it does seem to work. The context_switch_time test
3589 // works fine with task_delay set to 0.
3591 # endif /* ACE_HAS_STHREADS */
3594 #endif /* ACE_HAS_THREADS */
3598 ACE_OS::thread_mutex_destroy (ACE_thread_mutex_t *m)
3600 ACE_OS_TRACE ("ACE_OS::thread_mutex_destroy");
3601 #if defined (ACE_HAS_THREADS)
3602 # if defined (ACE_HAS_WTHREADS)
3603 ::DeleteCriticalSection (m);
3606 return ACE_OS::mutex_destroy (m);
3607 # endif /* ACE_HAS_WTHREADS */
3610 ACE_NOTSUP_RETURN (-1);
3612 #endif /* ACE_HAS_THREADS */
3616 ACE_OS::thread_mutex_init (ACE_thread_mutex_t *m,
3619 ACE_mutexattr_t *arg)
3621 // ACE_OS_TRACE ("ACE_OS::thread_mutex_init");
3622 #if defined (ACE_HAS_THREADS)
3623 # if defined (ACE_HAS_WTHREADS)
3624 ACE_UNUSED_ARG (lock_type);
3625 ACE_UNUSED_ARG (name);
3626 ACE_UNUSED_ARG (arg);
3630 ::InitializeCriticalSection (m);
3632 ACE_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3639 # elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS)
3640 // Force the use of USYNC_THREAD!
3641 return ACE_OS::mutex_init (m, USYNC_THREAD, name, arg, 0, lock_type);
3642 # elif defined (ACE_HAS_VXTHREADS)
3643 return mutex_init (m, lock_type, name, arg);
3645 # endif /* ACE_HAS_STHREADS || ACE_HAS_PTHREADS */
3649 ACE_UNUSED_ARG (lock_type);
3650 ACE_UNUSED_ARG (name);
3651 ACE_UNUSED_ARG (arg);
3652 ACE_NOTSUP_RETURN (-1);
3654 #endif /* ACE_HAS_THREADS */
3657 #if defined (ACE_HAS_WCHAR)
3659 ACE_OS::thread_mutex_init (ACE_thread_mutex_t *m,
3661 const wchar_t *name,
3662 ACE_mutexattr_t *arg)
3664 // ACE_OS_TRACE ("ACE_OS::thread_mutex_init");
3665 #if defined (ACE_HAS_THREADS)
3666 # if defined (ACE_HAS_WTHREADS)
3667 ACE_UNUSED_ARG (lock_type);
3668 ACE_UNUSED_ARG (name);
3669 ACE_UNUSED_ARG (arg);
3673 ::InitializeCriticalSection (m);
3675 ACE_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3682 # elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS)
3683 // Force the use of USYNC_THREAD!
3684 return ACE_OS::mutex_init (m, USYNC_THREAD, name, arg, 0, lock_type);
3685 # elif defined (ACE_HAS_VXTHREADS)
3686 return mutex_init (m, lock_type, name, arg);
3687 # endif /* ACE_HAS_STHREADS || ACE_HAS_PTHREADS */
3690 ACE_UNUSED_ARG (lock_type);
3691 ACE_UNUSED_ARG (name);
3692 ACE_UNUSED_ARG (arg);
3693 ACE_NOTSUP_RETURN (-1);
3695 #endif /* ACE_HAS_THREADS */
3697 #endif /* ACE_HAS_WCHAR */
3700 ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m)
3702 // ACE_OS_TRACE ("ACE_OS::thread_mutex_lock");
3703 #if defined (ACE_HAS_THREADS)
3704 # if defined (ACE_HAS_WTHREADS)
3705 ::EnterCriticalSection (m);
3708 return ACE_OS::mutex_lock (m);
3709 # endif /* ACE_HAS_WTHREADS */
3712 ACE_NOTSUP_RETURN (-1);
3713 #endif /* ACE_HAS_THREADS */
3717 ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m,
3718 const ACE_Time_Value &timeout)
3720 // ACE_OS_TRACE ("ACE_OS::thread_mutex_lock");
3722 // For all platforms, except MS Windows, this method is equivalent
3723 // to calling ACE_OS::mutex_lock() since ACE_thread_mutex_t and
3724 // ACE_mutex_t are the same type. However, those typedefs evaluate
3725 // to different types on MS Windows. The "thread mutex"
3726 // implementation in ACE for MS Windows cannot readily support
3727 // timeouts due to a lack of timeout features for this type of MS
3728 // Windows synchronization mechanism.
3730 #if defined (ACE_HAS_THREADS) && !defined (ACE_HAS_WTHREADS)
3731 return ACE_OS::mutex_lock (m, timeout);
3734 ACE_UNUSED_ARG (timeout);
3735 ACE_NOTSUP_RETURN (-1);
3736 #endif /* ACE_HAS_THREADS */
3740 ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m,
3741 const ACE_Time_Value *timeout)
3744 ? ACE_OS::thread_mutex_lock (m)
3745 : ACE_OS::thread_mutex_lock (m, *timeout);
3749 ACE_OS::thread_mutex_trylock (ACE_thread_mutex_t *m)
3751 ACE_OS_TRACE ("ACE_OS::thread_mutex_trylock");
3753 #if defined (ACE_HAS_THREADS)
3754 # if defined (ACE_HAS_WTHREADS)
3755 # if defined (ACE_HAS_WIN32_TRYLOCK)
3756 BOOL result = ::TryEnterCriticalSection (m);
3768 ACE_NOTSUP_RETURN (-1);
3769 # endif /* ACE_HAS_WIN32_TRYLOCK */
3770 # elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS) || defined (ACE_VXWORKS)
3771 return ACE_OS::mutex_trylock (m);
3772 #endif /* Threads variety case */
3776 ACE_NOTSUP_RETURN (-1);
3777 #endif /* ACE_HAS_THREADS */
3781 ACE_OS::thread_mutex_unlock (ACE_thread_mutex_t *m)
3783 ACE_OS_TRACE ("ACE_OS::thread_mutex_unlock");
3784 #if defined (ACE_HAS_THREADS)
3785 # if defined (ACE_HAS_WTHREADS)
3786 ::LeaveCriticalSection (m);
3789 return ACE_OS::mutex_unlock (m);
3790 # endif /* ACE_HAS_WTHREADS */
3793 ACE_NOTSUP_RETURN (-1);
3794 #endif /* ACE_HAS_THREADS */
3797 /*****************************************************************************/
3799 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
3803 ACE_OS_Thread_Mutex_Guard::acquire (void)
3805 return owner_ = ACE_OS::thread_mutex_lock (&lock_);
3810 ACE_OS_Thread_Mutex_Guard::release (void)
3817 return ACE_OS::thread_mutex_unlock (&lock_);
3822 ACE_OS_Thread_Mutex_Guard::ACE_OS_Thread_Mutex_Guard (ACE_thread_mutex_t &m)
3823 : lock_ (m), owner_ (-1)
3825 if (!ACE_OS_Object_Manager::starting_up ())
3830 ACE_OS_Thread_Mutex_Guard::~ACE_OS_Thread_Mutex_Guard ()
3835 /*****************************************************************************/
3839 ACE_OS_Recursive_Thread_Mutex_Guard::acquire (void)
3841 return owner_ = ACE_OS::recursive_mutex_lock (&lock_);
3846 ACE_OS_Recursive_Thread_Mutex_Guard::release (void)
3853 return ACE_OS::recursive_mutex_unlock (&lock_);
3858 ACE_OS_Recursive_Thread_Mutex_Guard::ACE_OS_Recursive_Thread_Mutex_Guard (
3859 ACE_recursive_thread_mutex_t &m)
3863 if (!ACE_OS_Object_Manager::starting_up ())
3868 ACE_OS_Recursive_Thread_Mutex_Guard::~ACE_OS_Recursive_Thread_Mutex_Guard ()
3873 #endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */
3876 /*****************************************************************************/
3879 ACE_Thread_ID::ACE_Thread_ID (ACE_thread_t thread_id,
3880 ACE_hthread_t thread_handle)
3881 : thread_id_ (thread_id),
3882 thread_handle_ (thread_handle)
3887 ACE_Thread_ID::ACE_Thread_ID (const ACE_Thread_ID &id)
3888 : thread_id_ (id.thread_id_),
3889 thread_handle_ (id.thread_handle_)
3895 ACE_Thread_ID::operator= (const ACE_Thread_ID &id)
3899 this->thread_id_ = id.thread_id_;
3900 this->thread_handle_ = id.thread_handle_;
3906 ACE_Thread_ID::ACE_Thread_ID (void)
3907 : thread_id_ (ACE_OS::thr_self ())
3909 ACE_OS::thr_self (thread_handle_);
3914 ACE_Thread_ID::id (void) const
3916 return this->thread_id_;
3920 ACE_Thread_ID::id (ACE_thread_t thread_id)
3922 this->thread_id_ = thread_id;
3925 ACE_INLINE ACE_hthread_t
3926 ACE_Thread_ID::handle (void) const
3928 return this->thread_handle_;
3932 ACE_Thread_ID::handle (ACE_hthread_t thread_handle)
3934 this->thread_handle_ = thread_handle;
3938 ACE_Thread_ID::operator== (const ACE_Thread_ID &rhs) const
3941 ACE_OS::thr_cmp (this->thread_handle_, rhs.thread_handle_)
3942 && ACE_OS::thr_equal (this->thread_id_, rhs.thread_id_);
3946 ACE_Thread_ID::operator!= (const ACE_Thread_ID &rhs) const
3948 return !(*this == rhs);
3951 #if !defined (ACE_WIN32)
3954 ACE_event_t::ACE_event_t (void) :
3960 #endif /* !ACE_WIN32 */
3962 ACE_END_VERSIONED_NAMESPACE_DECL