3 // $Id: OS_NS_Thread.inl 80826 2008-03-04 14:51:23Z wotte $
5 #include "ace/OS_NS_macros.h"
6 // for timespec_t, perhaps move it to os_time.h
7 #include "ace/Time_Value.h"
8 #include "ace/OS_NS_sys_mman.h"
9 #include "ace/OS_NS_sys_time.h"
10 #include "ace/OS_NS_string.h"
11 #include "ace/OS_NS_unistd.h"
12 #include "ace/OS_NS_stdio.h"
13 #include "ace/OS_NS_errno.h"
15 #if defined (ACE_USES_FIFO_SEM)
16 # include "ace/OS_NS_sys_stat.h"
17 # include "ace/OS_NS_sys_select.h"
18 # include "ace/OS_NS_fcntl.h"
19 # include "ace/Handle_Set.h"
20 # endif /* ACE_USES_FIFO_SEM */
22 #if defined (ACE_HAS_PRIOCNTL)
23 # include /**/ <sys/priocntl.h>
24 #endif /* ACE_HAS_PRIOCNTL */
26 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
28 /*****************************************************************************/
30 #if defined (ACE_LACKS_COND_T) && defined (ACE_HAS_THREADS)
32 ACE_cond_t::waiters (void) const
34 return this->waiters_;
36 #endif /* ACE_LACKS_COND_T && ACE_HAS_THREADS */
38 /*****************************************************************************/
40 #if defined (ACE_HAS_TSS_EMULATION)
42 # if !defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
45 ACE_TSS_Emulation::tss_base ()
47 # if defined (ACE_HAS_VXTHREADS)
48 int &spare = taskIdCurrent->ACE_VXWORKS_SPARE;
49 return reinterpret_cast <void **&> (spare);
52 ACE_NOTSUP_RETURN (0);
53 # endif /* ACE_HAS_VXTHREADS */
55 # endif /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
58 ACE_TSS_Emulation::ACE_TSS_DESTRUCTOR
59 ACE_TSS_Emulation::tss_destructor (const ACE_thread_key_t key)
61 ACE_KEY_INDEX (key_index, key);
62 return tss_destructor_ [key_index];
67 ACE_TSS_Emulation::tss_destructor (const ACE_thread_key_t key,
68 ACE_TSS_DESTRUCTOR destructor)
70 ACE_KEY_INDEX (key_index, key);
71 tss_destructor_ [key_index] = destructor;
76 ACE_TSS_Emulation::ts_object (const ACE_thread_key_t key)
78 ACE_KEY_INDEX (key_index, 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 (0 == taskIdCurrent->ACE_VXWORKS_SPARE)
86 taskIdCurrent->ACE_VXWORKS_SPARE =
87 reinterpret_cast<int> (new void *[ACE_TSS_THREAD_KEYS_MAX]);
89 // Zero the entire TSS array. Do it manually instead of using
90 // memset, for optimum speed. Though, memset may be faster :-)
92 reinterpret_cast<void **> (taskIdCurrent->ACE_VXWORKS_SPARE);
93 for (u_int i = 0; i < ACE_TSS_THREAD_KEYS_MAX; ++i, ++tss_base_p)
98 # endif /* ACE_HAS_VXTHREADS */
100 return tss_base ()[key_index];
103 #endif /* ACE_HAS_TSS_EMULATION */
105 /*****************************************************************************/
108 ACE_OS::thr_equal (ACE_thread_t t1, ACE_thread_t t2)
110 #if defined (ACE_HAS_PTHREADS)
111 # if defined (pthread_equal)
112 // If it's a macro we can't say "pthread_equal"...
113 return pthread_equal (t1, t2);
115 return pthread_equal (t1, t2);
116 # endif /* pthread_equal */
117 #else /* For both STHREADS and WTHREADS... */
118 // Hum, Do we need to treat WTHREAD differently?
119 // levine 13 oct 98 % I don't think so, ACE_thread_t is a DWORD.
121 #endif /* ACE_HAS_PTHREADS */
124 #if !defined (ACE_LACKS_COND_T)
125 // NOTE: The ACE_OS::cond_* functions for Unix platforms are defined
126 // here because the ACE_OS::sema_* functions below need them.
127 // However, ACE_WIN32 and VXWORKS define the ACE_OS::cond_* functions
128 // using the ACE_OS::sema_* functions. So, they are defined in OS.cpp.
131 ACE_OS::condattr_destroy (ACE_condattr_t &attributes)
133 #if defined (ACE_HAS_THREADS)
134 # if defined (ACE_HAS_PTHREADS)
136 pthread_condattr_destroy (&attributes);
138 # elif defined (ACE_HAS_STHREADS)
141 # endif /* ACE_HAS_PTHREADS vs. ACE_HAS_STHREADS */
144 ACE_UNUSED_ARG (attributes);
146 # endif /* ACE_HAS_THREADS */
150 ACE_OS::condattr_init (ACE_condattr_t &attributes,
153 ACE_UNUSED_ARG (type);
154 # if defined (ACE_HAS_THREADS)
155 # if defined (ACE_HAS_PTHREADS)
158 # if defined (ACE_VXWORKS) && (ACE_VXWORKS >= 0x600) && (ACE_VXWORKS <= 0x620)
159 /* Tests show that VxWorks 6.x pthread lib does not only
160 * require zeroing of mutex/condition objects to function correctly
161 * but also of the attribute objects.
163 ACE_OS::memset (&attributes, 0, sizeof (attributes));
166 ACE_ADAPT_RETVAL (pthread_condattr_init (&attributes), result) == 0
167 # if defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)
168 && ACE_ADAPT_RETVAL (pthread_condattr_setpshared (&attributes, type),
170 # endif /* _POSIX_THREAD_PROCESS_SHARED && ! ACE_LACKS_CONDATTR_PSHARED */
174 result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
177 # elif defined (ACE_HAS_STHREADS)
178 attributes.type = type;
183 ACE_UNUSED_ARG (attributes);
184 ACE_UNUSED_ARG (type);
185 ACE_NOTSUP_RETURN (-1);
187 # endif /* ACE_HAS_PTHREADS vs. ACE_HAS_STHREADS */
190 ACE_UNUSED_ARG (attributes);
191 ACE_UNUSED_ARG (type);
192 ACE_NOTSUP_RETURN (-1);
193 # endif /* ACE_HAS_THREADS */
197 ACE_OS::cond_broadcast (ACE_cond_t *cv)
199 ACE_OS_TRACE ("ACE_OS::cond_broadcast");
200 # if defined (ACE_HAS_THREADS)
201 # if defined (ACE_HAS_PTHREADS)
203 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_broadcast (cv),
206 # elif defined (ACE_HAS_STHREADS)
208 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_broadcast (cv),
211 # endif /* ACE_HAS_STHREADS */
214 ACE_NOTSUP_RETURN (-1);
215 # endif /* ACE_HAS_THREADS */
219 ACE_OS::cond_destroy (ACE_cond_t *cv)
221 ACE_OS_TRACE ("ACE_OS::cond_destroy");
222 # if defined (ACE_HAS_THREADS)
223 # if defined (ACE_HAS_PTHREADS)
225 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_destroy (cv), result), int, -1);
226 # elif defined (ACE_HAS_STHREADS)
228 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_destroy (cv), result), int, -1);
229 # endif /* ACE_HAS_STHREADS */
232 ACE_NOTSUP_RETURN (-1);
233 # endif /* ACE_HAS_THREADS */
237 ACE_OS::cond_init (ACE_cond_t *cv,
238 ACE_condattr_t &attributes,
242 // ACE_OS_TRACE ("ACE_OS::cond_init");
243 ACE_UNUSED_ARG (name);
244 ACE_UNUSED_ARG (arg);
245 # if defined (ACE_HAS_THREADS)
246 # if defined (ACE_HAS_PTHREADS)
249 # if defined (ACE_VXWORKS) && (ACE_VXWORKS >= 0x600) && (ACE_VXWORKS <= 0x620)
250 /* VxWorks 6.x API reference states:
251 * If the memory for the condition variable object has been allocated
252 * dynamically, it is a good policy to always zero out the
253 * block of memory so as to avoid spurious EBUSY return code
254 * when calling this routine.
256 ACE_OS::memset (cv, 0, sizeof (*cv));
259 if (ACE_ADAPT_RETVAL (pthread_cond_init (cv, &attributes), result) == 0)
262 result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
265 # elif defined (ACE_HAS_STHREADS)
267 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_init (cv,
272 # endif /* ACE_HAS_PTHREADS vs. ACE_HAS_STHREADS */
275 ACE_UNUSED_ARG (attributes);
276 ACE_UNUSED_ARG (name);
277 ACE_UNUSED_ARG (arg);
278 ACE_NOTSUP_RETURN (-1);
279 # endif /* ACE_HAS_THREADS */
282 #if defined (ACE_HAS_WCHAR)
284 ACE_OS::cond_init (ACE_cond_t *cv,
285 ACE_condattr_t &attributes,
289 return ACE_OS::cond_init (cv, attributes, ACE_Wide_To_Ascii (name).char_rep (), arg);
291 #endif /* ACE_HAS_WCHAR */
293 #if defined (ACE_HAS_WCHAR)
295 ACE_OS::cond_init (ACE_cond_t *cv, short type, const wchar_t *name, void *arg)
297 return ACE_OS::cond_init (cv, type, ACE_Wide_To_Ascii (name).char_rep (), arg);
299 #endif /* ACE_HAS_WCHAR */
302 ACE_OS::cond_signal (ACE_cond_t *cv)
304 ACE_OS_TRACE ("ACE_OS::cond_signal");
305 # if defined (ACE_HAS_THREADS)
306 # if defined (ACE_HAS_PTHREADS)
308 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_signal (cv), result),
310 # elif defined (ACE_HAS_STHREADS)
312 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_signal (cv), result), int, -1);
313 # endif /* ACE_HAS_STHREADS */
316 ACE_NOTSUP_RETURN (-1);
317 # endif /* ACE_HAS_THREADS */
321 ACE_OS::cond_wait (ACE_cond_t *cv,
322 ACE_mutex_t *external_mutex)
324 ACE_OS_TRACE ("ACE_OS::cond_wait");
325 # if defined (ACE_HAS_THREADS)
326 # if defined (ACE_HAS_PTHREADS)
328 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_wait (cv, external_mutex), result),
330 # elif defined (ACE_HAS_STHREADS)
332 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_wait (cv, external_mutex), result),
334 # endif /* ACE_HAS_PTHREADS */
337 ACE_UNUSED_ARG (external_mutex);
338 ACE_NOTSUP_RETURN (-1);
339 # endif /* ACE_HAS_THREADS */
343 ACE_OS::cond_timedwait (ACE_cond_t *cv,
344 ACE_mutex_t *external_mutex,
345 ACE_Time_Value *timeout)
347 ACE_OS_TRACE ("ACE_OS::cond_timedwait");
348 # if defined (ACE_HAS_THREADS)
353 ts = *timeout; // Calls ACE_Time_Value::operator timespec_t().
355 # if defined (ACE_HAS_PTHREADS)
357 ACE_OSCALL (ACE_ADAPT_RETVAL (timeout == 0
358 ? pthread_cond_wait (cv, external_mutex)
359 : pthread_cond_timedwait (cv, external_mutex,
360 (ACE_TIMESPEC_PTR) &ts),
363 // We need to adjust this to make the POSIX and Solaris return
364 // values consistent. EAGAIN is from Pthreads DRAFT4 (HP-UX 10.20 and down)
366 (errno == ETIMEDOUT || errno == EAGAIN))
369 # elif defined (ACE_HAS_STHREADS)
370 ACE_OSCALL (ACE_ADAPT_RETVAL (timeout == 0
371 ? ::cond_wait (cv, external_mutex)
372 : ::cond_timedwait (cv,
377 # endif /* ACE_HAS_STHREADS */
379 timeout->set (ts); // Update the time value before returning.
384 ACE_UNUSED_ARG (external_mutex);
385 ACE_UNUSED_ARG (timeout);
386 ACE_NOTSUP_RETURN (-1);
387 # endif /* ACE_HAS_THREADS */
389 #endif /* !ACE_LACKS_COND_T */
392 ACE_OS::mutex_lock (ACE_mutex_t *m,
393 const ACE_Time_Value *timeout)
395 return timeout == 0 ? ACE_OS::mutex_lock (m) : ACE_OS::mutex_lock (m, *timeout);
398 #if defined (ACE_HAS_WCHAR)
400 ACE_OS::event_init (ACE_event_t *event,
406 LPSECURITY_ATTRIBUTES sa)
408 #if defined (ACE_WIN32)
409 ACE_UNUSED_ARG (type);
410 ACE_UNUSED_ARG (arg);
411 SECURITY_ATTRIBUTES sa_buffer;
412 SECURITY_DESCRIPTOR sd_buffer;
413 *event = ::CreateEventW (ACE_OS::default_win32_security_attributes_r
414 (sa, &sa_buffer, &sd_buffer),
419 ACE_FAIL_RETURN (-1);
422 #else /* ACE_WIN32 */
423 return ACE_OS::event_init (event,
427 ACE_Wide_To_Ascii (name).char_rep (),
430 #endif /* ACE_WIN32 */
432 #endif /* ACE_HAS_WCHAR */
435 ACE_OS::priority_control (ACE_idtype_t idtype, ACE_id_t identifier, int cmd, void *arg)
437 ACE_OS_TRACE ("ACE_OS::priority_control");
438 #if defined (ACE_HAS_PRIOCNTL)
439 ACE_OSCALL_RETURN (priocntl (idtype, identifier, cmd, static_cast<caddr_t> (arg)),
441 #else /* ! ACE_HAS_PRIOCNTL*/
442 ACE_UNUSED_ARG (idtype);
443 ACE_UNUSED_ARG (identifier);
444 ACE_UNUSED_ARG (cmd);
445 ACE_UNUSED_ARG (arg);
446 ACE_NOTSUP_RETURN (-1);
447 #endif /* ! ACE_HAS_PRIOCNTL*/
450 // This method is used to prepare the recursive mutex for releasing
451 // when waiting on a condition variable. If the platform doesn't have
452 // native recursive mutex and condition variable support, then ACE needs
453 // to save the recursion state around the wait and also ensure that the
454 // wait and lock release are atomic. recursive_mutex_cond_relock()
455 // is the inverse of this method.
457 ACE_OS::recursive_mutex_cond_unlock (ACE_recursive_thread_mutex_t *m,
458 ACE_recursive_mutex_state &state)
460 #if defined (ACE_HAS_THREADS)
461 ACE_OS_TRACE ("ACE_OS::recursive_mutex_cond_unlock");
462 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
463 // Windows need special handling since it has recursive mutexes, but
464 // does not integrate them into a condition variable.
465 # if defined (ACE_WIN32)
466 // For Windows, the OS takes care of the mutex and its recursion. We just
467 // need to release the lock one fewer times than this thread has acquired
468 // it. Remember how many times, and reacquire it that many more times when
469 // the condition is signaled.
471 // For WinCE, the situation is a bit trickier. CE doesn't have
472 // RecursionCount, and LockCount has changed semantics over time.
473 // In CE 3 (and maybe 4?) LockCount is not an indicator of recursion;
474 // instead, see when it's unlocked by watching the OwnerThread, which will
475 // change to something other than the current thread when it's been
476 // unlocked "enough" times. Note that checking for 0 (unlocked) is not
477 // sufficient. Another thread may acquire the lock between our unlock and
478 // checking the OwnerThread. So grab our thread ID value first, then
479 // compare to it in the loop condition. NOTE - the problem with this
480 // scheme is that we really want to unlock the mutex one _less_ times than
481 // required to release it for another thread to acquire. With CE 5 we
482 // can do this by watching LockCount alone. I _think_ it can be done by
483 // watching LockCount on CE 4 as well (though its meaning is different),
484 // but I'm leary of changing this code since a user reported success
487 // We're using undocumented fields in the CRITICAL_SECTION structure
488 // and they've been known to change across Windows variants and versions./
489 // So be careful if you need to change these - there may be other
490 // Windows variants that depend on existing values and limits.
491 # if defined (ACE_HAS_WINCE) && (UNDER_CE < 500)
492 ACE_thread_t me = ACE_OS::thr_self ();
493 # endif /* ACE_HAS_WINCE && CE 4 or earlier */
495 state.relock_count_ = 0;
497 # if !defined (ACE_HAS_WINCE)
498 m->LockCount > 0 && m->RecursionCount > 1
500 // WinCE doesn't have RecursionCount and the LockCount semantic
501 // has changed between versions; pre-Mobile 5 the LockCount
502 // was 0-indexed, and Mobile 5 has it 1-indexed.
503 # if (UNDER_CE < 500)
504 m->LockCount > 0 && m->OwnerThread == (HANDLE)me
507 # endif /* UNDER_CE < 500 */
508 # endif /* ACE_HAS_WINCE */
511 // This may fail if the current thread doesn't own the mutex. If it
512 // does fail, it'll be on the first try, so don't worry about resetting
514 if (ACE_OS::recursive_mutex_unlock (m) == -1)
516 ++state.relock_count_;
518 # else /* not ACE_WIN32 */
519 // prevent warnings for unused variables
520 ACE_UNUSED_ARG (state);
522 # endif /* ACE_WIN32 */
524 # else /* ACE_HAS_RECURSIVE_MUTEXES */
525 // For platforms without recursive mutexes, we obtain the nesting mutex
526 // to gain control over the mutex internals. Then set the internals to say
527 // the mutex is available. If there are waiters, signal the condition
528 // to notify them (this is mostly like the recursive_mutex_unlock() method).
529 // Then, return with the nesting mutex still held. The condition wait
530 // will release it atomically, allowing mutex waiters to continue.
531 // Note that this arrangement relies on the fact that on return from
532 // the condition wait, this thread will again own the nesting mutex
533 // and can either set the mutex internals directly or get in line for
534 // the mutex... this part is handled in recursive_mutex_cond_relock().
535 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
538 # if !defined (ACE_NDEBUG)
539 if (m->nesting_level_ == 0
540 || ACE_OS::thr_equal (ACE_OS::thr_self (), m->owner_id_) == 0)
542 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
546 # endif /* ACE_NDEBUG */
548 // To make error recovery a bit easier, signal the condition now. Any
549 // waiter won't regain control until the mutex is released, which won't
550 // be until the caller returns and does the wait on the condition.
551 if (ACE_OS::cond_signal (&m->lock_available_) == -1)
553 // Save/restore errno.
554 ACE_Errno_Guard error (errno);
555 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
559 // Ok, the nesting_mutex_ lock is still held, the condition has been
560 // signaled... reset the nesting info and return _WITH_ the lock
561 // held. The lock will be released when the condition waits, in the
563 state.nesting_level_ = m->nesting_level_;
564 state.owner_id_ = m->owner_id_;
565 m->nesting_level_ = 0;
566 m->owner_id_ = ACE_OS::NULL_thread;
568 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
571 ACE_UNUSED_ARG (state);
572 ACE_NOTSUP_RETURN (-1);
573 #endif /* ACE_HAS_THREADS */
577 // This method is called after waiting on a condition variable when a
578 // recursive mutex must be reacquired. If the platform doesn't natively
579 // integrate recursive mutexes and condition variables, it's taken care
580 // of here (inverse of ACE_OS::recursive_mutex_cond_unlock).
582 ACE_OS::recursive_mutex_cond_relock (ACE_recursive_thread_mutex_t *m,
583 ACE_recursive_mutex_state &state)
585 #if defined (ACE_HAS_THREADS)
586 ACE_OS_TRACE ("ACE_OS::recursive_mutex_cond_relock");
587 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
588 // Windows need special handling since it has recursive mutexes, but
589 // does not integrate them into a condition variable.
590 // On entry, the OS has already reacquired the lock for us. Just
591 // reacquire it the proper number of times so the recursion is the same as
592 // before waiting on the condition.
593 # if defined (ACE_WIN32)
594 while (state.relock_count_ > 0)
596 ACE_OS::recursive_mutex_lock (m);
597 --state.relock_count_;
600 # else /* not ACE_WIN32 */
601 // prevent warnings for unused variables
602 ACE_UNUSED_ARG (state);
605 # endif /* ACE_WIN32 */
607 // Without recursive mutex support, it's somewhat trickier. On entry,
608 // the current thread holds the nesting_mutex_, but another thread may
609 // still be holding the ACE_recursive_mutex_t. If so, mimic the code
610 // in ACE_OS::recursive_mutex_lock that waits to acquire the mutex.
611 // After acquiring it, restore the nesting counts and release the
612 // nesting mutex. This will restore the conditions to what they were
613 // before calling ACE_OS::recursive_mutex_cond_unlock().
614 while (m->nesting_level_ > 0)
615 ACE_OS::cond_wait (&m->lock_available_, &m->nesting_mutex_);
617 // At this point, we still have nesting_mutex_ and the mutex is free.
618 m->nesting_level_ = state.nesting_level_;
619 m->owner_id_ = state.owner_id_;
620 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
622 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
625 ACE_UNUSED_ARG (state);
627 #endif /* ACE_HAS_THREADS */
631 ACE_OS::recursive_mutex_destroy (ACE_recursive_thread_mutex_t *m)
633 #if defined (ACE_HAS_THREADS)
634 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
635 return ACE_OS::thread_mutex_destroy (m);
637 if (ACE_OS::thread_mutex_destroy (&m->nesting_mutex_) == -1)
639 else if (ACE_OS::cond_destroy (&m->lock_available_) == -1)
643 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
646 ACE_NOTSUP_RETURN (-1);
647 #endif /* ACE_HAS_THREADS */
651 ACE_OS::recursive_mutex_init (ACE_recursive_thread_mutex_t *m,
652 const ACE_TCHAR *name,
653 ACE_mutexattr_t *arg,
654 LPSECURITY_ATTRIBUTES sa)
657 #if defined (ACE_HAS_THREADS)
658 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
659 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
660 return ACE_OS::thread_mutex_init (m, PTHREAD_MUTEX_RECURSIVE, name, arg);
662 return ACE_OS::thread_mutex_init (m, 0, name, arg);
663 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
665 if (ACE_OS::thread_mutex_init (&m->nesting_mutex_, 0, name, arg) == -1)
667 else if (ACE_OS::cond_init (&m->lock_available_,
668 (short) USYNC_THREAD,
674 m->nesting_level_ = 0;
675 m->owner_id_ = ACE_OS::NULL_thread;
678 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
681 ACE_UNUSED_ARG (name);
682 ACE_UNUSED_ARG (arg);
683 ACE_NOTSUP_RETURN (-1);
684 #endif /* ACE_HAS_THREADS */
688 ACE_OS::recursive_mutex_lock (ACE_recursive_thread_mutex_t *m)
690 #if defined (ACE_HAS_THREADS)
691 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
692 return ACE_OS::thread_mutex_lock (m);
694 ACE_thread_t const t_id = ACE_OS::thr_self ();
697 // Acquire the guard.
698 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
702 // If there's no contention, just grab the lock immediately
703 // (since this is the common case we'll optimize for it).
704 if (m->nesting_level_ == 0)
706 // If we already own the lock, then increment the nesting level
708 else if (ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
710 // Wait until the nesting level has dropped to zero, at
711 // which point we can acquire the lock.
712 while (m->nesting_level_ > 0)
713 ACE_OS::cond_wait (&m->lock_available_,
716 // At this point the nesting_mutex_ is held...
720 // At this point, we can safely increment the nesting_level_ no
721 // matter how we got here!
726 // Save/restore errno.
727 ACE_Errno_Guard error (errno);
728 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
731 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
734 ACE_NOTSUP_RETURN (-1);
735 #endif /* ACE_HAS_THREADS */
739 ACE_OS::recursive_mutex_lock (ACE_recursive_thread_mutex_t *m,
740 const ACE_Time_Value &timeout)
742 #if defined (ACE_HAS_THREADS)
743 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
744 return ACE_OS::thread_mutex_lock (m, timeout);
746 ACE_thread_t t_id = ACE_OS::thr_self ();
749 // Try to acquire the guard.
750 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_, timeout) == -1)
754 // If there's no contention, just grab the lock immediately
755 // (since this is the common case we'll optimize for it).
756 if (m->nesting_level_ == 0)
758 // If we already own the lock, then increment the nesting level
760 else if (ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
762 // Wait until the nesting level has dropped to zero, at
763 // which point we can acquire the lock.
764 while (m->nesting_level_ > 0)
766 result = ACE_OS::cond_timedwait (&m->lock_available_,
768 const_cast <ACE_Time_Value *> (&timeout));
770 // The mutex is reacquired even in the case of a timeout
771 // release the mutex to prevent a deadlock
774 // Save/restore errno.
775 ACE_Errno_Guard error (errno);
776 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
782 // At this point the nesting_mutex_ is held...
786 // At this point, we can safely increment the nesting_level_ no
787 // matter how we got here!
790 // Save/restore errno.
791 ACE_Errno_Guard error (errno);
792 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
795 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
798 ACE_UNUSED_ARG (timeout);
799 ACE_NOTSUP_RETURN (-1);
800 #endif /* ACE_HAS_THREADS */
804 ACE_OS::recursive_mutex_lock (ACE_recursive_thread_mutex_t *m,
805 const ACE_Time_Value *timeout)
808 ? ACE_OS::recursive_mutex_lock (m)
809 : ACE_OS::recursive_mutex_lock (m, *timeout);
813 ACE_OS::recursive_mutex_trylock (ACE_recursive_thread_mutex_t *m)
815 #if defined (ACE_HAS_THREADS)
816 #if defined (ACE_HAS_RECURSIVE_MUTEXES)
817 return ACE_OS::thread_mutex_trylock (m);
819 ACE_thread_t t_id = ACE_OS::thr_self ();
822 // Acquire the guard.
823 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
827 // If there's no contention, just grab the lock immediately.
828 if (m->nesting_level_ == 0)
831 m->nesting_level_ = 1;
833 // If we already own the lock, then increment the nesting level
835 else if (ACE_OS::thr_equal (t_id, m->owner_id_))
845 // Save/restore errno.
846 ACE_Errno_Guard error (errno);
847 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
850 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
853 ACE_NOTSUP_RETURN (-1);
854 #endif /* ACE_HAS_THREADS */
858 ACE_OS::recursive_mutex_unlock (ACE_recursive_thread_mutex_t *m)
860 #if defined (ACE_HAS_THREADS)
861 # if defined (ACE_HAS_RECURSIVE_MUTEXES)
862 return ACE_OS::thread_mutex_unlock (m);
864 ACE_OS_TRACE ("ACE_OS::recursive_mutex_unlock");
865 # if !defined (ACE_NDEBUG)
866 ACE_thread_t t_id = ACE_OS::thr_self ();
867 # endif /* ACE_NDEBUG */
870 if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
874 # if !defined (ACE_NDEBUG)
875 if (m->nesting_level_ == 0
876 || ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
882 # endif /* ACE_NDEBUG */
885 if (m->nesting_level_ == 0)
887 // This may not be strictly necessary, but it does put
888 // the mutex into a known state...
889 m->owner_id_ = ACE_OS::NULL_thread;
891 // Inform a waiter that the lock is free.
892 if (ACE_OS::cond_signal (&m->lock_available_) == -1)
899 // Save/restore errno.
900 ACE_Errno_Guard error (errno);
901 ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
904 # endif /* ACE_HAS_RECURSIVE_MUTEXES */
907 ACE_NOTSUP_RETURN (-1);
908 #endif /* ACE_HAS_THREADS */
912 ACE_OS::rw_rdlock (ACE_rwlock_t *rw)
914 ACE_OS_TRACE ("ACE_OS::rw_rdlock");
915 #if defined (ACE_HAS_THREADS)
916 # if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
917 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
919 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_rdlock (rw),
924 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_rdlock (rw), result), int, -1);
925 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
926 # else /* NT, POSIX, and VxWorks don't support this natively. */
927 # if defined (ACE_HAS_PTHREADS)
928 ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
929 # endif /* ACE_HAS_PTHREADS */
931 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
932 result = -1; // -1 means didn't get the mutex.
935 // Give preference to writers who are waiting.
936 while (rw->ref_count_ < 0 || rw->num_waiting_writers_ > 0)
938 rw->num_waiting_readers_++;
939 if (ACE_OS::cond_wait (&rw->waiting_readers_, &rw->lock_) == -1)
941 result = -2; // -2 means that we need to release the mutex.
944 rw->num_waiting_readers_--;
950 ACE_OS::mutex_unlock (&rw->lock_);
951 # if defined (ACE_HAS_PTHREADS)
952 ACE_PTHREAD_CLEANUP_POP (0);
953 # endif /* defined (ACE_HAS_PTHREADS) */
955 # endif /* ! ACE_LACKS_RWLOCK_T */
958 ACE_NOTSUP_RETURN (-1);
959 #endif /* ACE_HAS_THREADS */
963 ACE_OS::rw_tryrdlock (ACE_rwlock_t *rw)
965 ACE_OS_TRACE ("ACE_OS::rw_tryrdlock");
966 #if defined (ACE_HAS_THREADS)
967 # if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
968 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
970 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_tryrdlock (rw),
975 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_tryrdlock (rw), result), int, -1);
976 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
977 # else /* NT, POSIX, and VxWorks don't support this natively. */
980 if (ACE_OS::mutex_lock (&rw->lock_) != -1)
982 ACE_Errno_Guard error (errno);
984 if (rw->ref_count_ == -1 || rw->num_waiting_writers_ > 0)
995 ACE_OS::mutex_unlock (&rw->lock_);
998 # endif /* ! ACE_LACKS_RWLOCK_T */
1000 ACE_UNUSED_ARG (rw);
1001 ACE_NOTSUP_RETURN (-1);
1002 #endif /* ACE_HAS_THREADS */
1006 ACE_OS::rw_trywrlock (ACE_rwlock_t *rw)
1008 ACE_OS_TRACE ("ACE_OS::rw_trywrlock");
1009 #if defined (ACE_HAS_THREADS)
1010 # if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1011 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1013 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_trywrlock (rw),
1016 # else /* Solaris */
1018 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_trywrlock (rw), result), int, -1);
1019 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1020 # else /* NT, POSIX, and VxWorks don't support this natively. */
1023 if (ACE_OS::mutex_lock (&rw->lock_) != -1)
1025 ACE_Errno_Guard error (errno);
1027 if (rw->ref_count_ != 0)
1034 rw->ref_count_ = -1;
1038 ACE_OS::mutex_unlock (&rw->lock_);
1041 # endif /* ! ACE_LACKS_RWLOCK_T */
1043 ACE_UNUSED_ARG (rw);
1044 ACE_NOTSUP_RETURN (-1);
1045 #endif /* ACE_HAS_THREADS */
1048 // Note that the caller of this method *must* already possess this
1049 // lock as a read lock.
1050 // return {-1 and no errno set means: error,
1051 // -1 and errno==EBUSY set means: could not upgrade,
1052 // 0 means: upgraded successfully}
1055 ACE_OS::rw_trywrlock_upgrade (ACE_rwlock_t *rw)
1057 ACE_OS_TRACE ("ACE_OS::rw_trywrlock_upgrade");
1058 #if defined (ACE_HAS_THREADS)
1059 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1060 // This will probably result in -1, EDEADLK, at least on HP-UX, but let it
1061 // go - it's a more descriptive error than ENOTSUP.
1063 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_trywrlock (rw),
1066 # elif !defined (ACE_LACKS_RWLOCK_T)
1067 // Some native rwlocks, such as those on Solaris, don't
1068 // support the upgrade feature . . .
1069 ACE_UNUSED_ARG (rw);
1070 ACE_NOTSUP_RETURN (-1);
1071 # else /* NT, POSIX, and VxWorks don't support this natively. */
1072 // The ACE rwlock emulation does support upgrade . . .
1075 # if defined (ACE_HAS_PTHREADS)
1076 ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
1077 # endif /* defined (ACE_HAS_PTHREADS) */
1079 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
1081 // -1 means didn't get the mutex, error
1082 else if (rw->important_writer_)
1083 // an other reader upgrades already
1090 while (rw->ref_count_ > 1) // wait until only I am left
1092 rw->num_waiting_writers_++; // prohibit any more readers
1093 rw->important_writer_ = 1;
1095 if (ACE_OS::cond_wait (&rw->waiting_important_writer_, &rw->lock_) == -1)
1098 // we know that we have the lock again, we have this guarantee,
1099 // but something went wrong
1101 rw->important_writer_ = 0;
1102 rw->num_waiting_writers_--;
1106 // nothing bad happend
1107 rw->ref_count_ = -1;
1108 // now I am a writer
1109 // everything is O.K.
1113 ACE_OS::mutex_unlock (&rw->lock_);
1115 # if defined (ACE_HAS_PTHREADS)
1116 ACE_PTHREAD_CLEANUP_POP (0);
1117 # endif /* defined (ACE_HAS_PTHREADS) */
1121 # endif /* ! ACE_LACKS_RWLOCK_T */
1123 ACE_UNUSED_ARG (rw);
1124 ACE_NOTSUP_RETURN (-1);
1125 #endif /* ACE_HAS_THREADS */
1129 ACE_OS::rw_unlock (ACE_rwlock_t *rw)
1131 ACE_OS_TRACE ("ACE_OS::rw_unlock");
1132 #if defined (ACE_HAS_THREADS)
1133 # if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1134 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1136 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_unlock (rw),
1139 # else /* Solaris */
1141 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_unlock (rw), result), int, -1);
1142 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1143 # else /* NT, POSIX, and VxWorks don't support this natively. */
1144 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
1147 if (rw->ref_count_ > 0) // Releasing a reader.
1149 else if (rw->ref_count_ == -1) // Releasing a writer.
1153 (void) ACE_OS::mutex_unlock (&rw->lock_);
1154 return -1; // @@ ACE_ASSERT (!"count should not be 0!\n");
1158 ACE_Errno_Guard error (errno);
1160 if (rw->important_writer_ && rw->ref_count_ == 1)
1161 // only the reader requesting to upgrade its lock is left over.
1163 result = ACE_OS::cond_signal (&rw->waiting_important_writer_);
1166 else if (rw->num_waiting_writers_ > 0 && rw->ref_count_ == 0)
1167 // give preference to writers over readers...
1169 result = ACE_OS::cond_signal (&rw->waiting_writers_);
1172 else if (rw->num_waiting_readers_ > 0 && rw->num_waiting_writers_ == 0)
1174 result = ACE_OS::cond_broadcast (&rw->waiting_readers_);
1178 (void) ACE_OS::mutex_unlock (&rw->lock_);
1180 # endif /* ! ace_lacks_rwlock_t */
1182 ACE_UNUSED_ARG (rw);
1183 ACE_NOTSUP_RETURN (-1);
1184 #endif /* ace_has_threads */
1188 ACE_OS::rw_wrlock (ACE_rwlock_t *rw)
1190 ACE_OS_TRACE ("ACE_OS::rw_wrlock");
1191 #if defined (ACE_HAS_THREADS)
1192 # if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1193 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1195 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_wrlock (rw),
1198 # else /* Solaris */
1200 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_wrlock (rw), result), int, -1);
1201 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1202 # else /* NT, POSIX, and VxWorks don't support this natively. */
1203 # if defined (ACE_HAS_PTHREADS)
1204 ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
1205 # endif /* defined (ACE_HAS_PTHREADS) */
1208 if (ACE_OS::mutex_lock (&rw->lock_) == -1)
1209 result = -1; // -1 means didn't get the mutex.
1212 while (rw->ref_count_ != 0)
1214 rw->num_waiting_writers_++;
1216 if (ACE_OS::cond_wait (&rw->waiting_writers_, &rw->lock_) == -1)
1218 result = -2; // -2 means we need to release the mutex.
1222 rw->num_waiting_writers_--;
1226 rw->ref_count_ = -1;
1228 ACE_OS::mutex_unlock (&rw->lock_);
1229 # if defined (ACE_HAS_PTHREADS)
1230 ACE_PTHREAD_CLEANUP_POP (0);
1231 # endif /* defined (ACE_HAS_PTHREADS) */
1233 # endif /* ! ACE_LACKS_RWLOCK_T */
1235 ACE_UNUSED_ARG (rw);
1236 ACE_NOTSUP_RETURN (-1);
1237 #endif /* ACE_HAS_THREADS */
1241 ACE_OS::rwlock_destroy (ACE_rwlock_t *rw)
1243 ACE_OS_TRACE ("ACE_OS::rwlock_destroy");
1244 #if defined (ACE_HAS_THREADS)
1245 # if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1246 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1248 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_destroy (rw),
1251 # else /* Solaris */
1253 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rwlock_destroy (rw), result), int, -1);
1254 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1255 # else /* NT, POSIX, and VxWorks don't support this natively. */
1256 ACE_OS::mutex_destroy (&rw->lock_);
1257 ACE_OS::cond_destroy (&rw->waiting_readers_);
1258 ACE_OS::cond_destroy (&rw->waiting_important_writer_);
1259 return ACE_OS::cond_destroy (&rw->waiting_writers_);
1260 # endif /* ACE_HAS_STHREADS && !defined (ACE_LACKS_RWLOCK_T) */
1262 ACE_UNUSED_ARG (rw);
1263 ACE_NOTSUP_RETURN (-1);
1264 #endif /* ACE_HAS_THREADS */
1267 #if defined (ACE_HAS_THREADS) && (!defined (ACE_LACKS_RWLOCK_T) || \
1268 defined (ACE_HAS_PTHREADS_UNIX98_EXT))
1270 ACE_OS::rwlock_init (ACE_rwlock_t *rw,
1272 const ACE_TCHAR *name,
1275 // ACE_OS_TRACE ("ACE_OS::rwlock_init");
1276 # if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
1277 ACE_UNUSED_ARG (name);
1278 ACE_UNUSED_ARG (arg);
1281 pthread_rwlockattr_t attr;
1282 pthread_rwlockattr_init (&attr);
1283 # if !defined (ACE_LACKS_RWLOCKATTR_PSHARED)
1284 pthread_rwlockattr_setpshared (&attr, (type == USYNC_THREAD ?
1285 PTHREAD_PROCESS_PRIVATE :
1286 PTHREAD_PROCESS_SHARED));
1288 ACE_UNUSED_ARG (type);
1289 # endif /* !ACE_LACKS_RWLOCKATTR_PSHARED */
1290 status = ACE_ADAPT_RETVAL (pthread_rwlock_init (rw, &attr), status);
1291 pthread_rwlockattr_destroy (&attr);
1299 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rwlock_init (rw, type, arg), result), int, -1);
1300 # endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
1302 #endif /* ACE_HAS THREADS && !defined (ACE_LACKS_RWLOCK_T) */
1305 ACE_OS::sema_destroy (ACE_sema_t *s)
1307 ACE_OS_TRACE ("ACE_OS::sema_destroy");
1308 # if defined (ACE_HAS_POSIX_SEM)
1310 # if !defined (ACE_HAS_POSIX_SEM_TIMEOUT) && !defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
1311 ACE_OS::mutex_destroy (&s->lock_);
1312 ACE_OS::cond_destroy (&s->count_nonzero_);
1313 # endif /* !ACE_HAS_POSIX_SEM_TIMEOUT && !ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION */
1314 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1317 // Only destroy the semaphore if we're the ones who
1319 ACE_OSCALL (::sem_destroy (s->sema_),int, -1, result);
1320 ACE_OS::shm_unlink (s->name_);
1327 ACE_OSCALL (::sem_unlink (s->name_), int, -1, result);
1328 ACE_OS::free ((void *) s->name_);
1329 ACE_OSCALL_RETURN (::sem_close (s->sema_), int, -1);
1331 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1334 ACE_OSCALL (::sem_destroy (s->sema_), int, -1, result);
1335 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1337 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1342 # elif defined (ACE_USES_FIFO_SEM)
1346 r0 = ACE_OS::unlink (s->name_);
1347 ACE_OS::free (s->name_);
1350 int r1 = ACE_OS::close (s->fd_[0]); /* ignore error */
1351 int r2 = ACE_OS::close (s->fd_[1]); /* ignore error */
1352 return r0 != 0 || r1 != 0 || r2 != 0 ? -1 : 0;
1353 # elif defined (ACE_HAS_THREADS)
1354 # if defined (ACE_HAS_STHREADS)
1356 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_destroy (s), result), int, -1);
1357 # elif defined (ACE_HAS_PTHREADS)
1358 int r1 = ACE_OS::mutex_destroy (&s->lock_);
1359 int r2 = ACE_OS::cond_destroy (&s->count_nonzero_);
1360 return r1 != 0 || r2 != 0 ? -1 : 0;
1361 # elif defined (ACE_HAS_WTHREADS)
1362 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
1363 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (*s), ace_result_), int, -1);
1364 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
1365 // Free up underlying objects of the simulated semaphore.
1366 int r1 = ACE_OS::thread_mutex_destroy (&s->lock_);
1367 int r2 = ACE_OS::event_destroy (&s->count_nonzero_);
1368 return r1 != 0 || r2 != 0 ? -1 : 0;
1369 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
1370 # elif defined (ACE_VXWORKS)
1372 ACE_OSCALL (::semDelete (s->sema_), int, -1, result);
1375 # endif /* ACE_HAS_STHREADS */
1378 ACE_NOTSUP_RETURN (-1);
1379 # endif /* ACE_HAS_POSIX_SEM */
1382 // NOTE: The previous four function definitions must appear before
1383 // ACE_OS::sema_init ().
1386 ACE_OS::sema_init (ACE_sema_t *s,
1392 LPSECURITY_ATTRIBUTES sa)
1394 ACE_OS_TRACE ("ACE_OS::sema_init");
1395 #if defined (ACE_HAS_POSIX_SEM)
1396 ACE_UNUSED_ARG (max);
1397 ACE_UNUSED_ARG (sa);
1400 # if defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
1401 ACE_UNUSED_ARG (arg);
1405 if (ACE_OS::mutex_init (&s->lock_, type, name,
1406 (ACE_mutexattr_t *) arg) == 0
1407 && ACE_OS::cond_init (&s->count_nonzero_, (short)type, name, arg) == 0
1408 && ACE_OS::mutex_lock (&s->lock_) == 0)
1410 if (ACE_OS::mutex_unlock (&s->lock_) == 0)
1416 ACE_OS::mutex_destroy (&s->lock_);
1417 ACE_OS::cond_destroy (&s->count_nonzero_);
1420 # endif /* ACE_HAS_POSIX_SEM_TIMEOUT || ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION */
1422 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1423 s->new_sema_ = false;
1424 if (type == USYNC_PROCESS)
1426 // Let's see if it already exists.
1427 ACE_HANDLE fd = ACE_OS::shm_open (ACE_TEXT_CHAR_TO_TCHAR (name),
1428 O_RDWR | O_CREAT | O_EXCL,
1429 ACE_DEFAULT_FILE_PERMS);
1430 if (fd == ACE_INVALID_HANDLE)
1432 if (errno == EEXIST)
1433 fd = ACE_OS::shm_open (ACE_TEXT_CHAR_TO_TCHAR (name),
1435 ACE_DEFAULT_FILE_PERMS);
1441 // We own this shared memory object! Let's set its
1443 if (ACE_OS::ftruncate (fd,
1444 sizeof (ACE_sema_t)) == -1)
1446 s->name_ = ACE_OS::strdup (name);
1453 s->sema_ = (sem_t *)
1455 sizeof (ACE_sema_t),
1461 if (s->sema_ == (sem_t *) MAP_FAILED)
1464 // @@ According UNIX Network Programming V2 by Stevens,
1465 // sem_init() is currently not required to return zero on
1466 // success, but it *does* return -1 upon failure. For
1467 // this reason, check for failure by comparing to -1,
1468 // instead of checking for success by comparing to zero.
1470 // Only initialize it if we're the one who created it.
1471 && ::sem_init (s->sema_, type == USYNC_PROCESS, count) == -1)
1478 # if defined (sun) || defined (HPUX)
1479 // Solaris and HP-UX require the name to start with a slash. Solaris
1480 // further requires that there be no other slashes than the first.
1481 const char *last_slash = ACE_OS::strrchr (name, '/');
1482 char name2[MAXPATHLEN];
1483 if (0 == last_slash)
1485 ACE_OS::strcpy (name2, "/");
1486 ACE_OS::strcat (name2, name);
1491 name = last_slash; // Chop off chars preceding last slash
1493 # endif /* sun || HPUX */
1495 ACE_ALLOCATOR_RETURN (s->name_,
1496 ACE_OS::strdup (name),
1498 s->sema_ = ::sem_open (s->name_,
1500 ACE_DEFAULT_FILE_PERMS,
1502 if (s->sema_ == (sem_t *) SEM_FAILED)
1507 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1510 ACE_NEW_RETURN (s->sema_,
1513 # if defined (ACE_LACKS_NAMED_POSIX_SEM)
1514 s->new_sema_ = true;
1515 # endif /* ACE_LACKS_NAMED_POSIX_SEM */
1516 ACE_OSCALL_RETURN (::sem_init (s->sema_,
1517 type != USYNC_THREAD,
1521 #elif defined (ACE_USES_FIFO_SEM)
1522 ACE_UNUSED_ARG (arg);
1523 ACE_UNUSED_ARG (max);
1524 ACE_UNUSED_ARG (sa);
1526 mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP;
1528 if (type == USYNC_THREAD)
1530 // Create systemwide unique name for semaphore
1531 char uname[ACE_UNIQUE_NAME_LEN];
1532 ACE_OS::unique_name ((const void *) s,
1534 ACE_UNIQUE_NAME_LEN);
1539 s->fd_[0] = s->fd_[1] = ACE_INVALID_HANDLE;
1540 bool creator = false;
1542 if (ACE_OS::mkfifo (ACE_TEXT_CHAR_TO_TCHAR (name), mode) < 0)
1544 if (errno != EEXIST) /* already exists OK else ERR */
1546 // check if this is a real FIFO, not just some other existing file
1548 if (ACE_OS::stat (name, &fs))
1550 if (!S_ISFIFO (fs.st_mode))
1552 // existing file is not a FIFO
1558 creator = true; // remember we created it for initialization at end
1560 // for processshared semaphores remember who we are to be able to remove
1561 // the FIFO when we're done with it
1562 if (type == USYNC_PROCESS)
1564 s->name_ = ACE_OS::strdup (name);
1568 ACE_OS::unlink (name);
1573 if ((s->fd_[0] = ACE_OS::open (name, O_RDONLY | O_NONBLOCK)) == ACE_INVALID_HANDLE
1574 || (s->fd_[1] = ACE_OS::open (name, O_WRONLY | O_NONBLOCK)) == ACE_INVALID_HANDLE)
1577 /* turn off nonblocking for fd_[0] */
1578 if ((flags = ACE_OS::fcntl (s->fd_[0], F_GETFL, 0)) < 0)
1581 flags &= ~O_NONBLOCK;
1582 if (ACE_OS::fcntl (s->fd_[0], F_SETFL, flags) < 0)
1585 //if (s->name_ && count)
1586 if (creator && count)
1589 for (u_int i=0; i<count ;++i)
1590 if (ACE_OS::write (s->fd_[1], &c, sizeof (char)) != 1)
1594 // In the case of process scope semaphores we can already unlink the FIFO now that
1595 // we completely set it up (the opened handles will keep it active until we close
1596 // thos down). This way we're protected against unexpected crashes as far as removal
1598 // Unfortunately this does not work for processshared FIFOs since as soon as we
1599 // have unlinked the semaphore no other process will be able to open it anymore.
1600 if (type == USYNC_THREAD)
1602 ACE_OS::unlink (name);
1606 #elif defined (ACE_HAS_THREADS)
1607 # if defined (ACE_HAS_STHREADS)
1608 ACE_UNUSED_ARG (name);
1609 ACE_UNUSED_ARG (max);
1610 ACE_UNUSED_ARG (sa);
1612 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_init (s, count, type, arg), result),
1614 # elif defined (ACE_HAS_PTHREADS)
1615 ACE_UNUSED_ARG (max);
1616 ACE_UNUSED_ARG (sa);
1619 if (ACE_OS::mutex_init (&s->lock_, type, name,
1620 (ACE_mutexattr_t *) arg) == 0
1621 && ACE_OS::cond_init (&s->count_nonzero_, type, name, arg) == 0
1622 && ACE_OS::mutex_lock (&s->lock_) == 0)
1627 if (ACE_OS::mutex_unlock (&s->lock_) == 0)
1633 ACE_OS::mutex_destroy (&s->lock_);
1634 ACE_OS::cond_destroy (&s->count_nonzero_);
1637 # elif defined (ACE_HAS_WTHREADS)
1638 # if ! defined (ACE_USES_WINCE_SEMA_SIMULATION)
1639 ACE_UNUSED_ARG (type);
1640 ACE_UNUSED_ARG (arg);
1641 // Create the semaphore with its value initialized to <count> and
1642 // its maximum value initialized to <max>.
1643 SECURITY_ATTRIBUTES sa_buffer;
1644 SECURITY_DESCRIPTOR sd_buffer;
1645 *s = ::CreateSemaphoreA
1646 (ACE_OS::default_win32_security_attributes_r (sa, &sa_buffer, &sd_buffer),
1652 ACE_FAIL_RETURN (-1);
1656 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
1659 // Initialize internal object for semaphore simulation.
1660 // Grab the lock as soon as possible when we initializing
1661 // the semaphore count. Notice that we initialize the
1662 // event object as "manually reset" so we can amortize the
1663 // cost for singling/reseting the event.
1664 // @@ I changed the mutex type to thread_mutex. Notice that this
1665 // is basically a CriticalSection object and doesn't not has
1666 // any security attribute whatsoever. However, since this
1667 // semaphore implementation only works within a process, there
1668 // shouldn't any security issue at all.
1669 if (ACE_OS::thread_mutex_init (&s->lock_, type, name, (ACE_mutexattr_t *)arg) == 0
1670 && ACE_OS::event_init (&s->count_nonzero_, 1,
1671 count > 0, type, name, arg, sa) == 0
1672 && ACE_OS::thread_mutex_lock (&s->lock_) == 0)
1676 if (ACE_OS::thread_mutex_unlock (&s->lock_) == 0)
1680 // Destroy the internal objects if we didn't initialize
1681 // either of them successfully. Don't bother to check
1685 ACE_OS::thread_mutex_destroy (&s->lock_);
1686 ACE_OS::event_destroy (&s->count_nonzero_);
1689 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
1690 # elif defined (ACE_VXWORKS)
1691 ACE_UNUSED_ARG (name);
1692 ACE_UNUSED_ARG (arg);
1693 ACE_UNUSED_ARG (max);
1694 ACE_UNUSED_ARG (sa);
1696 s->sema_ = ::semCCreate (type, count);
1697 return s->sema_ ? 0 : -1;
1698 # endif /* ACE_HAS_STHREADS */
1701 ACE_UNUSED_ARG (count);
1702 ACE_UNUSED_ARG (type);
1703 ACE_UNUSED_ARG (name);
1704 ACE_UNUSED_ARG (arg);
1705 ACE_UNUSED_ARG (max);
1706 ACE_UNUSED_ARG (sa);
1707 ACE_NOTSUP_RETURN (-1);
1708 #endif /* ACE_HAS_POSIX_SEM */
1711 #if defined (ACE_HAS_WCHAR)
1713 ACE_OS::sema_init (ACE_sema_t *s,
1716 const wchar_t *name,
1719 LPSECURITY_ATTRIBUTES sa)
1721 # if defined (ACE_HAS_WTHREADS)
1722 # if ! defined (ACE_USES_WINCE_SEMA_SIMULATION)
1723 ACE_UNUSED_ARG (type);
1724 ACE_UNUSED_ARG (arg);
1725 // Create the semaphore with its value initialized to <count> and
1726 // its maximum value initialized to <max>.
1727 SECURITY_ATTRIBUTES sa_buffer;
1728 SECURITY_DESCRIPTOR sd_buffer;
1729 *s = ::CreateSemaphoreW
1730 (ACE_OS::default_win32_security_attributes_r (sa, &sa_buffer, &sd_buffer),
1736 ACE_FAIL_RETURN (-1);
1740 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
1743 // Initialize internal object for semaphore simulation.
1744 // Grab the lock as soon as possible when we initializing
1745 // the semaphore count. Notice that we initialize the
1746 // event object as "manually reset" so we can amortize the
1747 // cost for singling/reseting the event.
1748 // @@ I changed the mutex type to thread_mutex. Notice that this
1749 // is basically a CriticalSection object and doesn't not has
1750 // any security attribute whatsoever. However, since this
1751 // semaphore implementation only works within a process, there
1752 // shouldn't any security issue at all.
1753 if (ACE_OS::thread_mutex_init (&s->lock_, type, name, (ACE_mutexattr_t *)arg) == 0
1754 && ACE_OS::event_init (&s->count_nonzero_, 1,
1755 count > 0, type, name, arg, sa) == 0
1756 && ACE_OS::thread_mutex_lock (&s->lock_) == 0)
1760 if (ACE_OS::thread_mutex_unlock (&s->lock_) == 0)
1764 // Destroy the internal objects if we didn't initialize
1765 // either of them successfully. Don't bother to check
1769 ACE_OS::thread_mutex_destroy (&s->lock_);
1770 ACE_OS::event_destroy (&s->count_nonzero_);
1773 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
1774 # else /* ACE_HAS_WTHREADS */
1775 // Just call the normal char version.
1776 return ACE_OS::sema_init (s, count, type, ACE_Wide_To_Ascii (name).char_rep (), arg, max, sa);
1777 # endif /* ACE_HAS_WTHREADS */
1779 #endif /* ACE_HAS_WCHAR */
1782 ACE_OS::sema_post (ACE_sema_t *s)
1784 ACE_OS_TRACE ("ACE_OS::sema_post");
1785 # if defined (ACE_HAS_POSIX_SEM)
1786 # if defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
1787 ACE_OSCALL_RETURN (::sem_post (s->sema_), int, -1);
1791 if (ACE_OS::mutex_lock (&s->lock_) == 0)
1793 if (::sem_post (s->sema_) == 0)
1794 result = ACE_OS::cond_signal (&s->count_nonzero_);
1796 ACE_OS::mutex_unlock (&s->lock_);
1799 # endif /* ACE_HAS_POSIX_SEM_TIMEOUT || ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION */
1800 # elif defined (ACE_USES_FIFO_SEM)
1802 if (ACE_OS::write (s->fd_[1], &c, sizeof (char)) == sizeof (char))
1805 # elif defined (ACE_HAS_THREADS)
1806 # if defined (ACE_HAS_STHREADS)
1808 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_post (s), result), int, -1);
1809 # elif defined (ACE_HAS_PTHREADS)
1812 if (ACE_OS::mutex_lock (&s->lock_) == 0)
1814 // Always allow a waiter to continue if there is one.
1815 if (s->waiters_ > 0)
1816 result = ACE_OS::cond_signal (&s->count_nonzero_);
1821 ACE_OS::mutex_unlock (&s->lock_);
1824 # elif defined (ACE_HAS_WTHREADS)
1825 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
1826 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*s, 1, 0),
1829 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
1832 // Since we are simulating semaphores, we need to update semaphore
1833 // count manually. Grab the lock to prevent race condition first.
1834 if (ACE_OS::thread_mutex_lock (&s->lock_) == 0)
1836 // Check the original state of event object. Single the event
1837 // object in transition from semaphore not available to
1838 // semaphore available.
1839 if (s->count_++ <= 0)
1840 result = ACE_OS::event_signal (&s->count_nonzero_);
1844 ACE_OS::thread_mutex_unlock (&s->lock_);
1847 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
1848 # elif defined (ACE_VXWORKS)
1849 ACE_OSCALL_RETURN (::semGive (s->sema_), int, -1);
1850 # endif /* ACE_HAS_STHREADS */
1853 ACE_NOTSUP_RETURN (-1);
1854 # endif /* ACE_HAS_POSIX_SEM */
1858 ACE_OS::sema_post (ACE_sema_t *s, u_int release_count)
1860 #if defined (ACE_WIN32) && !defined (ACE_USES_WINCE_SEMA_SIMULATION)
1861 // Win32 supports this natively.
1862 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*s, release_count, 0),
1863 ace_result_), int, -1);
1865 // On POSIX platforms we need to emulate this ourselves.
1866 // @@ We can optimize on this implementation. However,
1867 // the semaphore promitive on Win32 doesn't allow one
1868 // to increase a semaphore to more than the count it was
1869 // first initialized. Posix and solaris don't seem to have
1870 // this restriction. Should we impose the restriction in
1871 // our semaphore simulation?
1872 for (size_t i = 0; i < release_count; i++)
1873 if (ACE_OS::sema_post (s) == -1)
1877 #endif /* ACE_WIN32 */
1881 ACE_OS::sema_trywait (ACE_sema_t *s)
1883 ACE_OS_TRACE ("ACE_OS::sema_trywait");
1884 # if defined (ACE_HAS_POSIX_SEM)
1885 // POSIX semaphores set errno to EAGAIN if trywait fails
1886 ACE_OSCALL_RETURN (::sem_trywait (s->sema_), int, -1);
1887 # elif defined (ACE_USES_FIFO_SEM)
1891 /* turn on nonblocking for s->fd_[0] */
1892 if ((flags = ACE_OS::fcntl (s->fd_[0], F_GETFL, 0)) < 0)
1894 flags |= O_NONBLOCK;
1895 if (ACE_OS::fcntl (s->fd_[0], F_SETFL, flags) < 0)
1898 // read sets errno to EAGAIN if no input
1899 rc = ACE_OS::read (s->fd_[0], &c, sizeof (char));
1901 /* turn off nonblocking for fd_[0] */
1902 if ((flags = ACE_OS::fcntl (s->fd_[0], F_GETFL, 0)) >= 0)
1904 flags &= ~O_NONBLOCK;
1905 ACE_OS::fcntl (s->fd_[0], F_SETFL, flags);
1908 return rc == 1 ? 0 : (-1);
1909 # elif defined (ACE_HAS_THREADS)
1910 # if defined (ACE_HAS_STHREADS)
1911 // STHREADS semaphores set errno to EBUSY if trywait fails.
1913 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_trywait (s),
1916 # elif defined (ACE_HAS_PTHREADS)
1920 if (ACE_OS::mutex_lock (&s->lock_) == 0)
1930 ACE_OS::mutex_unlock (&s->lock_);
1933 # elif defined (ACE_HAS_WTHREADS)
1934 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
1935 DWORD result = ::WaitForSingleObject (*s, 0);
1937 if (result == WAIT_OBJECT_0)
1941 if (result == WAIT_TIMEOUT)
1944 ACE_OS::set_errno_to_last_error ();
1945 // This is a hack, we need to find an appropriate mapping...
1948 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
1949 // Check the status of semaphore first. Return immediately
1950 // if the semaphore is not available and avoid grabing the
1952 DWORD result = ::WaitForSingleObject (s->count_nonzero_, 0);
1954 if (result == WAIT_OBJECT_0) // Proceed when it is available.
1956 ACE_OS::thread_mutex_lock (&s->lock_);
1958 // Need to double check if the semaphore is still available.
1959 // The double checking scheme will slightly affect the
1960 // efficiency if most of the time semaphores are not blocked.
1961 result = ::WaitForSingleObject (s->count_nonzero_, 0);
1962 if (result == WAIT_OBJECT_0)
1964 // Adjust the semaphore count. Only update the event
1965 // object status when the state changed.
1968 ACE_OS::event_reset (&s->count_nonzero_);
1972 ACE_OS::thread_mutex_unlock (&s->lock_);
1975 // Translate error message to errno used by ACE.
1976 if (result == WAIT_TIMEOUT)
1979 ACE_OS::set_errno_to_last_error ();
1980 // This is taken from the hack above. ;)
1982 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
1983 # elif defined (ACE_VXWORKS)
1984 if (::semTake (s->sema_, NO_WAIT) == ERROR)
1985 if (errno == S_objLib_OBJ_UNAVAILABLE)
1987 // couldn't get the semaphore
1995 // got the semaphore
1997 # endif /* ACE_HAS_STHREADS */
2000 ACE_NOTSUP_RETURN (-1);
2001 # endif /* ACE_HAS_POSIX_SEM */
2005 ACE_OS::sema_wait (ACE_sema_t *s)
2007 ACE_OS_TRACE ("ACE_OS::sema_wait");
2008 # if defined (ACE_HAS_POSIX_SEM)
2009 ACE_OSCALL_RETURN (::sem_wait (s->sema_), int, -1);
2010 # elif defined (ACE_USES_FIFO_SEM)
2012 if (ACE_OS::read (s->fd_[0], &c, sizeof (char)) == 1)
2015 # elif defined (ACE_HAS_THREADS)
2016 # if defined (ACE_HAS_STHREADS)
2018 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_wait (s), result), int, -1);
2019 # elif defined (ACE_HAS_PTHREADS)
2022 ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
2024 if (ACE_OS::mutex_lock (&s->lock_) != 0)
2028 // Keep track of the number of waiters so that we can signal
2029 // them properly in <ACE_OS::sema_post>.
2032 // Wait until the semaphore count is > 0.
2033 while (s->count_ == 0)
2034 if (ACE_OS::cond_wait (&s->count_nonzero_,
2037 result = -2; // -2 means that we need to release the mutex.
2048 ACE_OS::mutex_unlock (&s->lock_);
2049 ACE_PTHREAD_CLEANUP_POP (0);
2050 return result < 0 ? -1 : result;
2052 # elif defined (ACE_HAS_WTHREADS)
2053 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
2054 switch (::WaitForSingleObject (*s, INFINITE))
2059 // This is a hack, we need to find an appropriate mapping...
2060 ACE_OS::set_errno_to_last_error ();
2064 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
2068 // Check if the semaphore is avialable or not and wait forever.
2069 // Don't bother to grab the lock if it is not available (to avoid
2071 switch (::WaitForSingleObject (s->count_nonzero_, INFINITE))
2074 ACE_OS::thread_mutex_lock (&s->lock_);
2076 // Need to double check if the semaphore is still available.
2077 // This time, we shouldn't wait at all.
2078 if (::WaitForSingleObject (s->count_nonzero_, 0) == WAIT_OBJECT_0)
2080 // Decrease the internal counter. Only update the event
2081 // object's status when the state changed.
2084 ACE_OS::event_reset (&s->count_nonzero_);
2088 ACE_OS::thread_mutex_unlock (&s->lock_);
2089 // if we didn't get a hold on the semaphore, the result won't
2090 // be 0 and thus, we'll start from the beginning again.
2096 // Since we wait indefinitely, anything other than
2097 // WAIT_OBJECT_O indicates an error.
2098 ACE_OS::set_errno_to_last_error ();
2099 // This is taken from the hack above. ;)
2103 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
2104 # elif defined (ACE_VXWORKS)
2105 ACE_OSCALL_RETURN (::semTake (s->sema_, WAIT_FOREVER), int, -1);
2106 # endif /* ACE_HAS_STHREADS */
2109 ACE_NOTSUP_RETURN (-1);
2110 # endif /* ACE_HAS_POSIX_SEM */
2114 ACE_OS::sema_wait (ACE_sema_t *s, ACE_Time_Value &tv)
2116 ACE_OS_TRACE ("ACE_OS::sema_wait");
2117 # if defined (ACE_HAS_POSIX_SEM)
2118 # if defined (ACE_HAS_POSIX_SEM_TIMEOUT)
2121 ts = tv; // Calls ACE_Time_Value::operator timespec_t().
2122 ACE_OSCALL (::sem_timedwait (s->sema_, &ts), int, -1, rc);
2123 if (rc == -1 && errno == ETIMEDOUT)
2124 errno = ETIME; /* POSIX returns ETIMEDOUT but we need ETIME */
2126 # elif !defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
2128 bool expired = false;
2129 ACE_Errno_Guard error (errno);
2131 ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
2133 if (ACE_OS::mutex_lock (&s->lock_) != 0)
2137 bool finished = true;
2140 result = ACE_OS::sema_trywait (s);
2141 if (result == -1 && errno == EAGAIN)
2142 expired = ACE_OS::gettimeofday () > tv;
2146 finished = result != -1 || expired ||
2147 (result == -1 && errno != EAGAIN);
2150 if (ACE_OS::cond_timedwait (&s->count_nonzero_,
2159 } while (!finished);
2164 # if defined (ACE_LACKS_COND_TIMEDWAIT_RESET)
2165 tv = ACE_OS::gettimeofday ();
2166 # endif /* ACE_LACKS_COND_TIMEDWAIT_RESET */
2170 ACE_OS::mutex_unlock (&s->lock_);
2171 ACE_PTHREAD_CLEANUP_POP (0);
2172 return result < 0 ? -1 : result;
2173 # else /* No native sem_timedwait(), and emulation disabled */
2175 ACE_UNUSED_ARG (tv);
2176 ACE_NOTSUP_RETURN (-1);
2177 # endif /* ACE_HAS_POSIX_SEM_TIMEOUT */
2178 # elif defined (ACE_USES_FIFO_SEM)
2180 ACE_Time_Value now = ACE_OS::gettimeofday ();
2184 ACE_Time_Value timeout = tv;
2187 ACE_Handle_Set fds_;
2189 fds_.set_bit (s->fd_[0]);
2190 if ((rc = ACE_OS::select (ACE_Handle_Set::MAXSIZE, fds_, 0, 0, timeout)) != 1)
2192 if (rc == 0 || errno != EAGAIN)
2200 // try to read the signal *but* do *not* block
2201 if (rc == 1 && ACE_OS::sema_trywait (s) == 0)
2204 // we were woken for input but someone beat us to it
2205 // so we wait again if there is still time
2206 now = ACE_OS::gettimeofday ();
2209 // make sure errno is set right
2213 # elif defined (ACE_HAS_THREADS)
2214 # if defined (ACE_HAS_STHREADS)
2216 ACE_UNUSED_ARG (tv);
2217 ACE_NOTSUP_RETURN (-1);
2218 # elif defined (ACE_HAS_PTHREADS)
2220 ACE_Errno_Guard error (errno);
2222 ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
2224 if (ACE_OS::mutex_lock (&s->lock_) != 0)
2228 // Keep track of the number of waiters so that we can signal
2229 // them properly in <ACE_OS::sema_post>.
2232 // Wait until the semaphore count is > 0 or until we time out.
2233 while (s->count_ == 0)
2234 if (ACE_OS::cond_timedwait (&s->count_nonzero_,
2239 result = -2; // -2 means that we need to release the mutex.
2248 # if defined (ACE_LACKS_COND_TIMEDWAIT_RESET)
2249 tv = ACE_OS::gettimeofday ();
2250 # endif /* ACE_LACKS_COND_TIMEDWAIT_RESET */
2255 ACE_OS::mutex_unlock (&s->lock_);
2256 ACE_PTHREAD_CLEANUP_POP (0);
2257 return result < 0 ? -1 : result;
2258 # elif defined (ACE_HAS_WTHREADS)
2259 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
2262 if (tv.sec () == 0 && tv.usec () == 0)
2263 msec_timeout = 0; // Do a "poll."
2266 // Note that we must convert between absolute time (which is
2267 // passed as a parameter) and relative time (which is what
2268 // <WaitForSingleObjects> expects).
2269 ACE_Time_Value relative_time (tv - ACE_OS::gettimeofday ());
2271 // Watchout for situations where a context switch has caused the
2272 // current time to be > the timeout.
2273 if (relative_time < ACE_Time_Value::zero)
2276 msec_timeout = relative_time.msec ();
2279 switch (::WaitForSingleObject (*s, msec_timeout))
2282 tv = ACE_OS::gettimeofday (); // Update time to when acquired
2288 // This is a hack, we need to find an appropriate mapping...
2289 ACE_OS::set_errno_to_last_error ();
2293 # else /* ACE_USES_WINCE_SEMA_SIMULATION */
2294 // Note that in this mode, the acquire is done in two steps, and
2295 // we may get signaled but cannot grab the semaphore before
2296 // timeout. In that case, we'll need to restart the process with
2297 // updated timeout value.
2299 // tv is an absolute time, but we need relative to work with the Windows
2300 // API. Also, some users have become accustomed to using a 0 time value
2301 // as a shortcut for "now", which works on non-Windows because 0 is
2302 // always earlier than now. However, the need to convert to relative time
2303 // means we need to watch out for this case.
2304 ACE_Time_Value end_time = tv;
2305 if (tv == ACE_Time_Value::zero)
2306 end_time = ACE_OS::gettimeofday ();
2307 ACE_Time_Value relative_time = end_time - ACE_OS::gettimeofday ();
2310 // While we are not timeout yet. >= 0 will let this go through once
2311 // and if not able to get the object, it should hit WAIT_TIMEOUT
2313 while (relative_time >= ACE_Time_Value::zero)
2315 // Wait for our turn to get the object.
2316 switch (::WaitForSingleObject (s->count_nonzero_, relative_time.msec ()))
2319 ACE_OS::thread_mutex_lock (&s->lock_);
2321 // Need to double check if the semaphore is still available.
2322 // We can only do a "try lock" styled wait here to avoid
2323 // blocking threads that want to signal the semaphore.
2324 if (::WaitForSingleObject (s->count_nonzero_, 0) == WAIT_OBJECT_0)
2326 // As before, only reset the object when the semaphore
2327 // is no longer available.
2330 ACE_OS::event_reset (&s->count_nonzero_);
2334 ACE_OS::thread_mutex_unlock (&s->lock_);
2336 // Only return when we successfully get the semaphore.
2339 tv = ACE_OS::gettimeofday (); // Update to time acquired
2344 // We have timed out.
2351 ACE_OS::set_errno_to_last_error ();
2352 // This is taken from the hack above. ;)
2356 // Haven't been able to get the semaphore yet, update the
2357 // timeout value to reflect the remaining time we want to wait.
2358 relative_time = end_time - ACE_OS::gettimeofday ();
2361 // We have timed out.
2364 # endif /* ACE_USES_WINCE_SEMA_SIMULATION */
2365 # elif defined (ACE_VXWORKS)
2366 // Note that we must convert between absolute time (which is
2367 // passed as a parameter) and relative time (which is what
2368 // the system call expects).
2369 ACE_Time_Value relative_time (tv - ACE_OS::gettimeofday ());
2371 int ticks_per_sec = ::sysClkRateGet ();
2373 int ticks = relative_time.sec () * ticks_per_sec +
2374 relative_time.usec () * ticks_per_sec / ACE_ONE_SECOND_IN_USECS;
2375 if (::semTake (s->sema_, ticks) == ERROR)
2377 if (errno == S_objLib_OBJ_TIMEOUT)
2378 // Convert the VxWorks errno to one that's common for to ACE
2381 else if (errno == S_objLib_OBJ_UNAVAILABLE)
2387 tv = ACE_OS::gettimeofday (); // Update to time acquired
2390 # endif /* ACE_HAS_STHREADS */
2393 ACE_UNUSED_ARG (tv);
2394 ACE_NOTSUP_RETURN (-1);
2395 # endif /* ACE_HAS_POSIX_SEM */
2399 ACE_OS::sema_wait (ACE_sema_t *s, ACE_Time_Value *tv)
2401 return tv == 0 ? ACE_OS::sema_wait (s) : ACE_OS::sema_wait (s, *tv);
2405 ACE_OS::semctl (int int_id, int semnum, int cmd, semun value)
2407 ACE_OS_TRACE ("ACE_OS::semctl");
2408 #if defined (ACE_HAS_SYSV_IPC)
2409 ACE_OSCALL_RETURN (::semctl (int_id, semnum, cmd, value), int, -1);
2411 ACE_UNUSED_ARG (int_id);
2412 ACE_UNUSED_ARG (semnum);
2413 ACE_UNUSED_ARG (cmd);
2414 ACE_UNUSED_ARG (value);
2416 ACE_NOTSUP_RETURN (-1);
2417 #endif /* ACE_HAS_SYSV_IPC */
2421 ACE_OS::semget (key_t key, int nsems, int flags)
2423 ACE_OS_TRACE ("ACE_OS::semget");
2424 #if defined (ACE_HAS_SYSV_IPC)
2425 ACE_OSCALL_RETURN (::semget (key, nsems, flags), int, -1);
2427 ACE_UNUSED_ARG (key);
2428 ACE_UNUSED_ARG (nsems);
2429 ACE_UNUSED_ARG (flags);
2431 ACE_NOTSUP_RETURN (-1);
2432 #endif /* ACE_HAS_SYSV_IPC */
2436 ACE_OS::semop (int int_id, struct sembuf *sops, size_t nsops)
2438 ACE_OS_TRACE ("ACE_OS::semop");
2439 #if defined (ACE_HAS_SYSV_IPC)
2440 ACE_OSCALL_RETURN (::semop (int_id, sops, nsops), int, -1);
2442 ACE_UNUSED_ARG (int_id);
2443 ACE_UNUSED_ARG (sops);
2444 ACE_UNUSED_ARG (nsops);
2446 ACE_NOTSUP_RETURN (-1);
2447 #endif /* ACE_HAS_SYSV_IPC */
2451 ACE_OS::sigtimedwait (const sigset_t *sset,
2453 const ACE_Time_Value *timeout)
2455 ACE_OS_TRACE ("ACE_OS::sigtimedwait");
2456 #if defined (ACE_HAS_SIGTIMEDWAIT)
2462 ts = *timeout; // Calls ACE_Time_Value::operator timespec_t().
2468 ACE_OSCALL_RETURN (::sigtimedwait (sset, info, tsp),
2471 ACE_UNUSED_ARG (sset);
2472 ACE_UNUSED_ARG (info);
2473 ACE_UNUSED_ARG (timeout);
2474 ACE_NOTSUP_RETURN (-1);
2475 #endif /* ACE_HAS_SIGTIMEDWAIT */
2479 ACE_OS::sigwait (sigset_t *sset, int *sig)
2481 ACE_OS_TRACE ("ACE_OS::sigwait");
2485 #if defined (ACE_HAS_THREADS)
2486 # if (defined (__FreeBSD__) && (__FreeBSD__ < 3))
2487 ACE_UNUSED_ARG (sset);
2488 ACE_NOTSUP_RETURN (-1);
2489 # elif defined (ACE_HAS_STHREADS)
2490 # if (_POSIX_C_SOURCE - 0 >= 199506L) || defined (_POSIX_PTHREAD_SEMANTICS)
2491 errno = ::sigwait (sset, sig);
2492 return errno == 0 ? *sig : -1;
2494 *sig = ::sigwait (sset);
2496 #endif /* _POSIX_C_SOURCE - 0 >= 199506L || _POSIX_PTHREAD_SEMANTICS */
2497 # elif defined (ACE_HAS_PTHREADS)
2498 // LynxOS and Digital UNIX have their own hoops to jump through.
2499 # if defined (__Lynx__)
2500 // Second arg is a void **, which we don't need (the selected
2501 // signal number is returned).
2502 *sig = ::sigwait (sset, 0);
2504 # elif defined (DIGITAL_UNIX) && defined (__DECCXX_VER)
2505 // DEC cxx (but not g++) needs this direct call to its internal
2506 // sigwait (). This allows us to #undef sigwait, so that we can
2507 // have ACE_OS::sigwait. cxx gets confused by ACE_OS::sigwait
2508 // if sigwait is _not_ #undef'ed.
2509 errno = ::_Psigwait (sset, sig);
2510 return errno == 0 ? *sig : -1;
2511 # else /* ! __Lynx __ && ! (DIGITAL_UNIX && __DECCXX_VER) */
2512 # if defined (CYGWIN32)
2513 // Cygwin has sigwait definition, but it is not implemented
2514 ACE_UNUSED_ARG (sset);
2515 ACE_NOTSUP_RETURN (-1);
2516 # elif defined (ACE_TANDEM_T1248_PTHREADS)
2517 errno = ::spt_sigwait (sset, sig);
2518 return errno == 0 ? *sig : -1;
2519 # else /* this is draft 7 or std */
2520 errno = ::sigwait (sset, sig);
2521 return errno == 0 ? *sig : -1;
2522 # endif /* CYGWIN32 */
2523 # endif /* ! __Lynx__ && ! (DIGITAL_UNIX && __DECCXX_VER) */
2524 # elif defined (ACE_HAS_WTHREADS)
2525 ACE_UNUSED_ARG (sset);
2526 ACE_NOTSUP_RETURN (-1);
2527 # elif defined (ACE_VXWORKS)
2528 // Second arg is a struct siginfo *, which we don't need (the
2529 // selected signal number is returned). Third arg is timeout: 0
2531 *sig = ::sigtimedwait (sset, 0, 0);
2533 # endif /* __FreeBSD__ */
2535 ACE_UNUSED_ARG (sset);
2536 ACE_UNUSED_ARG (sig);
2537 ACE_NOTSUP_RETURN (-1);
2538 #endif /* ACE_HAS_THREADS */
2542 ACE_OS::sigwaitinfo (const sigset_t *sset,
2545 ACE_OS_TRACE ("ACE_OS::sigwaitinfo");
2546 // If this platform has sigtimedwait, it should have sigwaitinfo as well.
2547 // If this isn't true somewhere, let me know and I'll fix this.
2548 // -Steve Huston <shuston@riverace.com>.
2549 #if defined (ACE_HAS_SIGTIMEDWAIT)
2550 ACE_OSCALL_RETURN (::sigwaitinfo (sset, info), int, -1);
2552 ACE_UNUSED_ARG (sset);
2553 ACE_UNUSED_ARG (info);
2554 ACE_NOTSUP_RETURN (-1);
2555 #endif /* ACE_HAS_SIGTIMEDWAIT */
2559 ACE_OS::thr_cancel (ACE_thread_t thr_id)
2561 ACE_OS_TRACE ("ACE_OS::thr_cancel");
2562 #if defined (ACE_HAS_THREADS)
2563 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
2565 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cancel (thr_id),
2568 # elif defined (ACE_HAS_VXTHREADS)
2569 ACE_OSCALL_RETURN (::taskDelete (thr_id), int, -1);
2570 # else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
2571 ACE_UNUSED_ARG (thr_id);
2572 ACE_NOTSUP_RETURN (-1);
2573 # endif /* ACE_HAS_PTHREADS */
2575 ACE_UNUSED_ARG (thr_id);
2576 ACE_NOTSUP_RETURN (-1);
2577 #endif /* ACE_HAS_THREADS */
2581 ACE_OS::thr_cmp (ACE_hthread_t t1, ACE_hthread_t t2)
2583 #if defined (ACE_HAS_PTHREADS)
2584 # if defined (pthread_equal)
2585 // If it's a macro we can't say "pthread_equal"...
2586 return pthread_equal (t1, t2);
2588 return pthread_equal (t1, t2);
2589 # endif /* pthread_equal */
2590 #else /* For STHREADS, WTHREADS, and VXWORKS ... */
2591 // Hum, Do we need to treat WTHREAD differently?
2592 // levine 13 oct 98 % Probably, ACE_hthread_t is a HANDLE.
2594 #endif /* ACE_HAS_PTHREADS */
2598 ACE_OS::thr_continue (ACE_hthread_t target_thread)
2600 ACE_OS_TRACE ("ACE_OS::thr_continue");
2601 #if defined (ACE_HAS_THREADS)
2602 # if defined (ACE_HAS_STHREADS)
2604 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_continue (target_thread), result), int, -1);
2605 # elif defined (ACE_HAS_PTHREADS)
2606 # if defined (ACE_HAS_PTHREAD_CONTINUE)
2608 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_continue (target_thread),
2611 # elif defined (ACE_HAS_PTHREAD_CONTINUE_NP)
2613 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_continue_np (target_thread),
2616 # elif defined (ACE_HAS_PTHREAD_RESUME_NP)
2618 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_resume_np (target_thread),
2622 ACE_UNUSED_ARG (target_thread);
2623 ACE_NOTSUP_RETURN (-1);
2624 # endif /* ACE_HAS_PTHREAD_CONTINUE */
2625 # elif defined (ACE_HAS_WTHREADS)
2626 DWORD result = ::ResumeThread (target_thread);
2627 if (result == ACE_SYSCALL_FAILED)
2628 ACE_FAIL_RETURN (-1);
2631 # elif defined (ACE_HAS_VXTHREADS)
2632 ACE_OSCALL_RETURN (::taskResume (target_thread), int, -1);
2633 # endif /* ACE_HAS_STHREADS */
2635 ACE_UNUSED_ARG (target_thread);
2636 ACE_NOTSUP_RETURN (-1);
2637 #endif /* ACE_HAS_THREADS */
2641 ACE_OS::thr_getconcurrency (void)
2643 ACE_OS_TRACE ("ACE_OS::thr_getconcurrency");
2644 #if defined (ACE_HAS_THREADS)
2645 # if defined (ACE_HAS_STHREADS)
2646 return ::thr_getconcurrency ();
2647 # elif defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_PTHREAD_GETCONCURRENCY)
2648 return pthread_getconcurrency ();
2650 ACE_NOTSUP_RETURN (-1);
2651 # endif /* ACE_HAS_STHREADS */
2653 ACE_NOTSUP_RETURN (-1);
2654 #endif /* ACE_HAS_THREADS */
2658 ACE_OS::thr_getprio (ACE_hthread_t ht_id, int &priority, int &policy)
2660 ACE_OS_TRACE ("ACE_OS::thr_getprio");
2661 ACE_UNUSED_ARG (policy);
2662 #if defined (ACE_HAS_THREADS)
2663 # if (defined (ACE_HAS_PTHREADS) && \
2664 (!defined (ACE_LACKS_SETSCHED) || defined (ACE_HAS_PTHREAD_SCHEDPARAM)))
2666 struct sched_param param;
2669 ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_getschedparam (ht_id, &policy, ¶m),
2672 priority = param.sched_priority;
2674 # elif defined (ACE_HAS_STHREADS)
2676 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_getprio (ht_id, &priority), result), int, -1);
2677 # elif defined (ACE_HAS_WTHREADS) && !defined (ACE_HAS_WINCE)
2678 ACE_Errno_Guard error (errno);
2680 priority = ::GetThreadPriority (ht_id);
2682 # if defined (ACE_HAS_PHARLAP)
2683 # if defined (ACE_PHARLAP_LABVIEW_RT)
2684 policy = ACE_SCHED_FIFO;
2686 DWORD timeslice = ::EtsGetTimeSlice ();
2687 policy = timeslice == 0 ? ACE_SCHED_OTHER : ACE_SCHED_FIFO;
2688 # endif /* ACE_PHARLAP_LABVIEW_RT */
2690 DWORD priority_class = ::GetPriorityClass (::GetCurrentProcess ());
2691 if (priority_class == 0 && (error = ::GetLastError ()) != NO_ERROR)
2692 ACE_FAIL_RETURN (-1);
2696 REALTIME_PRIORITY_CLASS) ? ACE_SCHED_FIFO : ACE_SCHED_OTHER;
2697 # endif /* ACE_HAS_PHARLAP */
2700 # elif defined (ACE_HAS_VXTHREADS)
2701 ACE_OSCALL_RETURN (::taskPriorityGet (ht_id, &priority), int, -1);
2703 ACE_UNUSED_ARG (ht_id);
2704 ACE_UNUSED_ARG (priority);
2705 ACE_NOTSUP_RETURN (-1);
2706 # endif /* ACE_HAS_STHREADS */
2708 ACE_UNUSED_ARG (ht_id);
2709 ACE_UNUSED_ARG (priority);
2710 ACE_NOTSUP_RETURN (-1);
2711 #endif /* ACE_HAS_THREADS */
2715 ACE_OS::thr_getprio (ACE_hthread_t ht_id, int &priority)
2717 ACE_OS_TRACE ("ACE_OS::thr_getprio");
2719 return ACE_OS::thr_getprio (ht_id, priority, policy);
2722 #if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
2724 ACE_OS::thr_getspecific_native (ACE_OS_thread_key_t key, void **data)
2726 // ACE_OS_TRACE ("ACE_OS::thr_getspecific_native");
2727 # if defined (ACE_HAS_PTHREADS)
2728 *data = pthread_getspecific (key);
2730 # elif defined (ACE_HAS_STHREADS)
2732 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_getspecific (key, data), result), int, -1);
2733 # elif defined (ACE_HAS_WTHREADS)
2734 *data = ::TlsGetValue (key);
2735 if (*data == 0 && ::GetLastError () != NO_ERROR)
2737 ACE_OS::set_errno_to_last_error ();
2742 # else /* ACE_HAS_PTHREADS etc.*/
2743 ACE_UNUSED_ARG (key);
2744 ACE_UNUSED_ARG (data);
2745 ACE_NOTSUP_RETURN (-1);
2746 # endif /* ACE_HAS_PTHREADS etc.*/
2748 #endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
2751 ACE_OS::thr_getspecific (ACE_thread_key_t key, void **data)
2753 // ACE_OS_TRACE ("ACE_OS::thr_getspecific");
2754 #if defined (ACE_HAS_THREADS)
2755 # if defined (ACE_HAS_TSS_EMULATION)
2756 if (ACE_TSS_Emulation::is_key (key) == 0)
2764 *data = ACE_TSS_Emulation::ts_object (key);
2767 # elif defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
2768 return ACE_OS::thr_getspecific_native (key, data);
2770 ACE_UNUSED_ARG (key);
2771 ACE_UNUSED_ARG (data);
2772 ACE_NOTSUP_RETURN (-1);
2773 # endif /* ACE_HAS_TSS_EMULATION */
2775 ACE_UNUSED_ARG (key);
2776 ACE_UNUSED_ARG (data);
2777 ACE_NOTSUP_RETURN (-1);
2778 #endif /* ACE_HAS_THREADS */
2781 #if !defined (ACE_HAS_VXTHREADS)
2783 ACE_OS::thr_join (ACE_hthread_t thr_handle,
2784 ACE_THR_FUNC_RETURN *status)
2786 ACE_OS_TRACE ("ACE_OS::thr_join");
2787 #if defined (ACE_HAS_THREADS)
2788 # if defined (ACE_HAS_STHREADS)
2790 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_join (thr_handle, 0, status), result),
2792 # elif defined (ACE_HAS_PTHREADS)
2794 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_join (thr_handle, status), result),
2796 # elif defined (ACE_HAS_WTHREADS)
2797 ACE_THR_FUNC_RETURN local_status = 0;
2799 // Make sure that status is non-NULL.
2801 status = &local_status;
2803 if (::WaitForSingleObject (thr_handle, INFINITE) == WAIT_OBJECT_0
2804 && ::GetExitCodeThread (thr_handle, status) != FALSE)
2806 ::CloseHandle (thr_handle);
2809 ACE_FAIL_RETURN (-1);
2812 ACE_UNUSED_ARG (thr_handle);
2813 ACE_UNUSED_ARG (status);
2814 ACE_NOTSUP_RETURN (-1);
2815 # endif /* ACE_HAS_STHREADS */
2817 ACE_UNUSED_ARG (thr_handle);
2818 ACE_UNUSED_ARG (status);
2819 ACE_NOTSUP_RETURN (-1);
2820 #endif /* ACE_HAS_THREADS */
2824 ACE_OS::thr_join (ACE_thread_t waiter_id,
2825 ACE_thread_t *thr_id,
2826 ACE_THR_FUNC_RETURN *status)
2828 ACE_OS_TRACE ("ACE_OS::thr_join");
2829 #if defined (ACE_HAS_THREADS)
2830 # if defined (ACE_HAS_STHREADS)
2832 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_join (waiter_id, thr_id, status), result),
2834 # elif defined (ACE_HAS_PTHREADS)
2835 ACE_UNUSED_ARG (thr_id);
2837 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_join (waiter_id, status), result),
2839 # elif defined (ACE_HAS_WTHREADS)
2840 ACE_UNUSED_ARG (waiter_id);
2841 ACE_UNUSED_ARG (thr_id);
2842 ACE_UNUSED_ARG (status);
2844 // This could be implemented if the DLL-Main function or the
2845 // task exit base class some log the threads which have exited
2846 ACE_NOTSUP_RETURN (-1);
2847 # endif /* ACE_HAS_STHREADS */
2849 ACE_UNUSED_ARG (waiter_id);
2850 ACE_UNUSED_ARG (thr_id);
2851 ACE_UNUSED_ARG (status);
2852 ACE_NOTSUP_RETURN (-1);
2853 #endif /* ACE_HAS_THREADS */
2855 #endif /* !VXWORKS */
2858 ACE_OS::thr_kill (ACE_thread_t thr_id, int signum)
2860 ACE_OS_TRACE ("ACE_OS::thr_kill");
2861 #if defined (ACE_HAS_THREADS)
2862 # if defined (ACE_HAS_PTHREADS)
2863 # if defined (ACE_LACKS_PTHREAD_KILL)
2864 ACE_UNUSED_ARG (signum);
2865 ACE_UNUSED_ARG (thr_id);
2866 ACE_NOTSUP_RETURN (-1);
2869 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_kill (thr_id, signum),
2872 # endif /* ACE_LACKS_PTHREAD_KILL */
2873 # elif defined (ACE_HAS_STHREADS)
2875 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_kill (thr_id, signum),
2878 # elif defined (ACE_HAS_VXTHREADS)
2879 //FUZZ: disable check_for_lack_ACE_OS
2880 ACE_OSCALL_RETURN (::kill (thr_id, signum), int, -1);
2881 //FUZZ: enable check_for_lack_ACE_OS
2883 ACE_UNUSED_ARG (thr_id);
2884 ACE_UNUSED_ARG (signum);
2885 ACE_NOTSUP_RETURN (-1);
2886 # endif /* ACE_HAS_STHREADS */
2888 ACE_UNUSED_ARG (thr_id);
2889 ACE_UNUSED_ARG (signum);
2890 ACE_NOTSUP_RETURN (-1);
2891 #endif /* ACE_HAS_THREADS */
2895 ACE_OS::thr_min_stack (void)
2897 ACE_OS_TRACE ("ACE_OS::thr_min_stack");
2898 #if defined (ACE_HAS_THREADS)
2899 # if defined (ACE_HAS_STHREADS)
2900 # if defined (ACE_HAS_THR_MINSTACK)
2901 // Tandem did some weirdo mangling of STHREAD names...
2902 return ::thr_minstack ();
2904 return ::thr_min_stack ();
2905 # endif /* !ACE_HAS_THR_MINSTACK */
2906 # elif defined (ACE_HAS_PTHREADS)
2907 # if defined (_SC_THREAD_STACK_MIN)
2908 return (size_t) ACE_OS::sysconf (_SC_THREAD_STACK_MIN);
2909 # elif defined (PTHREAD_STACK_MIN)
2910 return PTHREAD_STACK_MIN;
2912 ACE_NOTSUP_RETURN (0);
2913 # endif /* _SC_THREAD_STACK_MIN */
2914 # elif defined (ACE_HAS_WTHREADS)
2915 ACE_NOTSUP_RETURN (0);
2916 # elif defined (ACE_HAS_VXTHREADS)
2920 ACE_thread_t tid = ACE_OS::thr_self ();
2922 ACE_OSCALL (ACE_ADAPT_RETVAL (::taskInfoGet (tid, &taskDesc),
2924 STATUS, -1, status);
2925 return status == OK ? taskDesc.td_stackSize : 0;
2926 # else /* Should not happen... */
2927 ACE_NOTSUP_RETURN (0);
2928 # endif /* ACE_HAS_STHREADS */
2930 ACE_NOTSUP_RETURN (0);
2931 #endif /* ACE_HAS_THREADS */
2934 ACE_INLINE ACE_thread_t
2935 ACE_OS::thr_self (void)
2937 // ACE_OS_TRACE ("ACE_OS::thr_self");
2938 #if defined (ACE_HAS_THREADS)
2939 # if defined (ACE_HAS_PTHREADS)
2940 // Note, don't use "::" here since the following call is often a macro.
2941 return pthread_self ();
2942 # elif defined (ACE_HAS_STHREADS)
2943 ACE_OSCALL_RETURN (::thr_self (), int, -1);
2944 # elif defined (ACE_HAS_WTHREADS)
2945 return ::GetCurrentThreadId ();
2946 # elif defined (ACE_HAS_VXTHREADS)
2947 return ::taskIdSelf ();
2948 # endif /* ACE_HAS_STHREADS */
2950 return 1; // Might as well make it the first thread ;-)
2951 #endif /* ACE_HAS_THREADS */
2954 ACE_INLINE const char*
2955 ACE_OS::thr_name (void)
2957 #if defined (ACE_HAS_THREADS)
2958 #if defined (ACE_HAS_VXTHREADS)
2959 return ::taskName (ACE_OS::thr_self ());
2961 ACE_NOTSUP_RETURN (0);
2964 ACE_NOTSUP_RETURN (0);
2969 ACE_OS::thr_self (ACE_hthread_t &self)
2971 ACE_OS_TRACE ("ACE_OS::thr_self");
2972 #if defined (ACE_HAS_THREADS)
2973 # if defined (ACE_HAS_PTHREADS)
2974 // Note, don't use "::" here since the following call is often a macro.
2975 self = pthread_self ();
2976 # elif defined (ACE_HAS_THREAD_SELF)
2977 self = ::thread_self ();
2978 # elif defined (ACE_HAS_STHREADS)
2979 self = ::thr_self ();
2980 # elif defined (ACE_HAS_WTHREADS)
2981 self = ::GetCurrentThread ();
2982 # elif defined (ACE_HAS_VXTHREADS)
2983 self = ::taskIdSelf ();
2984 # endif /* ACE_HAS_STHREADS */
2986 self = 1; // Might as well make it the main thread ;-)
2987 #endif /* ACE_HAS_THREADS */
2991 ACE_OS::thr_setcancelstate (int new_state, int *old_state)
2993 ACE_OS_TRACE ("ACE_OS::thr_setcancelstate");
2994 #if defined (ACE_HAS_THREADS)
2995 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
2997 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setcancelstate (new_state,
3001 # elif defined (ACE_HAS_STHREADS)
3002 ACE_UNUSED_ARG (new_state);
3003 ACE_UNUSED_ARG (old_state);
3004 ACE_NOTSUP_RETURN (-1);
3005 # elif defined (ACE_HAS_WTHREADS)
3006 ACE_UNUSED_ARG (new_state);
3007 ACE_UNUSED_ARG (old_state);
3008 ACE_NOTSUP_RETURN (-1);
3009 # else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
3010 ACE_UNUSED_ARG (new_state);
3011 ACE_UNUSED_ARG (old_state);
3012 ACE_NOTSUP_RETURN (-1);
3013 # endif /* ACE_HAS_PTHREADS */
3015 ACE_UNUSED_ARG (new_state);
3016 ACE_UNUSED_ARG (old_state);
3017 ACE_NOTSUP_RETURN (-1);
3018 #endif /* ACE_HAS_THREADS */
3022 ACE_OS::thr_setcanceltype (int new_type, int *old_type)
3024 ACE_OS_TRACE ("ACE_OS::thr_setcanceltype");
3025 #if defined (ACE_HAS_THREADS)
3026 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
3028 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setcanceltype (new_type,
3032 # else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
3033 ACE_UNUSED_ARG (new_type);
3034 ACE_UNUSED_ARG (old_type);
3035 ACE_NOTSUP_RETURN (-1);
3036 # endif /* ACE_HAS_PTHREADS */
3038 ACE_UNUSED_ARG (new_type);
3039 ACE_UNUSED_ARG (old_type);
3040 ACE_NOTSUP_RETURN (-1);
3041 #endif /* ACE_HAS_THREADS */
3045 ACE_OS::thr_setconcurrency (int hint)
3047 ACE_OS_TRACE ("ACE_OS::thr_setconcurrency");
3048 #if defined (ACE_HAS_THREADS)
3049 # if defined (ACE_HAS_STHREADS)
3051 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setconcurrency (hint),
3054 # elif defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_PTHREAD_SETCONCURRENCY)
3056 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setconcurrency (hint),
3060 ACE_UNUSED_ARG (hint);
3061 ACE_NOTSUP_RETURN (-1);
3062 # endif /* ACE_HAS_STHREADS */
3064 ACE_UNUSED_ARG (hint);
3065 ACE_NOTSUP_RETURN (-1);
3066 #endif /* ACE_HAS_THREADS */
3070 ACE_OS::thr_setprio (ACE_hthread_t ht_id, int priority, int policy)
3072 ACE_OS_TRACE ("ACE_OS::thr_setprio");
3073 ACE_UNUSED_ARG (policy);
3074 #if defined (ACE_HAS_THREADS)
3075 # if (defined (ACE_HAS_PTHREADS) && \
3076 (!defined (ACE_LACKS_SETSCHED) || defined (ACE_HAS_PTHREAD_SCHEDPARAM)))
3079 struct sched_param param;
3080 ACE_OS::memset ((void *) ¶m, 0, sizeof param);
3082 // If <policy> is -1, we don't want to use it for
3083 // pthread_setschedparam(). Instead, obtain policy from
3084 // pthread_getschedparam().
3087 ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_getschedparam (ht_id, &policy, ¶m),
3094 param.sched_priority = priority;
3096 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setschedparam (ht_id,
3101 # elif defined (ACE_HAS_STHREADS)
3103 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setprio (ht_id, priority),
3106 # elif defined (ACE_HAS_WTHREADS)
3107 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::SetThreadPriority (ht_id, priority),
3110 # elif defined (ACE_HAS_VXTHREADS)
3111 ACE_OSCALL_RETURN (::taskPrioritySet (ht_id, priority), int, -1);
3113 // For example, platforms that support Pthreads but LACK_SETSCHED.
3114 ACE_UNUSED_ARG (ht_id);
3115 ACE_UNUSED_ARG (priority);
3116 ACE_NOTSUP_RETURN (-1);
3117 # endif /* ACE_HAS_STHREADS */
3119 ACE_UNUSED_ARG (ht_id);
3120 ACE_UNUSED_ARG (priority);
3121 ACE_NOTSUP_RETURN (-1);
3122 #endif /* ACE_HAS_THREADS */
3126 ACE_OS::thr_sigsetmask (int how,
3127 const sigset_t *nsm,
3130 ACE_OS_TRACE ("ACE_OS::thr_sigsetmask");
3131 #if defined (ACE_HAS_THREADS)
3132 # if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
3133 // DCE threads and Solaris 2.4 have no such function.
3134 ACE_UNUSED_ARG (osm);
3135 ACE_UNUSED_ARG (nsm);
3136 ACE_UNUSED_ARG (how);
3138 ACE_NOTSUP_RETURN (-1);
3139 # elif defined (ACE_HAS_SIGTHREADMASK)
3141 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigthreadmask (how, nsm, osm),
3143 # elif defined (ACE_HAS_STHREADS)
3145 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_sigsetmask (how, nsm, osm),
3148 # elif defined (ACE_HAS_PTHREADS)
3149 # if !defined (ACE_LACKS_PTHREAD_SIGMASK)
3151 //FUZZ: disable check_for_lack_ACE_OS
3152 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm),
3154 //FUZZ: enable check_for_lack_ACE_OS
3155 # endif /* !ACE_LACKS_PTHREAD_SIGMASK */
3158 /* Don't know if any platform actually needs this... */
3159 // as far as I can tell, this is now pthread_sigaction() -- jwr
3161 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_sigaction (how, nsm, osm),
3165 # elif defined (ACE_HAS_WTHREADS)
3166 ACE_UNUSED_ARG (osm);
3167 ACE_UNUSED_ARG (nsm);
3168 ACE_UNUSED_ARG (how);
3170 ACE_NOTSUP_RETURN (-1);
3171 # elif defined (ACE_VXWORKS)
3179 old_mask = ::sigsetmask (*nsm);
3180 // create a new mask: the following assumes that sigset_t is 4 bytes,
3181 // which it is on VxWorks 5.2, so bit operations are done simply . . .
3182 ::sigsetmask (how == SIG_BLOCK ? (old_mask |= *nsm) : (old_mask &= ~*nsm));
3188 old_mask = ::sigsetmask (*nsm);
3197 # else /* Should not happen. */
3198 ACE_UNUSED_ARG (how);
3199 ACE_UNUSED_ARG (nsm);
3200 ACE_UNUSED_ARG (osm);
3201 ACE_NOTSUP_RETURN (-1);
3202 # endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
3204 ACE_UNUSED_ARG (how);
3205 ACE_UNUSED_ARG (nsm);
3206 ACE_UNUSED_ARG (osm);
3207 ACE_NOTSUP_RETURN (-1);
3208 #endif /* ACE_HAS_THREADS */
3212 ACE_OS::thr_suspend (ACE_hthread_t target_thread)
3214 ACE_OS_TRACE ("ACE_OS::thr_suspend");
3215 #if defined (ACE_HAS_THREADS)
3216 # if defined (ACE_HAS_STHREADS)
3218 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_suspend (target_thread), result), int, -1);
3219 # elif defined (ACE_HAS_PTHREADS)
3220 # if defined (ACE_HAS_PTHREAD_SUSPEND)
3222 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_suspend (target_thread),
3225 # elif defined (ACE_HAS_PTHREAD_SUSPEND_NP)
3227 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_suspend_np (target_thread),
3231 ACE_UNUSED_ARG (target_thread);
3232 ACE_NOTSUP_RETURN (-1);
3233 # endif /* ACE_HAS_PTHREAD_SUSPEND */
3234 # elif defined (ACE_HAS_WTHREADS)
3235 if (::SuspendThread (target_thread) != ACE_SYSCALL_FAILED)
3238 ACE_FAIL_RETURN (-1);
3240 # elif defined (ACE_HAS_VXTHREADS)
3241 ACE_OSCALL_RETURN (::taskSuspend (target_thread), int, -1);
3242 # endif /* ACE_HAS_STHREADS */
3244 ACE_UNUSED_ARG (target_thread);
3245 ACE_NOTSUP_RETURN (-1);
3246 #endif /* ACE_HAS_THREADS */
3250 ACE_OS::thr_testcancel (void)
3252 ACE_OS_TRACE ("ACE_OS::thr_testcancel");
3253 #if defined (ACE_HAS_THREADS)
3254 # if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
3255 pthread_testcancel ();
3256 # elif defined (ACE_HAS_STHREADS)
3257 # elif defined (ACE_HAS_WTHREADS)
3258 # elif defined (ACE_HAS_VXTHREADS)
3260 // no-op: can't use ACE_NOTSUP_RETURN because there is no return value
3261 # endif /* ACE_HAS_PTHREADS */
3263 #endif /* ACE_HAS_THREADS */
3267 ACE_OS::thr_yield (void)
3269 ACE_OS_TRACE ("ACE_OS::thr_yield");
3270 #if defined (ACE_HAS_THREADS)
3271 # if defined (ACE_HAS_PTHREADS)
3273 # elif defined (ACE_HAS_STHREADS)
3275 # elif defined (ACE_HAS_WTHREADS)
3277 # elif defined (ACE_HAS_VXTHREADS)
3278 // An argument of 0 to ::taskDelay doesn't appear to yield the
3280 // Now, it does seem to work. The context_switch_time test
3281 // works fine with task_delay set to 0.
3283 # endif /* ACE_HAS_STHREADS */
3286 #endif /* ACE_HAS_THREADS */
3290 ACE_OS::thread_mutex_destroy (ACE_thread_mutex_t *m)
3292 ACE_OS_TRACE ("ACE_OS::thread_mutex_destroy");
3293 #if defined (ACE_HAS_THREADS)
3294 # if defined (ACE_HAS_WTHREADS)
3295 ::DeleteCriticalSection (m);
3298 return ACE_OS::mutex_destroy (m);
3299 # endif /* ACE_HAS_WTHREADS */
3302 ACE_NOTSUP_RETURN (-1);
3304 #endif /* ACE_HAS_THREADS */
3308 ACE_OS::thread_mutex_init (ACE_thread_mutex_t *m,
3311 ACE_mutexattr_t *arg)
3313 // ACE_OS_TRACE ("ACE_OS::thread_mutex_init");
3314 #if defined (ACE_HAS_THREADS)
3315 # if defined (ACE_HAS_WTHREADS)
3316 ACE_UNUSED_ARG (lock_type);
3317 ACE_UNUSED_ARG (name);
3318 ACE_UNUSED_ARG (arg);
3322 ::InitializeCriticalSection (m);
3324 ACE_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3331 # elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS)
3332 // Force the use of USYNC_THREAD!
3333 return ACE_OS::mutex_init (m, USYNC_THREAD, name, arg, 0, lock_type);
3334 # elif defined (ACE_HAS_VXTHREADS)
3335 return mutex_init (m, lock_type, name, arg);
3337 # endif /* ACE_HAS_STHREADS || ACE_HAS_PTHREADS */
3341 ACE_UNUSED_ARG (lock_type);
3342 ACE_UNUSED_ARG (name);
3343 ACE_UNUSED_ARG (arg);
3344 ACE_NOTSUP_RETURN (-1);
3346 #endif /* ACE_HAS_THREADS */
3349 #if defined (ACE_HAS_WCHAR)
3351 ACE_OS::thread_mutex_init (ACE_thread_mutex_t *m,
3353 const wchar_t *name,
3354 ACE_mutexattr_t *arg)
3356 // ACE_OS_TRACE ("ACE_OS::thread_mutex_init");
3357 #if defined (ACE_HAS_THREADS)
3358 # if defined (ACE_HAS_WTHREADS)
3359 ACE_UNUSED_ARG (lock_type);
3360 ACE_UNUSED_ARG (name);
3361 ACE_UNUSED_ARG (arg);
3365 ::InitializeCriticalSection (m);
3367 ACE_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3374 # elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS)
3375 // Force the use of USYNC_THREAD!
3376 return ACE_OS::mutex_init (m, USYNC_THREAD, name, arg, 0, lock_type);
3377 # elif defined (ACE_HAS_VXTHREADS)
3378 return mutex_init (m, lock_type, name, arg);
3379 # endif /* ACE_HAS_STHREADS || ACE_HAS_PTHREADS */
3382 ACE_UNUSED_ARG (lock_type);
3383 ACE_UNUSED_ARG (name);
3384 ACE_UNUSED_ARG (arg);
3385 ACE_NOTSUP_RETURN (-1);
3387 #endif /* ACE_HAS_THREADS */
3389 #endif /* ACE_HAS_WCHAR */
3392 ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m)
3394 // ACE_OS_TRACE ("ACE_OS::thread_mutex_lock");
3395 #if defined (ACE_HAS_THREADS)
3396 # if defined (ACE_HAS_WTHREADS)
3397 ::EnterCriticalSection (m);
3400 return ACE_OS::mutex_lock (m);
3401 # endif /* ACE_HAS_WTHREADS */
3404 ACE_NOTSUP_RETURN (-1);
3405 #endif /* ACE_HAS_THREADS */
3409 ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m,
3410 const ACE_Time_Value &timeout)
3412 // ACE_OS_TRACE ("ACE_OS::thread_mutex_lock");
3414 // For all platforms, except MS Windows, this method is equivalent
3415 // to calling ACE_OS::mutex_lock() since ACE_thread_mutex_t and
3416 // ACE_mutex_t are the same type. However, those typedefs evaluate
3417 // to different types on MS Windows. The "thread mutex"
3418 // implementation in ACE for MS Windows cannot readily support
3419 // timeouts due to a lack of timeout features for this type of MS
3420 // Windows synchronization mechanism.
3422 #if defined (ACE_HAS_THREADS) && !defined (ACE_HAS_WTHREADS)
3423 return ACE_OS::mutex_lock (m, timeout);
3426 ACE_UNUSED_ARG (timeout);
3427 ACE_NOTSUP_RETURN (-1);
3428 #endif /* ACE_HAS_THREADS */
3432 ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m,
3433 const ACE_Time_Value *timeout)
3436 ? ACE_OS::thread_mutex_lock (m)
3437 : ACE_OS::thread_mutex_lock (m, *timeout);
3441 ACE_OS::thread_mutex_trylock (ACE_thread_mutex_t *m)
3443 ACE_OS_TRACE ("ACE_OS::thread_mutex_trylock");
3445 #if defined (ACE_HAS_THREADS)
3446 # if defined (ACE_HAS_WTHREADS)
3447 # if defined (ACE_HAS_WIN32_TRYLOCK)
3448 BOOL result = ::TryEnterCriticalSection (m);
3458 ACE_NOTSUP_RETURN (-1);
3459 # endif /* ACE_HAS_WIN32_TRYLOCK */
3460 # elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS) || defined (ACE_VXWORKS)
3461 return ACE_OS::mutex_trylock (m);
3462 #endif /* Threads variety case */
3466 ACE_NOTSUP_RETURN (-1);
3467 #endif /* ACE_HAS_THREADS */
3471 ACE_OS::thread_mutex_unlock (ACE_thread_mutex_t *m)
3473 ACE_OS_TRACE ("ACE_OS::thread_mutex_unlock");
3474 #if defined (ACE_HAS_THREADS)
3475 # if defined (ACE_HAS_WTHREADS)
3476 ::LeaveCriticalSection (m);
3479 return ACE_OS::mutex_unlock (m);
3480 # endif /* ACE_HAS_WTHREADS */
3483 ACE_NOTSUP_RETURN (-1);
3484 #endif /* ACE_HAS_THREADS */
3487 /*****************************************************************************/
3489 # if defined (ACE_IS_SPLITTING)
3490 # define ACE_SPECIAL_INLINE
3492 # define ACE_SPECIAL_INLINE ACE_INLINE
3493 //# define ACE_SPECIAL_INLINE inline
3496 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
3500 ACE_OS_Thread_Mutex_Guard::acquire (void)
3502 return owner_ = ACE_OS::thread_mutex_lock (&lock_);
3507 ACE_OS_Thread_Mutex_Guard::release (void)
3514 return ACE_OS::thread_mutex_unlock (&lock_);
3519 ACE_OS_Thread_Mutex_Guard::ACE_OS_Thread_Mutex_Guard (ACE_thread_mutex_t &m)
3520 : lock_ (m), owner_ (-1)
3522 if (!ACE_OS_Object_Manager::starting_up ())
3527 ACE_OS_Thread_Mutex_Guard::~ACE_OS_Thread_Mutex_Guard ()
3532 /*****************************************************************************/
3536 ACE_OS_Recursive_Thread_Mutex_Guard::acquire (void)
3538 return owner_ = ACE_OS::recursive_mutex_lock (&lock_);
3543 ACE_OS_Recursive_Thread_Mutex_Guard::release (void)
3550 return ACE_OS::recursive_mutex_unlock (&lock_);
3555 ACE_OS_Recursive_Thread_Mutex_Guard::ACE_OS_Recursive_Thread_Mutex_Guard (
3556 ACE_recursive_thread_mutex_t &m)
3560 if (!ACE_OS_Object_Manager::starting_up ())
3565 ACE_OS_Recursive_Thread_Mutex_Guard::~ACE_OS_Recursive_Thread_Mutex_Guard ()
3570 #endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */
3573 /*****************************************************************************/
3576 ACE_Thread_ID::ACE_Thread_ID (ACE_thread_t thread_id,
3577 ACE_hthread_t thread_handle)
3578 : thread_id_ (thread_id),
3579 thread_handle_ (thread_handle)
3584 ACE_Thread_ID::ACE_Thread_ID (const ACE_Thread_ID &id)
3585 : thread_id_ (id.thread_id_),
3586 thread_handle_ (id.thread_handle_)
3591 ACE_Thread_ID::ACE_Thread_ID (void)
3592 : thread_id_ (ACE_OS::thr_self ())
3594 ACE_OS::thr_self (thread_handle_);
3599 ACE_Thread_ID::id (void) const
3601 return this->thread_id_;
3605 ACE_Thread_ID::id (ACE_thread_t thread_id)
3607 this->thread_id_ = thread_id;
3610 ACE_INLINE ACE_hthread_t
3611 ACE_Thread_ID::handle (void) const
3613 return this->thread_handle_;
3617 ACE_Thread_ID::handle (ACE_hthread_t thread_handle)
3619 this->thread_handle_ = thread_handle;
3623 ACE_Thread_ID::operator== (const ACE_Thread_ID &rhs) const
3626 ACE_OS::thr_cmp (this->thread_handle_, rhs.thread_handle_)
3627 && ACE_OS::thr_equal (this->thread_id_, rhs.thread_id_);
3631 ACE_Thread_ID::operator!= (const ACE_Thread_ID &rhs) const
3633 return !(*this == rhs);
3636 ACE_END_VERSIONED_NAMESPACE_DECL