Initial Patch of Auction House bot rev. 135
[auctionmangos.git] / dep / ACE_wrappers / ace / OS_NS_Thread.inl
blob14a32196e8dba22ba15cb996a8027a311718eb2f
1 // -*- C++ -*-
2 //
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)
31 ACE_INLINE long
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)
43 ACE_INLINE
44 void **&
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);
50 #    else
51   // Uh oh.
52   ACE_NOTSUP_RETURN (0);
53 #    endif /* ACE_HAS_VXTHREADS */
55 #  endif /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
57 ACE_INLINE
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];
65 ACE_INLINE
66 void
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;
74 ACE_INLINE
75 void *&
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)
85       {
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 :-)
91         void **tss_base_p =
92           reinterpret_cast<void **> (taskIdCurrent->ACE_VXWORKS_SPARE);
93         for (u_int i = 0; i < ACE_TSS_THREAD_KEYS_MAX; ++i, ++tss_base_p)
94           {
95             *tss_base_p = 0;
96           }
97       }
98 #    endif /* ACE_HAS_VXTHREADS */
100   return tss_base ()[key_index];
103 #endif /* ACE_HAS_TSS_EMULATION */
105 /*****************************************************************************/
107 ACE_INLINE int
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);
114 # else
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.
120   return t1 == t2;
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.
130 ACE_INLINE int
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)
139   attributes.type = 0;
141 #   endif /* ACE_HAS_PTHREADS vs. ACE_HAS_STHREADS */
142   return 0;
143 # else
144   ACE_UNUSED_ARG (attributes);
145   return 0;
146 # endif /* ACE_HAS_THREADS  */
149 ACE_INLINE int
150 ACE_OS::condattr_init (ACE_condattr_t &attributes,
151                        int type)
153   ACE_UNUSED_ARG (type);
154 # if defined (ACE_HAS_THREADS)
155 #   if defined (ACE_HAS_PTHREADS)
156   int result = -1;
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.
162        */
163       ACE_OS::memset (&attributes, 0, sizeof (attributes));
164 #   endif
165   if (
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),
169                            result) == 0
170 #       endif /* _POSIX_THREAD_PROCESS_SHARED && ! ACE_LACKS_CONDATTR_PSHARED */
171       )
172      result = 0;
173   else
174      result = -1;       // ACE_ADAPT_RETVAL used it for intermediate status
176   return result;
177 #   elif defined (ACE_HAS_STHREADS)
178   attributes.type = type;
180   return 0;
182 #   else
183   ACE_UNUSED_ARG (attributes);
184   ACE_UNUSED_ARG (type);
185   ACE_NOTSUP_RETURN (-1);
187 #   endif /* ACE_HAS_PTHREADS vs. ACE_HAS_STHREADS */
189 # else
190   ACE_UNUSED_ARG (attributes);
191   ACE_UNUSED_ARG (type);
192   ACE_NOTSUP_RETURN (-1);
193 # endif /* ACE_HAS_THREADS */
196 ACE_INLINE int
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)
202   int result;
203   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_broadcast (cv),
204                                        result),
205                      int, -1);
206 #   elif defined (ACE_HAS_STHREADS)
207   int result;
208   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_broadcast (cv),
209                                        result),
210                      int, -1);
211 #   endif /* ACE_HAS_STHREADS */
212 # else
213   ACE_UNUSED_ARG (cv);
214   ACE_NOTSUP_RETURN (-1);
215 # endif /* ACE_HAS_THREADS */
218 ACE_INLINE int
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)
224   int result;
225   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_destroy (cv), result), int, -1);
226 #   elif defined (ACE_HAS_STHREADS)
227   int result;
228   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_destroy (cv), result), int, -1);
229 #   endif /* ACE_HAS_STHREADS */
230 # else
231   ACE_UNUSED_ARG (cv);
232   ACE_NOTSUP_RETURN (-1);
233 # endif /* ACE_HAS_THREADS */
236 ACE_INLINE int
237 ACE_OS::cond_init (ACE_cond_t *cv,
238                    ACE_condattr_t &attributes,
239                    const char *name,
240                    void *arg)
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)
247   int result = -1;
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.
255    */
256   ACE_OS::memset (cv, 0, sizeof (*cv));
257 #     endif
259   if (ACE_ADAPT_RETVAL (pthread_cond_init (cv, &attributes), result) == 0)
260      result = 0;
261   else
262      result = -1;       // ACE_ADAPT_RETVAL used it for intermediate status
264   return result;
265 #   elif defined (ACE_HAS_STHREADS)
266   int result;
267   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_init (cv,
268                                                     attributes.type,
269                                                     arg),
270                                        result),
271                      int, -1);
272 #   endif /* ACE_HAS_PTHREADS vs. ACE_HAS_STHREADS */
273 # else
274   ACE_UNUSED_ARG (cv);
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)
283 ACE_INLINE int
284 ACE_OS::cond_init (ACE_cond_t *cv,
285                    ACE_condattr_t &attributes,
286                    const wchar_t *name,
287                    void *arg)
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)
294 ACE_INLINE int
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 */
301 ACE_INLINE int
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)
307   int result;
308   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_signal (cv), result),
309                      int, -1);
310 #   elif defined (ACE_HAS_STHREADS)
311   int result;
312   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_signal (cv), result), int, -1);
313 #   endif /* ACE_HAS_STHREADS */
314 # else
315   ACE_UNUSED_ARG (cv);
316   ACE_NOTSUP_RETURN (-1);
317 # endif /* ACE_HAS_THREADS */
320 ACE_INLINE int
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)
327   int result;
328   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cond_wait (cv, external_mutex), result),
329                      int, -1);
330 #   elif defined (ACE_HAS_STHREADS)
331   int result;
332   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_wait (cv, external_mutex), result),
333                      int, -1);
334 #   endif /* ACE_HAS_PTHREADS */
335 # else
336   ACE_UNUSED_ARG (cv);
337   ACE_UNUSED_ARG (external_mutex);
338   ACE_NOTSUP_RETURN (-1);
339 # endif /* ACE_HAS_THREADS */
342 ACE_INLINE int
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)
349   int result;
350   timespec_t ts;
352   if (timeout != 0)
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),
361                                 result),
362               int, -1, result);
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)
365   if (result == -1 &&
366       (errno == ETIMEDOUT || errno == EAGAIN))
367     errno = ETIME;
369 #   elif defined (ACE_HAS_STHREADS)
370   ACE_OSCALL (ACE_ADAPT_RETVAL (timeout == 0
371                                 ? ::cond_wait (cv, external_mutex)
372                                 : ::cond_timedwait (cv,
373                                                     external_mutex,
374                                                     (timestruc_t*)&ts),
375                                 result),
376               int, -1, result);
377 #   endif /* ACE_HAS_STHREADS */
378   if (timeout != 0)
379     timeout->set (ts); // Update the time value before returning.
381   return result;
382 # else
383   ACE_UNUSED_ARG (cv);
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 */
391 ACE_INLINE int
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)
399 ACE_INLINE int
400 ACE_OS::event_init (ACE_event_t *event,
401                     int manual_reset,
402                     int initial_state,
403                     int type,
404                     const wchar_t *name,
405                     void *arg,
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),
415   manual_reset,
416   initial_state,
417   name);
418   if (*event == 0)
419     ACE_FAIL_RETURN (-1);
421   return 0;
422 #else  /* ACE_WIN32 */
423   return ACE_OS::event_init (event,
424                              manual_reset,
425                              initial_state,
426                              type,
427                              ACE_Wide_To_Ascii (name).char_rep (),
428                              arg,
429                              sa);
430 #endif /* ACE_WIN32 */
432 #endif /* ACE_HAS_WCHAR */
434 ACE_INLINE long
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)),
440                      long, -1);
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.
456 ACE_INLINE int
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.
470   //
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
485   // with it.
486   //
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;
496   while (
497 #      if !defined (ACE_HAS_WINCE)
498          m->LockCount > 0 && m->RecursionCount > 1
499 #      else
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
505 #        else
506          m->LockCount > 1
507 #        endif /* UNDER_CE < 500 */
508 #      endif /* ACE_HAS_WINCE */
509          )
510     {
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
513       // the state.
514       if (ACE_OS::recursive_mutex_unlock (m) == -1)
515         return -1;
516       ++state.relock_count_;
517     }
518 #    else /* not ACE_WIN32 */
519     // prevent warnings for unused variables
520     ACE_UNUSED_ARG (state);
521     ACE_UNUSED_ARG (m);
522 #    endif /* ACE_WIN32 */
523   return 0;
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)
536     return -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)
541     {
542       ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
543       errno = EINVAL;
544       return -1;
545     }
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)
552     {
553       // Save/restore errno.
554       ACE_Errno_Guard error (errno);
555       ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
556       return -1;
557     }
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
562   // caller.
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;
567   return 0;
568 #  endif /* ACE_HAS_RECURSIVE_MUTEXES */
569 #else
570   ACE_UNUSED_ARG (m);
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).
581 ACE_INLINE void
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)
595     {
596       ACE_OS::recursive_mutex_lock (m);
597       --state.relock_count_;
598     }
599   return;
600 #    else /* not ACE_WIN32 */
601     // prevent warnings for unused variables
602     ACE_UNUSED_ARG (state);
603     ACE_UNUSED_ARG (m);
605 #    endif /* ACE_WIN32 */
606 #  else
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_);
621   return;
622 #  endif /* ACE_HAS_RECURSIVE_MUTEXES */
623 #else
624   ACE_UNUSED_ARG (m);
625   ACE_UNUSED_ARG (state);
626   return;
627 #endif /* ACE_HAS_THREADS */
630 ACE_INLINE int
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);
636 #else
637   if (ACE_OS::thread_mutex_destroy (&m->nesting_mutex_) == -1)
638     return -1;
639   else if (ACE_OS::cond_destroy (&m->lock_available_) == -1)
640     return -1;
641   else
642     return 0;
643 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
644 #else
645   ACE_UNUSED_ARG (m);
646   ACE_NOTSUP_RETURN (-1);
647 #endif /* ACE_HAS_THREADS */
650 ACE_INLINE int
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)
656   ACE_UNUSED_ARG (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);
661 #    else
662   return ACE_OS::thread_mutex_init (m, 0, name, arg);
663 #    endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
664 #  else
665   if (ACE_OS::thread_mutex_init (&m->nesting_mutex_, 0, name, arg) == -1)
666     return -1;
667   else if (ACE_OS::cond_init (&m->lock_available_,
668                               (short) USYNC_THREAD,
669                               name,
670                               0) == -1)
671     return -1;
672   else
673     {
674       m->nesting_level_ = 0;
675       m->owner_id_ = ACE_OS::NULL_thread;
676       return 0;
677     }
678 #  endif /* ACE_HAS_RECURSIVE_MUTEXES */
679 #else
680   ACE_UNUSED_ARG (m);
681   ACE_UNUSED_ARG (name);
682   ACE_UNUSED_ARG (arg);
683   ACE_NOTSUP_RETURN (-1);
684 #endif /* ACE_HAS_THREADS */
687 ACE_INLINE int
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);
693 #else
694   ACE_thread_t const t_id = ACE_OS::thr_self ();
695   int result = 0;
697   // Acquire the guard.
698   if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
699     result = -1;
700   else
701   {
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)
705       m->owner_id_ = t_id;
706       // If we already own the lock, then increment the nesting level
707       // and return.
708     else if (ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
709     {
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_,
714                             &m->nesting_mutex_);
716           // At this point the nesting_mutex_ is held...
717       m->owner_id_ = t_id;
718     }
720     // At this point, we can safely increment the nesting_level_ no
721     // matter how we got here!
722     ++m->nesting_level_;
723   }
725   {
726     // Save/restore errno.
727     ACE_Errno_Guard error (errno);
728     ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
729   }
730   return result;
731 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
732 #else
733   ACE_UNUSED_ARG (m);
734   ACE_NOTSUP_RETURN (-1);
735 #endif /* ACE_HAS_THREADS */
738 ACE_INLINE int
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);
745 #else
746   ACE_thread_t t_id = ACE_OS::thr_self ();
747   int result = 0;
749   // Try to acquire the guard.
750   if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_, timeout) == -1)
751     result = -1;
752   else
753     {
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)
757         m->owner_id_ = t_id;
758       // If we already own the lock, then increment the nesting level
759       // and return.
760       else if (ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
761         {
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)
765             {
766               result = ACE_OS::cond_timedwait (&m->lock_available_,
767                                                &m->nesting_mutex_,
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
772               if (result == -1)
773                 {
774                   // Save/restore errno.
775                   ACE_Errno_Guard error (errno);
776                   ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
778                   return result;
779                 }
780             }
782           // At this point the nesting_mutex_ is held...
783           m->owner_id_ = t_id;
784         }
786       // At this point, we can safely increment the nesting_level_ no
787       // matter how we got here!
788       m->nesting_level_++;
790       // Save/restore errno.
791       ACE_Errno_Guard error (errno);
792       ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
793     }
794   return result;
795 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
796 #else
797   ACE_UNUSED_ARG (m);
798   ACE_UNUSED_ARG (timeout);
799   ACE_NOTSUP_RETURN (-1);
800 #endif /* ACE_HAS_THREADS */
803 ACE_INLINE int
804 ACE_OS::recursive_mutex_lock (ACE_recursive_thread_mutex_t *m,
805                               const ACE_Time_Value *timeout)
807   return timeout == 0
808     ? ACE_OS::recursive_mutex_lock (m)
809     : ACE_OS::recursive_mutex_lock (m, *timeout);
812 ACE_INLINE int
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);
818 #else
819   ACE_thread_t t_id = ACE_OS::thr_self ();
820   int result = 0;
822   // Acquire the guard.
823   if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
824     result = -1;
825   else
826   {
827       // If there's no contention, just grab the lock immediately.
828     if (m->nesting_level_ == 0)
829     {
830       m->owner_id_ = t_id;
831       m->nesting_level_ = 1;
832     }
833       // If we already own the lock, then increment the nesting level
834       // and proceed.
835     else if (ACE_OS::thr_equal (t_id, m->owner_id_))
836       m->nesting_level_++;
837     else
838     {
839       errno = EBUSY;
840       result = -1;
841     }
842   }
844   {
845     // Save/restore errno.
846     ACE_Errno_Guard error (errno);
847     ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
848   }
849   return result;
850 #endif /* ACE_HAS_RECURSIVE_MUTEXES */
851 #else
852   ACE_UNUSED_ARG (m);
853   ACE_NOTSUP_RETURN (-1);
854 #endif /* ACE_HAS_THREADS */
857 ACE_INLINE int
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);
863 #  else
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 */
868   int result = 0;
870   if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
871     result = -1;
872   else
873   {
874 #    if !defined (ACE_NDEBUG)
875       if (m->nesting_level_ == 0
876           || ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
878   errno = EINVAL;
879   result = -1;
881       else
882 #    endif /* ACE_NDEBUG */
884   m->nesting_level_--;
885   if (m->nesting_level_ == 0)
886   {
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)
893       result = -1;
894   }
896   }
899     // Save/restore errno.
900   ACE_Errno_Guard error (errno);
901   ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
903   return result;
904 #  endif /* ACE_HAS_RECURSIVE_MUTEXES */
905 #else
906   ACE_UNUSED_ARG (m);
907   ACE_NOTSUP_RETURN (-1);
908 #endif /* ACE_HAS_THREADS */
911 ACE_INLINE int
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)
918   int result;
919   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_rdlock (rw),
920                                        result),
921                      int, -1);
922 #  else /* Solaris */
923   int result;
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 */
930   int result = 0;
931   if (ACE_OS::mutex_lock (&rw->lock_) == -1)
932     result = -1; // -1 means didn't get the mutex.
933   else
934     {
935       // Give preference to writers who are waiting.
936       while (rw->ref_count_ < 0 || rw->num_waiting_writers_ > 0)
937         {
938           rw->num_waiting_readers_++;
939           if (ACE_OS::cond_wait (&rw->waiting_readers_, &rw->lock_) == -1)
940             {
941               result = -2; // -2 means that we need to release the mutex.
942               break;
943             }
944           rw->num_waiting_readers_--;
945         }
946     }
947   if (result == 0)
948     rw->ref_count_++;
949   if (result != -1)
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) */
954   return 0;
955 # endif /* ! ACE_LACKS_RWLOCK_T */
956 #else
957   ACE_UNUSED_ARG (rw);
958   ACE_NOTSUP_RETURN (-1);
959 #endif /* ACE_HAS_THREADS */
962 ACE_INLINE int
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)
969   int result;
970   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_tryrdlock (rw),
971                                        result),
972                      int, -1);
973 #  else /* Solaris */
974   int result;
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. */
978   int result = -1;
980   if (ACE_OS::mutex_lock (&rw->lock_) != -1)
981     {
982       ACE_Errno_Guard error (errno);
984       if (rw->ref_count_ == -1 || rw->num_waiting_writers_ > 0)
985         {
986           error = EBUSY;
987           result = -1;
988         }
989       else
990         {
991           rw->ref_count_++;
992           result = 0;
993         }
995       ACE_OS::mutex_unlock (&rw->lock_);
996     }
997   return result;
998 # endif /* ! ACE_LACKS_RWLOCK_T */
999 #else
1000   ACE_UNUSED_ARG (rw);
1001   ACE_NOTSUP_RETURN (-1);
1002 #endif /* ACE_HAS_THREADS */
1005 ACE_INLINE int
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)
1012   int result;
1013   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_trywrlock (rw),
1014                                        result),
1015                      int, -1);
1016 #  else /* Solaris */
1017   int result;
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. */
1021   int result = -1;
1023   if (ACE_OS::mutex_lock (&rw->lock_) != -1)
1024     {
1025       ACE_Errno_Guard error (errno);
1027       if (rw->ref_count_ != 0)
1028         {
1029           error = EBUSY;
1030           result = -1;
1031         }
1032       else
1033         {
1034           rw->ref_count_ = -1;
1035           result = 0;
1036         }
1038       ACE_OS::mutex_unlock (&rw->lock_);
1039     }
1040   return result;
1041 # endif /* ! ACE_LACKS_RWLOCK_T */
1042 #else
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}
1054 ACE_INLINE int
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.
1062   int result;
1063   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_trywrlock (rw),
1064                                        result),
1065                      int, -1);
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 . . .
1073   int result = 0;
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)
1080     return -1;
1081     // -1 means didn't get the mutex, error
1082   else if (rw->important_writer_)
1083     // an other reader upgrades already
1084     {
1085       result = -1;
1086       errno = EBUSY;
1087     }
1088   else
1089     {
1090       while (rw->ref_count_ > 1) // wait until only I am left
1091         {
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)
1096             {
1097               result = -1;
1098               // we know that we have the lock again, we have this guarantee,
1099               // but something went wrong
1100             }
1101           rw->important_writer_ = 0;
1102           rw->num_waiting_writers_--;
1103         }
1104       if (result == 0)
1105         {
1106           // nothing bad happend
1107           rw->ref_count_ = -1;
1108           // now I am a writer
1109           // everything is O.K.
1110         }
1111     }
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) */
1119   return result;
1121 # endif /* ! ACE_LACKS_RWLOCK_T */
1122 #else
1123   ACE_UNUSED_ARG (rw);
1124   ACE_NOTSUP_RETURN (-1);
1125 #endif /* ACE_HAS_THREADS */
1128 ACE_INLINE int
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)
1135   int result;
1136   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_unlock (rw),
1137                                        result),
1138                      int, -1);
1139 #  else /* Solaris */
1140   int result;
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)
1145     return -1;
1147   if (rw->ref_count_ > 0) // Releasing a reader.
1148     rw->ref_count_--;
1149   else if (rw->ref_count_ == -1) // Releasing a writer.
1150     rw->ref_count_ = 0;
1151   else
1152     {
1153       (void) ACE_OS::mutex_unlock (&rw->lock_);
1154       return -1; // @@ ACE_ASSERT (!"count should not be 0!\n");
1155     }
1157   int result = 0;
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.
1162     {
1163       result = ACE_OS::cond_signal (&rw->waiting_important_writer_);
1164       error = errno;
1165     }
1166   else if (rw->num_waiting_writers_ > 0 && rw->ref_count_ == 0)
1167     // give preference to writers over readers...
1168     {
1169       result = ACE_OS::cond_signal (&rw->waiting_writers_);
1170       error =  errno;
1171     }
1172   else if (rw->num_waiting_readers_ > 0 && rw->num_waiting_writers_ == 0)
1173     {
1174       result = ACE_OS::cond_broadcast (&rw->waiting_readers_);
1175       error = errno;
1176     }
1178   (void) ACE_OS::mutex_unlock (&rw->lock_);
1179   return result;
1180 # endif /* ! ace_lacks_rwlock_t */
1181 #else
1182   ACE_UNUSED_ARG (rw);
1183   ACE_NOTSUP_RETURN (-1);
1184 #endif /* ace_has_threads */
1187 ACE_INLINE int
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)
1194   int result;
1195   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_wrlock (rw),
1196                                        result),
1197                      int, -1);
1198 #  else /* Solaris */
1199   int result;
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) */
1206   int result = 0;
1208   if (ACE_OS::mutex_lock (&rw->lock_) == -1)
1209     result = -1; // -1 means didn't get the mutex.
1210   else
1211     {
1212       while (rw->ref_count_ != 0)
1213         {
1214           rw->num_waiting_writers_++;
1216           if (ACE_OS::cond_wait (&rw->waiting_writers_, &rw->lock_) == -1)
1217             {
1218               result = -2; // -2 means we need to release the mutex.
1219               break;
1220             }
1222           rw->num_waiting_writers_--;
1223         }
1224     }
1225   if (result == 0)
1226     rw->ref_count_ = -1;
1227   if (result != -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) */
1232   return 0;
1233 # endif /* ! ACE_LACKS_RWLOCK_T */
1234 #else
1235   ACE_UNUSED_ARG (rw);
1236   ACE_NOTSUP_RETURN (-1);
1237 #endif /* ACE_HAS_THREADS */
1240 ACE_INLINE int
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)
1247   int result;
1248   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_destroy (rw),
1249                                        result),
1250                      int, -1);
1251 #  else /* Solaris */
1252   int result;
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) */
1261 #else
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))
1269 ACE_INLINE int
1270 ACE_OS::rwlock_init (ACE_rwlock_t *rw,
1271                      int type,
1272                      const ACE_TCHAR *name,
1273                      void *arg)
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);
1280   int status;
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));
1287 #    else
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);
1293   return status;
1295 #  else
1296   type = type;
1297   name = name;
1298   int result;
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) */
1304 ACE_INLINE int
1305 ACE_OS::sema_destroy (ACE_sema_t *s)
1307   ACE_OS_TRACE ("ACE_OS::sema_destroy");
1308 # if defined (ACE_HAS_POSIX_SEM)
1309   int result;
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)
1315   if (s->name_)
1316     {
1317       // Only destroy the semaphore if we're the ones who
1318       // initialized it.
1319       ACE_OSCALL (::sem_destroy (s->sema_),int, -1, result);
1320       ACE_OS::shm_unlink (s->name_);
1321       delete s->name_;
1322       return result;
1323     }
1324 #   else
1325   if (s->name_)
1326     {
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);
1330     }
1331 #   endif /*  ACE_LACKS_NAMED_POSIX_SEM */
1332   else
1333     {
1334       ACE_OSCALL (::sem_destroy (s->sema_), int, -1, result);
1335 #   if defined (ACE_LACKS_NAMED_POSIX_SEM)
1336       if (s->new_sema_)
1337 #   endif /* ACE_LACKS_NAMED_POSIX_SEM */
1338         delete s->sema_;
1339       s->sema_ = 0;
1340       return result;
1341     }
1342 # elif defined (ACE_USES_FIFO_SEM)
1343   int r0 = 0;
1344   if (s->name_)
1345     {
1346       r0 = ACE_OS::unlink (s->name_);
1347       ACE_OS::free (s->name_);
1348       s->name_ = 0;
1349     }
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)
1355   int result;
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)
1371   int result;
1372   ACE_OSCALL (::semDelete (s->sema_), int, -1, result);
1373   s->sema_ = 0;
1374   return result;
1375 #   endif /* ACE_HAS_STHREADS */
1376 # else
1377   ACE_UNUSED_ARG (s);
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 ().
1385 ACE_INLINE int
1386 ACE_OS::sema_init (ACE_sema_t *s,
1387                    u_int count,
1388                    int type,
1389                    const char *name,
1390                    void *arg,
1391                    int max,
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);
1399   s->name_ = 0;
1400 #  if defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
1401   ACE_UNUSED_ARG (arg);
1402 #  else
1403   int result = -1;
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)
1409     {
1410       if (ACE_OS::mutex_unlock (&s->lock_) == 0)
1411         result = 0;
1412     }
1414   if (result == -1)
1415     {
1416       ACE_OS::mutex_destroy (&s->lock_);
1417       ACE_OS::cond_destroy (&s->count_nonzero_);
1418       return result;
1419     }
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)
1425     {
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)
1431         {
1432           if (errno == EEXIST)
1433             fd = ACE_OS::shm_open (ACE_TEXT_CHAR_TO_TCHAR (name),
1434                                    O_RDWR | O_CREAT,
1435                                    ACE_DEFAULT_FILE_PERMS);
1436           else
1437             return -1;
1438         }
1439       else
1440         {
1441           // We own this shared memory object!  Let's set its
1442           // size.
1443           if (ACE_OS::ftruncate (fd,
1444                                  sizeof (ACE_sema_t)) == -1)
1445             return -1;
1446           s->name_ = ACE_OS::strdup (name);
1447           if (s->name_ == 0)
1448             return -1;
1449         }
1450       if (fd == -1)
1451         return -1;
1453       s->sema_ = (sem_t *)
1454         ACE_OS::mmap (0,
1455                       sizeof (ACE_sema_t),
1456                       PROT_RDWR,
1457                       MAP_SHARED,
1458                       fd,
1459                       0);
1460       ACE_OS::close (fd);
1461       if (s->sema_ == (sem_t *) MAP_FAILED)
1462         return -1;
1463       if (s->name_
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.
1469           //        -Ossama
1470           // Only initialize it if we're the one who created it.
1471           && ::sem_init (s->sema_, type == USYNC_PROCESS, count) == -1)
1472         return -1;
1473       return 0;
1474     }
1475 #  else
1476   if (name)
1477     {
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)
1484         {
1485           ACE_OS::strcpy (name2, "/");
1486           ACE_OS::strcat (name2, name);
1487           name = name2;
1488         }
1489 #      if defined (sun)
1490       else
1491         name = last_slash;         // Chop off chars preceding last slash
1492 #      endif /* sun */
1493 #    endif /* sun || HPUX */
1495       ACE_ALLOCATOR_RETURN (s->name_,
1496                             ACE_OS::strdup (name),
1497                             -1);
1498       s->sema_ = ::sem_open (s->name_,
1499                              O_CREAT,
1500                              ACE_DEFAULT_FILE_PERMS,
1501                              count);
1502       if (s->sema_ == (sem_t *) SEM_FAILED)
1503         return -1;
1504       else
1505         return 0;
1506     }
1507 #  endif /* ACE_LACKS_NAMED_POSIX_SEM */
1508   else
1509     {
1510       ACE_NEW_RETURN (s->sema_,
1511                       sem_t,
1512                       -1);
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,
1518                                      count), int, -1);
1519     }
1521 #elif defined (ACE_USES_FIFO_SEM)
1522   ACE_UNUSED_ARG (arg);
1523   ACE_UNUSED_ARG (max);
1524   ACE_UNUSED_ARG (sa);
1525   int             flags = 0;
1526   mode_t          mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP;
1528   if (type == USYNC_THREAD)
1529     {
1530       // Create systemwide unique name for semaphore
1531       char   uname[ACE_UNIQUE_NAME_LEN];
1532       ACE_OS::unique_name ((const void *) s,
1533                             uname,
1534                             ACE_UNIQUE_NAME_LEN);
1535       name = &uname[0];
1536     }
1538   s->name_ = 0;
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)
1543     {
1544       if (errno != EEXIST)    /* already exists OK else ERR */
1545         return -1;
1546       // check if this is a real FIFO, not just some other existing file
1547       ACE_stat fs;
1548       if (ACE_OS::stat (name, &fs))
1549         return -1;
1550       if (!S_ISFIFO (fs.st_mode))
1551         {
1552           // existing file is not a FIFO
1553           errno = EEXIST;
1554           return -1;
1555         }
1556     }
1557     else
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)
1563     {
1564       s->name_ = ACE_OS::strdup (name);
1565       if (s->name_ == 0)
1566         {
1567           if (creator)
1568             ACE_OS::unlink (name);
1569           return -1;
1570         }
1571     }
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)
1575     return (-1);
1577   /* turn off nonblocking for fd_[0] */
1578   if ((flags = ACE_OS::fcntl (s->fd_[0], F_GETFL, 0)) < 0)
1579     return (-1);
1581   flags &= ~O_NONBLOCK;
1582   if (ACE_OS::fcntl (s->fd_[0], F_SETFL, flags) < 0)
1583     return (-1);
1585   //if (s->name_ && count)
1586   if (creator && count)
1587     {
1588       char    c = 1;
1589       for (u_int i=0; i<count ;++i)
1590         if (ACE_OS::write (s->fd_[1], &c, sizeof (char)) != 1)
1591           return (-1);
1592     }
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
1597   // is concerned.
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)
1601     {
1602       ACE_OS::unlink (name);
1603     }
1605   return (0);
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);
1611   int result;
1612   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_init (s, count, type, arg), result),
1613                      int, -1);
1614 #  elif defined (ACE_HAS_PTHREADS)
1615   ACE_UNUSED_ARG (max);
1616   ACE_UNUSED_ARG (sa);
1617   int result = -1;
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)
1623     {
1624       s->count_ = count;
1625       s->waiters_ = 0;
1627       if (ACE_OS::mutex_unlock (&s->lock_) == 0)
1628         result = 0;
1629     }
1631   if (result == -1)
1632     {
1633       ACE_OS::mutex_destroy (&s->lock_);
1634       ACE_OS::cond_destroy (&s->count_nonzero_);
1635     }
1636   return result;
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),
1647      count,
1648      max,
1649      name);
1651   if (*s == 0)
1652     ACE_FAIL_RETURN (-1);
1653   /* NOTREACHED */
1654   else
1655     return 0;
1656 #    else /* ACE_USES_WINCE_SEMA_SIMULATION */
1657   int result = -1;
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)
1673     {
1674       s->count_ = count;
1676       if (ACE_OS::thread_mutex_unlock (&s->lock_) == 0)
1677         result = 0;
1678     }
1680   // Destroy the internal objects if we didn't initialize
1681   // either of them successfully.  Don't bother to check
1682   // for errors.
1683   if (result == -1)
1684     {
1685       ACE_OS::thread_mutex_destroy (&s->lock_);
1686       ACE_OS::event_destroy (&s->count_nonzero_);
1687     }
1688   return result;
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);
1695   s->name_ = 0;
1696   s->sema_ = ::semCCreate (type, count);
1697   return s->sema_ ? 0 : -1;
1698 #  endif /* ACE_HAS_STHREADS */
1699 #else
1700   ACE_UNUSED_ARG (s);
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)
1712 ACE_INLINE int
1713 ACE_OS::sema_init (ACE_sema_t *s,
1714                    u_int count,
1715                    int type,
1716                    const wchar_t *name,
1717                    void *arg,
1718                    int max,
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),
1731      count,
1732      max,
1733      name);
1735   if (*s == 0)
1736     ACE_FAIL_RETURN (-1);
1737   /* NOTREACHED */
1738   else
1739     return 0;
1740 #   else /* ACE_USES_WINCE_SEMA_SIMULATION */
1741   int result = -1;
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)
1757     {
1758       s->count_ = count;
1760       if (ACE_OS::thread_mutex_unlock (&s->lock_) == 0)
1761         result = 0;
1762     }
1764   // Destroy the internal objects if we didn't initialize
1765   // either of them successfully.  Don't bother to check
1766   // for errors.
1767   if (result == -1)
1768     {
1769       ACE_OS::thread_mutex_destroy (&s->lock_);
1770       ACE_OS::event_destroy (&s->count_nonzero_);
1771     }
1772   return result;
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 */
1781 ACE_INLINE int
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);
1788 #   else
1789   int result = -1;
1791   if (ACE_OS::mutex_lock (&s->lock_) == 0)
1792     {
1793       if (::sem_post (s->sema_) == 0)
1794         result = ACE_OS::cond_signal (&s->count_nonzero_);
1796       ACE_OS::mutex_unlock (&s->lock_);
1797     }
1798   return result;
1799 #   endif /* ACE_HAS_POSIX_SEM_TIMEOUT || ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION */
1800 # elif defined (ACE_USES_FIFO_SEM)
1801   char    c = 1;
1802   if (ACE_OS::write (s->fd_[1], &c, sizeof (char)) == sizeof (char))
1803     return (0);
1804   return (-1);
1805 # elif defined (ACE_HAS_THREADS)
1806 #   if defined (ACE_HAS_STHREADS)
1807   int result;
1808   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_post (s), result), int, -1);
1809 #   elif defined (ACE_HAS_PTHREADS)
1810   int result = -1;
1812   if (ACE_OS::mutex_lock (&s->lock_) == 0)
1813     {
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_);
1817       else
1818         result = 0;
1820       s->count_++;
1821       ACE_OS::mutex_unlock (&s->lock_);
1822     }
1823   return result;
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),
1827                                           ace_result_),
1828                         int, -1);
1829 #     else /* ACE_USES_WINCE_SEMA_SIMULATION */
1830   int result = -1;
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)
1835     {
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_);
1841       else
1842         result = 0;
1844       ACE_OS::thread_mutex_unlock (&s->lock_);
1845     }
1846   return result;
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 */
1851 # else
1852   ACE_UNUSED_ARG (s);
1853   ACE_NOTSUP_RETURN (-1);
1854 # endif /* ACE_HAS_POSIX_SEM */
1857 ACE_INLINE int
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);
1864 #else
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)
1874       return -1;
1876   return 0;
1877 #endif /* ACE_WIN32 */
1880 ACE_INLINE int
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)
1888   char  c;
1889   int     rc, flags;
1891   /* turn on nonblocking for s->fd_[0] */
1892   if ((flags = ACE_OS::fcntl (s->fd_[0], F_GETFL, 0)) < 0)
1893     return (-1);
1894   flags |= O_NONBLOCK;
1895   if (ACE_OS::fcntl (s->fd_[0], F_SETFL, flags) < 0)
1896     return (-1);
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)
1903   {
1904     flags &= ~O_NONBLOCK;
1905     ACE_OS::fcntl (s->fd_[0], F_SETFL, flags);
1906   }
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.
1912   int result;
1913   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_trywait (s),
1914                                        result),
1915                      int, -1);
1916 #   elif defined (ACE_HAS_PTHREADS)
1918   int result = -1;
1920   if (ACE_OS::mutex_lock (&s->lock_) == 0)
1921     {
1922       if (s->count_ > 0)
1923         {
1924           --s->count_;
1925           result = 0;
1926         }
1927       else
1928         errno = EBUSY;
1930       ACE_OS::mutex_unlock (&s->lock_);
1931     }
1932   return result;
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)
1938     return 0;
1939   else
1940     {
1941       if (result == WAIT_TIMEOUT)
1942         errno = EBUSY;
1943       else
1944         ACE_OS::set_errno_to_last_error ();
1945       // This is a hack, we need to find an appropriate mapping...
1946       return -1;
1947     }
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
1951   // lock.
1952   DWORD result = ::WaitForSingleObject (s->count_nonzero_, 0);
1954   if (result == WAIT_OBJECT_0)  // Proceed when it is available.
1955     {
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)
1963         {
1964           // Adjust the semaphore count.  Only update the event
1965           // object status when the state changed.
1966           s->count_--;
1967           if (s->count_ <= 0)
1968             ACE_OS::event_reset (&s->count_nonzero_);
1969           result = 0;
1970         }
1972       ACE_OS::thread_mutex_unlock (&s->lock_);
1973     }
1975   // Translate error message to errno used by ACE.
1976   if (result == WAIT_TIMEOUT)
1977     errno = EBUSY;
1978   else
1979     ACE_OS::set_errno_to_last_error ();
1980   // This is taken from the hack above. ;)
1981   return -1;
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)
1986       {
1987         // couldn't get the semaphore
1988         errno = EBUSY;
1989         return -1;
1990       }
1991     else
1992       // error
1993       return -1;
1994   else
1995     // got the semaphore
1996     return 0;
1997 #   endif /* ACE_HAS_STHREADS */
1998 # else
1999   ACE_UNUSED_ARG (s);
2000   ACE_NOTSUP_RETURN (-1);
2001 # endif /* ACE_HAS_POSIX_SEM */
2004 ACE_INLINE int
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)
2011   char c;
2012   if (ACE_OS::read (s->fd_[0], &c, sizeof (char)) == 1)
2013     return (0);
2014   return (-1);
2015 # elif defined (ACE_HAS_THREADS)
2016 #   if defined (ACE_HAS_STHREADS)
2017   int result;
2018   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_wait (s), result), int, -1);
2019 #   elif defined (ACE_HAS_PTHREADS)
2020   int result = 0;
2022   ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
2024   if (ACE_OS::mutex_lock (&s->lock_) != 0)
2025     result = -1;
2026   else
2027     {
2028       // Keep track of the number of waiters so that we can signal
2029       // them properly in <ACE_OS::sema_post>.
2030       s->waiters_++;
2032       // Wait until the semaphore count is > 0.
2033       while (s->count_ == 0)
2034         if (ACE_OS::cond_wait (&s->count_nonzero_,
2035                                &s->lock_) == -1)
2036           {
2037             result = -2; // -2 means that we need to release the mutex.
2038             break;
2039           }
2041       --s->waiters_;
2042     }
2044   if (result == 0)
2045     --s->count_;
2047   if (result != -1)
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))
2055     {
2056     case WAIT_OBJECT_0:
2057       return 0;
2058     default:
2059       // This is a hack, we need to find an appropriate mapping...
2060       ACE_OS::set_errno_to_last_error ();
2061       return -1;
2062     }
2063   /* NOTREACHED */
2064 #     else /* ACE_USES_WINCE_SEMA_SIMULATION */
2065   // Timed wait.
2066   int result = -1;
2067   for (;;)
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
2070     // deadlock.)
2071     switch (::WaitForSingleObject (s->count_nonzero_, INFINITE))
2072       {
2073       case WAIT_OBJECT_0:
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)
2079           {
2080             // Decrease the internal counter.  Only update the event
2081             // object's status when the state changed.
2082             s->count_--;
2083             if (s->count_ <= 0)
2084               ACE_OS::event_reset (&s->count_nonzero_);
2085             result = 0;
2086           }
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.
2091         if (result == 0)
2092           return 0;
2093         break;
2095       default:
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. ;)
2100         return -1;
2101       }
2102   /* NOTREACHED */
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 */
2107 # else
2108   ACE_UNUSED_ARG (s);
2109   ACE_NOTSUP_RETURN (-1);
2110 # endif /* ACE_HAS_POSIX_SEM */
2113 ACE_INLINE int
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)
2119   int rc;
2120   timespec_t ts;
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 */
2125   return rc;
2126 #   elif !defined (ACE_DISABLE_POSIX_SEM_TIMEOUT_EMULATION)
2127   int result = 0;
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)
2134     result = -2;
2135   else
2136     {
2137       bool finished = true;
2138       do
2139       {
2140         result = ACE_OS::sema_trywait (s);
2141         if (result == -1 && errno == EAGAIN)
2142           expired = ACE_OS::gettimeofday () > tv;
2143         else
2144           expired = false;
2146         finished = result != -1 || expired ||
2147                    (result == -1 && errno != EAGAIN);
2148         if (!finished)
2149           {
2150             if (ACE_OS::cond_timedwait (&s->count_nonzero_,
2151                                         &s->lock_,
2152                                         &tv) == -1)
2153               {
2154                 error = errno;
2155                 result = -1;
2156                 break;
2157               }
2158           }
2159       } while (!finished);
2161       if (expired)
2162         error = ETIME;
2164 #     if defined (ACE_LACKS_COND_TIMEDWAIT_RESET)
2165       tv = ACE_OS::gettimeofday ();
2166 #     endif /* ACE_LACKS_COND_TIMEDWAIT_RESET */
2167     }
2169   if (result != -2)
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 */
2174   ACE_UNUSED_ARG (s);
2175   ACE_UNUSED_ARG (tv);
2176   ACE_NOTSUP_RETURN (-1);
2177 #   endif /* ACE_HAS_POSIX_SEM_TIMEOUT */
2178 # elif defined (ACE_USES_FIFO_SEM)
2179   int rc;
2180   ACE_Time_Value now = ACE_OS::gettimeofday ();
2182   while (tv > now)
2183     {
2184       ACE_Time_Value timeout = tv;
2185       timeout -= now;
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)
2191         {
2192           if (rc == 0 || errno != EAGAIN)
2193           {
2194             if (rc == 0)
2195               errno = ETIME;
2196             return (-1);
2197           }
2198         }
2200       // try to read the signal *but* do *not* block
2201       if (rc == 1 && ACE_OS::sema_trywait (s) == 0)
2202         return (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 ();
2207     }
2209   // make sure errno is set right
2210   errno = ETIME;
2212   return (-1);
2213 # elif defined (ACE_HAS_THREADS)
2214 #   if defined (ACE_HAS_STHREADS)
2215   ACE_UNUSED_ARG (s);
2216   ACE_UNUSED_ARG (tv);
2217   ACE_NOTSUP_RETURN (-1);
2218 #   elif defined (ACE_HAS_PTHREADS)
2219   int result = 0;
2220   ACE_Errno_Guard error (errno);
2222   ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
2224   if (ACE_OS::mutex_lock (&s->lock_) != 0)
2225     result = -1;
2226   else
2227     {
2228       // Keep track of the number of waiters so that we can signal
2229       // them properly in <ACE_OS::sema_post>.
2230       s->waiters_++;
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_,
2235                                     &s->lock_,
2236                                     &tv) == -1)
2237           {
2238             error = errno;
2239             result = -2; // -2 means that we need to release the mutex.
2240             break;
2241           }
2243       --s->waiters_;
2244     }
2246   if (result == 0)
2247     {
2248 #     if defined (ACE_LACKS_COND_TIMEDWAIT_RESET)
2249       tv = ACE_OS::gettimeofday ();
2250 #     endif /* ACE_LACKS_COND_TIMEDWAIT_RESET */
2251       --s->count_;
2252     }
2254   if (result != -1)
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)
2260   int msec_timeout;
2262   if (tv.sec () == 0 && tv.usec () == 0)
2263     msec_timeout = 0; // Do a "poll."
2264   else
2265     {
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)
2274         msec_timeout = 0;
2275       else
2276         msec_timeout = relative_time.msec ();
2277     }
2279   switch (::WaitForSingleObject (*s, msec_timeout))
2280     {
2281     case WAIT_OBJECT_0:
2282       tv = ACE_OS::gettimeofday ();     // Update time to when acquired
2283       return 0;
2284     case WAIT_TIMEOUT:
2285       errno = ETIME;
2286       return -1;
2287     default:
2288       // This is a hack, we need to find an appropriate mapping...
2289       ACE_OS::set_errno_to_last_error ();
2290       return -1;
2291     }
2292   /* NOTREACHED */
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 ();
2308   int result = -1;
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
2312   // right away.
2313   while (relative_time >= ACE_Time_Value::zero)
2314     {
2315       // Wait for our turn to get the object.
2316       switch (::WaitForSingleObject (s->count_nonzero_, relative_time.msec ()))
2317         {
2318         case WAIT_OBJECT_0:
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)
2325             {
2326               // As before, only reset the object when the semaphore
2327               // is no longer available.
2328               s->count_--;
2329               if (s->count_ <= 0)
2330                 ACE_OS::event_reset (&s->count_nonzero_);
2331               result = 0;
2332             }
2334           ACE_OS::thread_mutex_unlock (&s->lock_);
2336           // Only return when we successfully get the semaphore.
2337           if (result == 0)
2338             {
2339               tv = ACE_OS::gettimeofday ();     // Update to time acquired
2340               return 0;
2341             }
2342           break;
2344           // We have timed out.
2345         case WAIT_TIMEOUT:
2346           errno = ETIME;
2347           return -1;
2349           // What?
2350         default:
2351           ACE_OS::set_errno_to_last_error ();
2352           // This is taken from the hack above. ;)
2353           return -1;
2354         };
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 ();
2359     }
2361   // We have timed out.
2362   errno = ETIME;
2363   return -1;
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)
2376     {
2377       if (errno == S_objLib_OBJ_TIMEOUT)
2378         // Convert the VxWorks errno to one that's common for to ACE
2379         // platforms.
2380         errno = ETIME;
2381       else if (errno == S_objLib_OBJ_UNAVAILABLE)
2382         errno = EBUSY;
2383       return -1;
2384     }
2385   else
2386     {
2387       tv = ACE_OS::gettimeofday ();  // Update to time acquired
2388       return 0;
2389     }
2390 #   endif /* ACE_HAS_STHREADS */
2391 # else
2392   ACE_UNUSED_ARG (s);
2393   ACE_UNUSED_ARG (tv);
2394   ACE_NOTSUP_RETURN (-1);
2395 # endif /* ACE_HAS_POSIX_SEM */
2398 ACE_INLINE int
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);
2404 ACE_INLINE int
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);
2410 #else
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 */
2420 ACE_INLINE int
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);
2426 #else
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 */
2435 ACE_INLINE int
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);
2441 #else
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 */
2450 ACE_INLINE int
2451 ACE_OS::sigtimedwait (const sigset_t *sset,
2452                       siginfo_t *info,
2453                       const ACE_Time_Value *timeout)
2455   ACE_OS_TRACE ("ACE_OS::sigtimedwait");
2456 #if defined (ACE_HAS_SIGTIMEDWAIT)
2457   timespec_t ts;
2458   timespec_t *tsp;
2460   if (timeout != 0)
2461     {
2462       ts = *timeout; // Calls ACE_Time_Value::operator timespec_t().
2463       tsp = &ts;
2464     }
2465   else
2466     tsp = 0;
2468   ACE_OSCALL_RETURN (::sigtimedwait (sset, info, tsp),
2469                      int, -1);
2470 #else
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 */
2478 ACE_INLINE int
2479 ACE_OS::sigwait (sigset_t *sset, int *sig)
2481   ACE_OS_TRACE ("ACE_OS::sigwait");
2482   int local_sig;
2483   if (sig == 0)
2484     sig = &local_sig;
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;
2493    #else
2494      *sig = ::sigwait (sset);
2495      return *sig;
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);
2503     return *sig;
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
2530     // means forever.
2531     *sig = ::sigtimedwait (sset, 0, 0);
2532     return *sig;
2533 # endif /* __FreeBSD__ */
2534 #else
2535     ACE_UNUSED_ARG (sset);
2536     ACE_UNUSED_ARG (sig);
2537     ACE_NOTSUP_RETURN (-1);
2538 #endif /* ACE_HAS_THREADS */
2541 ACE_INLINE int
2542 ACE_OS::sigwaitinfo (const sigset_t *sset,
2543                      siginfo_t *info)
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);
2551 #else
2552   ACE_UNUSED_ARG (sset);
2553   ACE_UNUSED_ARG (info);
2554   ACE_NOTSUP_RETURN (-1);
2555 #endif /* ACE_HAS_SIGTIMEDWAIT */
2558 ACE_INLINE int
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)
2564   int result;
2565   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_cancel (thr_id),
2566                                         result),
2567                       int, -1);
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 */
2574 #else
2575   ACE_UNUSED_ARG (thr_id);
2576   ACE_NOTSUP_RETURN (-1);
2577 #endif /* ACE_HAS_THREADS */
2580 ACE_INLINE int
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);
2587 # else
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.
2593   return t1 == t2;
2594 #endif /* ACE_HAS_PTHREADS */
2597 ACE_INLINE int
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)
2603   int result;
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)
2607   int result;
2608   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_continue (target_thread),
2609                                        result),
2610                      int, -1);
2611 #  elif defined (ACE_HAS_PTHREAD_CONTINUE_NP)
2612   int result;
2613   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_continue_np (target_thread),
2614                                        result),
2615                      int, -1);
2616 #  elif defined (ACE_HAS_PTHREAD_RESUME_NP)
2617   int result;
2618   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_resume_np (target_thread),
2619                                        result),
2620                      int, -1);
2621 #  else
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);
2629   else
2630     return 0;
2631 # elif defined (ACE_HAS_VXTHREADS)
2632   ACE_OSCALL_RETURN (::taskResume (target_thread), int, -1);
2633 # endif /* ACE_HAS_STHREADS */
2634 #else
2635   ACE_UNUSED_ARG (target_thread);
2636   ACE_NOTSUP_RETURN (-1);
2637 #endif /* ACE_HAS_THREADS */
2640 ACE_INLINE int
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 ();
2649 # else
2650   ACE_NOTSUP_RETURN (-1);
2651 # endif /* ACE_HAS_STHREADS */
2652 #else
2653   ACE_NOTSUP_RETURN (-1);
2654 #endif /* ACE_HAS_THREADS */
2657 ACE_INLINE int
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;
2667   int result;
2669   ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_getschedparam (ht_id, &policy, &param),
2670                                 result), int,
2671               -1, result);
2672   priority = param.sched_priority;
2673   return result;
2674 # elif defined (ACE_HAS_STHREADS)
2675   int result;
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;
2685 #     else
2686   DWORD timeslice = ::EtsGetTimeSlice ();
2687   policy = timeslice == 0 ? ACE_SCHED_OTHER : ACE_SCHED_FIFO;
2688 #     endif /* ACE_PHARLAP_LABVIEW_RT */
2689 #   else
2690   DWORD priority_class = ::GetPriorityClass (::GetCurrentProcess ());
2691   if (priority_class == 0 && (error = ::GetLastError ()) != NO_ERROR)
2692     ACE_FAIL_RETURN (-1);
2694   policy =
2695     (priority_class ==
2696      REALTIME_PRIORITY_CLASS) ? ACE_SCHED_FIFO : ACE_SCHED_OTHER;
2697 #   endif /* ACE_HAS_PHARLAP */
2699   return 0;
2700 # elif defined (ACE_HAS_VXTHREADS)
2701   ACE_OSCALL_RETURN (::taskPriorityGet (ht_id, &priority), int, -1);
2702 # else
2703   ACE_UNUSED_ARG (ht_id);
2704   ACE_UNUSED_ARG (priority);
2705   ACE_NOTSUP_RETURN (-1);
2706 # endif /* ACE_HAS_STHREADS */
2707 #else
2708   ACE_UNUSED_ARG (ht_id);
2709   ACE_UNUSED_ARG (priority);
2710   ACE_NOTSUP_RETURN (-1);
2711 #endif /* ACE_HAS_THREADS */
2714 ACE_INLINE int
2715 ACE_OS::thr_getprio (ACE_hthread_t ht_id, int &priority)
2717   ACE_OS_TRACE ("ACE_OS::thr_getprio");
2718   int policy = 0;
2719   return ACE_OS::thr_getprio (ht_id, priority, policy);
2722 #if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
2723 ACE_INLINE int
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);
2729     return 0;
2730 # elif defined (ACE_HAS_STHREADS)
2731     int result;
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)
2736     {
2737       ACE_OS::set_errno_to_last_error ();
2738       return -1;
2739     }
2740   else
2741     return 0;
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 */
2750 ACE_INLINE int
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)
2757       {
2758         errno = EINVAL;
2759         data = 0;
2760         return -1;
2761       }
2762     else
2763       {
2764         *data = ACE_TSS_Emulation::ts_object (key);
2765         return 0;
2766       }
2767 # elif defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
2768   return ACE_OS::thr_getspecific_native (key, data);
2769 #else
2770   ACE_UNUSED_ARG (key);
2771   ACE_UNUSED_ARG (data);
2772   ACE_NOTSUP_RETURN (-1);
2773 # endif /* ACE_HAS_TSS_EMULATION */
2774 #else
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)
2782 ACE_INLINE int
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)
2789   int result;
2790   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_join (thr_handle, 0, status), result),
2791                      int, -1);
2792 # elif defined (ACE_HAS_PTHREADS)
2793   int result;
2794   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_join (thr_handle, status), result),
2795                      int, -1);
2796 # elif defined (ACE_HAS_WTHREADS)
2797   ACE_THR_FUNC_RETURN local_status = 0;
2799   // Make sure that status is non-NULL.
2800   if (status == 0)
2801     status = &local_status;
2803   if (::WaitForSingleObject (thr_handle, INFINITE) == WAIT_OBJECT_0
2804       && ::GetExitCodeThread (thr_handle, status) != FALSE)
2805     {
2806       ::CloseHandle (thr_handle);
2807       return 0;
2808     }
2809   ACE_FAIL_RETURN (-1);
2810   /* NOTREACHED */
2811 # else
2812   ACE_UNUSED_ARG (thr_handle);
2813   ACE_UNUSED_ARG (status);
2814   ACE_NOTSUP_RETURN (-1);
2815 # endif /* ACE_HAS_STHREADS */
2816 #else
2817   ACE_UNUSED_ARG (thr_handle);
2818   ACE_UNUSED_ARG (status);
2819   ACE_NOTSUP_RETURN (-1);
2820 #endif /* ACE_HAS_THREADS */
2823 ACE_INLINE int
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)
2831   int result;
2832   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_join (waiter_id, thr_id, status), result),
2833                      int, -1);
2834 # elif defined (ACE_HAS_PTHREADS)
2835   ACE_UNUSED_ARG (thr_id);
2836   int result;
2837   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_join (waiter_id, status), result),
2838                      int, -1);
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 */
2848 #else
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 */
2857 ACE_INLINE int
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);
2867 #   else
2868   int result;
2869   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_kill (thr_id, signum),
2870                                        result),
2871                      int, -1);
2872 #   endif /* ACE_LACKS_PTHREAD_KILL */
2873 # elif defined (ACE_HAS_STHREADS)
2874   int result;
2875   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_kill (thr_id, signum),
2876                                        result),
2877                      int, -1);
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
2882 # else
2883   ACE_UNUSED_ARG (thr_id);
2884   ACE_UNUSED_ARG (signum);
2885   ACE_NOTSUP_RETURN (-1);
2886 # endif /* ACE_HAS_STHREADS */
2887 #else
2888   ACE_UNUSED_ARG (thr_id);
2889   ACE_UNUSED_ARG (signum);
2890   ACE_NOTSUP_RETURN (-1);
2891 #endif /* ACE_HAS_THREADS */
2894 ACE_INLINE size_t
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 ();
2903 #   else
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;
2911 #   else
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)
2917   TASK_DESC taskDesc;
2918   STATUS status;
2920   ACE_thread_t tid = ACE_OS::thr_self ();
2922   ACE_OSCALL (ACE_ADAPT_RETVAL (::taskInfoGet (tid, &taskDesc),
2923                                 status),
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 */
2929 #else
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 */
2949 #else
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 ());
2960 #else
2961   ACE_NOTSUP_RETURN (0);
2962 #endif
2963 #else
2964   ACE_NOTSUP_RETURN (0);
2965 #endif
2968 ACE_INLINE void
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 */
2985 #else
2986   self = 1; // Might as well make it the main thread ;-)
2987 #endif /* ACE_HAS_THREADS */
2990 ACE_INLINE int
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)
2996   int result;
2997   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setcancelstate (new_state,
2998                                                                old_state),
2999                                        result),
3000                      int, -1);
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 */
3014 #else
3015   ACE_UNUSED_ARG (new_state);
3016   ACE_UNUSED_ARG (old_state);
3017   ACE_NOTSUP_RETURN (-1);
3018 #endif /* ACE_HAS_THREADS */
3021 ACE_INLINE int
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)
3027   int result;
3028   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setcanceltype (new_type,
3029                                                               old_type),
3030                                        result),
3031                      int, -1);
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 */
3037 #else
3038   ACE_UNUSED_ARG (new_type);
3039   ACE_UNUSED_ARG (old_type);
3040   ACE_NOTSUP_RETURN (-1);
3041 #endif /* ACE_HAS_THREADS */
3044 ACE_INLINE int
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)
3050   int result;
3051   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setconcurrency (hint),
3052                                        result),
3053                      int, -1);
3054 # elif defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_PTHREAD_SETCONCURRENCY)
3055   int result;
3056   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setconcurrency (hint),
3057                                        result),
3058                      int, -1);
3059 # else
3060   ACE_UNUSED_ARG (hint);
3061   ACE_NOTSUP_RETURN (-1);
3062 # endif /* ACE_HAS_STHREADS */
3063 #else
3064   ACE_UNUSED_ARG (hint);
3065   ACE_NOTSUP_RETURN (-1);
3066 #endif /* ACE_HAS_THREADS */
3069 ACE_INLINE int
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)))
3078   int result;
3079   struct sched_param param;
3080   ACE_OS::memset ((void *) &param, 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().
3085   if (policy == -1)
3086     {
3087       ACE_OSCALL (ACE_ADAPT_RETVAL (pthread_getschedparam (ht_id, &policy, &param),
3088                                     result),
3089                   int, -1, result);
3090       if (result == -1)
3091         return result;
3092     }
3094   param.sched_priority = priority;
3096   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setschedparam (ht_id,
3097                                                               policy,
3098                                                               &param),
3099                                        result),
3100                      int, -1);
3101 # elif defined (ACE_HAS_STHREADS)
3102   int result;
3103   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setprio (ht_id, priority),
3104                                        result),
3105                      int, -1);
3106 # elif defined (ACE_HAS_WTHREADS)
3107   ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::SetThreadPriority (ht_id, priority),
3108                                           ace_result_),
3109                         int, -1);
3110 # elif defined (ACE_HAS_VXTHREADS)
3111   ACE_OSCALL_RETURN (::taskPrioritySet (ht_id, priority), int, -1);
3112 # else
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 */
3118 #else
3119   ACE_UNUSED_ARG (ht_id);
3120   ACE_UNUSED_ARG (priority);
3121   ACE_NOTSUP_RETURN (-1);
3122 #endif /* ACE_HAS_THREADS */
3125 ACE_INLINE int
3126 ACE_OS::thr_sigsetmask (int how,
3127                         const sigset_t *nsm,
3128                         sigset_t *osm)
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)
3140   int result;
3141   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigthreadmask (how, nsm, osm),
3142                                        result), int, -1);
3143 # elif defined (ACE_HAS_STHREADS)
3144   int result;
3145   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_sigsetmask (how, nsm, osm),
3146                                        result),
3147                      int, -1);
3148 # elif defined (ACE_HAS_PTHREADS)
3149 #   if !defined (ACE_LACKS_PTHREAD_SIGMASK)
3150   int result;
3151   //FUZZ: disable check_for_lack_ACE_OS
3152   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm),
3153                                        result), int, -1);
3154   //FUZZ: enable check_for_lack_ACE_OS
3155 #   endif /* !ACE_LACKS_PTHREAD_SIGMASK */
3157 #if 0
3158   /* Don't know if any platform actually needs this... */
3159   // as far as I can tell, this is now pthread_sigaction() -- jwr
3160   int result;
3161   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_sigaction (how, nsm, osm),
3162                                        result), int, -1);
3163 #endif /* 0 */
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)
3172   int old_mask = 0;
3173   switch (how)
3174     {
3175     case SIG_BLOCK:
3176     case SIG_UNBLOCK:
3177       {
3178         // get the old mask
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));
3183         if (osm)
3184           *osm = old_mask;
3185         break;
3186       }
3187     case SIG_SETMASK:
3188       old_mask = ::sigsetmask (*nsm);
3189       if (osm)
3190         *osm = old_mask;
3191       break;
3192     default:
3193       return -1;
3194     }
3196   return 0;
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 */
3203 #else
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 */
3211 ACE_INLINE int
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)
3217   int result;
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)
3221   int result;
3222   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_suspend (target_thread),
3223                                        result),
3224                      int, -1);
3225 #  elif defined (ACE_HAS_PTHREAD_SUSPEND_NP)
3226   int result;
3227   ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_suspend_np (target_thread),
3228                                        result),
3229                      int, -1);
3230 #  else
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)
3236     return 0;
3237   else
3238     ACE_FAIL_RETURN (-1);
3239   /* NOTREACHED */
3240 # elif defined (ACE_HAS_VXTHREADS)
3241   ACE_OSCALL_RETURN (::taskSuspend (target_thread), int, -1);
3242 # endif /* ACE_HAS_STHREADS */
3243 #else
3244   ACE_UNUSED_ARG (target_thread);
3245   ACE_NOTSUP_RETURN (-1);
3246 #endif /* ACE_HAS_THREADS */
3249 ACE_INLINE void
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)
3259 # else
3260   // no-op:  can't use ACE_NOTSUP_RETURN because there is no return value
3261 # endif /* ACE_HAS_PTHREADS */
3262 #else
3263 #endif /* ACE_HAS_THREADS */
3266 ACE_INLINE void
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)
3272   ::sched_yield ();
3273 # elif defined (ACE_HAS_STHREADS)
3274   ::thr_yield ();
3275 # elif defined (ACE_HAS_WTHREADS)
3276   ::Sleep (0);
3277 # elif defined (ACE_HAS_VXTHREADS)
3278   // An argument of 0 to ::taskDelay doesn't appear to yield the
3279   // current thread.
3280   // Now, it does seem to work.  The context_switch_time test
3281   // works fine with task_delay set to 0.
3282   ::taskDelay (0);
3283 # endif /* ACE_HAS_STHREADS */
3284 #else
3285   ;
3286 #endif /* ACE_HAS_THREADS */
3289 ACE_INLINE int
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);
3296   return 0;
3297 # else
3298   return ACE_OS::mutex_destroy (m);
3299 # endif /* ACE_HAS_WTHREADS */
3300 #else
3301   ACE_UNUSED_ARG (m);
3302   ACE_NOTSUP_RETURN (-1);
3304 #endif /* ACE_HAS_THREADS */
3307 ACE_INLINE int
3308 ACE_OS::thread_mutex_init (ACE_thread_mutex_t *m,
3309                            int lock_type,
3310                            const char *name,
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);
3320   ACE_SEH_TRY
3321     {
3322       ::InitializeCriticalSection (m);
3323     }
3324   ACE_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3325     {
3326       errno = ENOMEM;
3327       return -1;
3328     }
3329   return 0;
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 */
3339 #else
3340   ACE_UNUSED_ARG (m);
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)
3350 ACE_INLINE int
3351 ACE_OS::thread_mutex_init (ACE_thread_mutex_t *m,
3352                            int lock_type,
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);
3363   ACE_SEH_TRY
3364     {
3365       ::InitializeCriticalSection (m);
3366     }
3367   ACE_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3368     {
3369       errno = ENOMEM;
3370       return -1;
3371     }
3372   return 0;
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 */
3380 #else
3381   ACE_UNUSED_ARG (m);
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 */
3391 ACE_INLINE int
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);
3398   return 0;
3399 # else
3400   return ACE_OS::mutex_lock (m);
3401 # endif /* ACE_HAS_WTHREADS */
3402 #else
3403   ACE_UNUSED_ARG (m);
3404   ACE_NOTSUP_RETURN (-1);
3405 #endif /* ACE_HAS_THREADS */
3408 ACE_INLINE int
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);
3424 #else
3425   ACE_UNUSED_ARG (m);
3426   ACE_UNUSED_ARG (timeout);
3427   ACE_NOTSUP_RETURN (-1);
3428 #endif /* ACE_HAS_THREADS */
3431 ACE_INLINE int
3432 ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m,
3433                            const ACE_Time_Value *timeout)
3435   return timeout == 0
3436     ? ACE_OS::thread_mutex_lock (m)
3437     : ACE_OS::thread_mutex_lock (m, *timeout);
3440 ACE_INLINE int
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);
3449   if (result == TRUE)
3450     return 0;
3451   else
3452     {
3453       errno = EBUSY;
3454       return -1;
3455     }
3456 #   else
3457   ACE_UNUSED_ARG (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 */
3464 #else
3465   ACE_UNUSED_ARG (m);
3466   ACE_NOTSUP_RETURN (-1);
3467 #endif /* ACE_HAS_THREADS */
3470 ACE_INLINE int
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);
3477   return 0;
3478 # else
3479   return ACE_OS::mutex_unlock (m);
3480 # endif /* ACE_HAS_WTHREADS */
3481 #else
3482   ACE_UNUSED_ARG (m);
3483   ACE_NOTSUP_RETURN (-1);
3484 #endif /* ACE_HAS_THREADS */
3487 /*****************************************************************************/
3489 # if defined (ACE_IS_SPLITTING)
3490 #   define ACE_SPECIAL_INLINE
3491 # else
3492 #   define ACE_SPECIAL_INLINE ACE_INLINE
3493 //#   define ACE_SPECIAL_INLINE inline
3494 # endif
3496 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
3498 ACE_INLINE
3500 ACE_OS_Thread_Mutex_Guard::acquire (void)
3502   return owner_ = ACE_OS::thread_mutex_lock (&lock_);
3505 ACE_INLINE
3507 ACE_OS_Thread_Mutex_Guard::release (void)
3509   if (owner_ == -1)
3510     return 0;
3511   else
3512     {
3513       owner_ = -1;
3514       return ACE_OS::thread_mutex_unlock (&lock_);
3515     }
3518 ACE_INLINE
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 ())
3523     acquire ();
3526 ACE_INLINE
3527 ACE_OS_Thread_Mutex_Guard::~ACE_OS_Thread_Mutex_Guard ()
3529   release ();
3532 /*****************************************************************************/
3534 ACE_INLINE
3536 ACE_OS_Recursive_Thread_Mutex_Guard::acquire (void)
3538   return owner_ = ACE_OS::recursive_mutex_lock (&lock_);
3541 ACE_INLINE
3543 ACE_OS_Recursive_Thread_Mutex_Guard::release (void)
3545   if (owner_ == -1)
3546     return 0;
3547   else
3548     {
3549       owner_ = -1;
3550       return ACE_OS::recursive_mutex_unlock (&lock_);
3551     }
3554 ACE_INLINE
3555 ACE_OS_Recursive_Thread_Mutex_Guard::ACE_OS_Recursive_Thread_Mutex_Guard (
3556   ACE_recursive_thread_mutex_t &m)
3557    : lock_ (m),
3558      owner_ (-1)
3560   if (!ACE_OS_Object_Manager::starting_up ())
3561     acquire ();
3564 ACE_INLINE
3565 ACE_OS_Recursive_Thread_Mutex_Guard::~ACE_OS_Recursive_Thread_Mutex_Guard ()
3567   release ();
3570 #endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */
3573 /*****************************************************************************/
3575 ACE_INLINE
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)
3583 ACE_INLINE
3584 ACE_Thread_ID::ACE_Thread_ID (const ACE_Thread_ID &id)
3585   : thread_id_ (id.thread_id_),
3586     thread_handle_ (id.thread_handle_)
3590 ACE_INLINE
3591 ACE_Thread_ID::ACE_Thread_ID (void)
3592   : thread_id_ (ACE_OS::thr_self ())
3594   ACE_OS::thr_self (thread_handle_);
3597 ACE_INLINE
3598 ACE_thread_t
3599 ACE_Thread_ID::id (void) const
3601   return this->thread_id_;
3604 ACE_INLINE void
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_;
3616 ACE_INLINE void
3617 ACE_Thread_ID::handle (ACE_hthread_t thread_handle)
3619   this->thread_handle_ = thread_handle;
3622 ACE_INLINE bool
3623 ACE_Thread_ID::operator== (const ACE_Thread_ID &rhs) const
3625   return
3626     ACE_OS::thr_cmp (this->thread_handle_, rhs.thread_handle_)
3627     && ACE_OS::thr_equal (this->thread_id_, rhs.thread_id_);
3630 ACE_INLINE bool
3631 ACE_Thread_ID::operator!= (const ACE_Thread_ID &rhs) const
3633   return !(*this == rhs);
3636 ACE_END_VERSIONED_NAMESPACE_DECL