00001 #include "ace/OS_NS_Thread.h"
00002
00003 ACE_RCSID (ace,
00004 OS_NS_Thread,
00005 "OS_NS_Thread.cpp,v 1.79 2006/06/07 08:23:48 jwillemsen Exp")
00006
00007 #if !defined (ACE_HAS_INLINED_OSCALLS)
00008 # include "ace/OS_NS_Thread.inl"
00009 #endif
00010
00011 #include "ace/OS_NS_stdio.h"
00012 #include "ace/Sched_Params.h"
00013 #include "ace/OS_Memory.h"
00014 #include "ace/OS_Thread_Adapter.h"
00015 #include "ace/Min_Max.h"
00016 #include "ace/Object_Manager_Base.h"
00017 #include "ace/OS_NS_errno.h"
00018 #include "ace/OS_NS_ctype.h"
00019 #include "ace/Log_Msg.h"
00020
00021 #include "ace/Auto_Ptr.h"
00022 #include "ace/Thread_Mutex.h"
00023 #include "ace/Condition_T.h"
00024 #include "ace/Guard_T.h"
00025
00026 extern "C" void
00027 ACE_MUTEX_LOCK_CLEANUP_ADAPTER_NAME (void *args)
00028 {
00029 ACE_VERSIONED_NAMESPACE_NAME::ACE_OS::mutex_lock_cleanup (args);
00030 }
00031
00032
00033 #if !defined(ACE_WIN32) && defined (__IBMCPP__) && (__IBMCPP__ >= 400)
00034 # define ACE_BEGINTHREADEX(STACK, STACKSIZE, ENTRY_POINT, ARGS, FLAGS, THR_ID) \
00035 (*THR_ID = ::_beginthreadex ((void(_Optlink*)(void*))ENTRY_POINT, STACK, STACKSIZE, ARGS), *THR_ID)
00036 #elif defined(ACE_WIN32) && defined (__IBMCPP__) && (__IBMCPP__ >= 400)
00037
00038 struct __IBMCPP__thread_params {
00039 __IBMCPP__thread_params(ACE_THR_C_FUNC e, LPVOID a)
00040 :entry_point(e),args(a) {}
00041 ACE_THR_C_FUNC entry_point;
00042 LPVOID args;
00043 };
00044
00045 # pragma handler(initThread)
00046 extern "C" DWORD __stdcall __IBMCPP__initThread(void *arg)
00047 {
00048
00049 _fpreset();
00050
00051
00052 auto_ptr<__IBMCPP__thread_params> parms((__IBMCPP__thread_params *)arg);
00053 (*parms->entry_point)(parms->args);
00054 _endthread();
00055 return 0;
00056 }
00057
00058 HANDLE WINAPI __IBMCPP__beginthreadex(void *stack,
00059 DWORD stacksize,
00060 ACE_THR_C_FUNC entry_point,
00061 LPVOID args,
00062 DWORD flags,
00063 LPDWORD thr_id)
00064 {
00065 return CreateThread(0,
00066 stacksize,
00067 (LPTHREAD_START_ROUTINE)__IBMCPP__initThread,
00068 new __IBMCPP__thread_params(entry_point, args),
00069 flags,
00070 thr_id);
00071 }
00072
00073 # define ACE_BEGINTHREADEX(STACK, STACKSIZE, ENTRY_POINT, ARGS, FLAGS, THR_ID) \
00074 __IBMCPP__beginthreadex(STACK, STACKSIZE, ENTRY_POINT, ARGS, FLAGS, THR_ID)
00075
00076 #elif defined (ACE_HAS_WINCE) && defined (UNDER_CE) && (UNDER_CE >= 211)
00077 # define ACE_BEGINTHREADEX(STACK, STACKSIZE, ENTRY_POINT, ARGS, FLAGS, THR_ID) \
00078 CreateThread (0, STACKSIZE, (unsigned long (__stdcall *) (void *)) ENTRY_POINT, ARGS, (FLAGS) & CREATE_SUSPENDED, (unsigned long *) THR_ID)
00079 #elif defined(ACE_HAS_WTHREADS)
00080
00081
00082
00083 typedef unsigned (__stdcall *ACE_WIN32THRFUNC_T)(void*);
00084 # define ACE_BEGINTHREADEX(STACK, STACKSIZE, ENTRY_POINT, ARGS, FLAGS, THR_ID) \
00085 ::_beginthreadex (STACK, STACKSIZE, (ACE_WIN32THRFUNC_T) ENTRY_POINT, ARGS, FLAGS, (unsigned int *) THR_ID)
00086 #endif
00087
00088
00089
00090 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00091
00092 void
00093 ACE_Thread_ID::to_string (char *thr_string) const
00094 {
00095 char format[128];
00096 char *fp = 0;
00097 fp = format;
00098 *fp++ = '%';
00099
00100 #if defined (ACE_WIN32)
00101 ACE_OS::strcpy (fp, "u");
00102 ACE_OS::sprintf (thr_string,
00103 format,
00104 static_cast <unsigned> (thread_id_));
00105 #elif defined (ACE_AIX_VERS) && (ACE_AIX_VERS <= 402)
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 ACE_OS::strcpy (fp, "u");
00117 ACE_OS::sprintf (thr_string, format, thread_id_);
00118 #elif defined (DIGITAL_UNIX)
00119 ACE_OS::strcpy (fp, "u");
00120 ACE_OS::sprintf (thr_string, format,
00121 # if defined (ACE_HAS_THREADS)
00122 thread_id_
00123 # else
00124 thread_id_
00125 # endif
00126 );
00127 #else
00128
00129 # if defined (ACE_MVS) || defined (ACE_TANDEM_T1248_PTHREADS)
00130
00131
00132 ACE_OS::strcpy (fp, "u");
00133 ACE_OS::sprintf (thr_string, format, thread_handle_);
00134 # else
00135
00136
00137
00138
00139
00140
00141 ACE_OS::strcpy (fp, "lu");
00142 ACE_OS::sprintf (thr_string,
00143 format,
00144 (unsigned long) thread_handle_);
00145 # endif
00146
00147 #endif
00148 }
00149
00150
00151
00152 #if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION)
00153
00154 #if defined (ACE_HAS_TSS_EMULATION)
00155 u_int ACE_TSS_Emulation::total_keys_ = 0;
00156
00157 ACE_TSS_Keys* ACE_TSS_Emulation::tss_keys_used_ = 0;
00158
00159 ACE_TSS_Emulation::ACE_TSS_DESTRUCTOR
00160 ACE_TSS_Emulation::tss_destructor_[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX]
00161 = { 0 };
00162
00163 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
00164
00165 int ACE_TSS_Emulation::key_created_ = 0;
00166
00167 ACE_OS_thread_key_t ACE_TSS_Emulation::native_tss_key_;
00168
00169
00170 # if defined (ACE_HAS_THR_C_FUNC)
00171 extern "C"
00172 void
00173 ACE_TSS_Emulation_cleanup (void *ptr)
00174 {
00175 ACE_UNUSED_ARG (ptr);
00176
00177
00178 }
00179 # else
00180 void
00181 ACE_TSS_Emulation_cleanup (void *ptr)
00182 {
00183 ACE_UNUSED_ARG (ptr);
00184
00185
00186 }
00187 # endif
00188
00189 void **
00190 ACE_TSS_Emulation::tss_base (void* ts_storage[], u_int *ts_created)
00191 {
00192
00193
00194
00195 if (key_created_ == 0)
00196 {
00197
00198 ACE_TSS_BASE_GUARD
00199
00200 if (key_created_ == 0)
00201 {
00202 ACE_NO_HEAP_CHECK;
00203 if (ACE_OS::thr_keycreate_native (&native_tss_key_,
00204 &ACE_TSS_Emulation_cleanup) != 0)
00205 {
00206 ACE_ASSERT (0);
00207 return 0;
00208 }
00209 key_created_ = 1;
00210 }
00211 }
00212
00213 void **old_ts_storage = 0;
00214
00215
00216 if (ACE_OS::thr_getspecific_native (native_tss_key_,
00217 (void **) &old_ts_storage) == -1)
00218 {
00219 ACE_ASSERT (false);
00220 return 0;
00221 }
00222
00223
00224
00225
00226 if (old_ts_storage == 0)
00227 {
00228 if (ts_created)
00229 *ts_created = 1u;
00230
00231
00232
00233
00234
00235
00236 if (ts_storage == 0)
00237 {
00238 ACE_NO_HEAP_CHECK;
00239
00240 ACE_NEW_RETURN (ts_storage,
00241 void*[ACE_TSS_THREAD_KEYS_MAX],
00242 0);
00243
00244
00245
00246
00247 void **tss_base_p = ts_storage;
00248
00249 for (u_int i = 0;
00250 i < ACE_TSS_THREAD_KEYS_MAX;
00251 ++i)
00252 *tss_base_p++ = 0;
00253 }
00254
00255
00256
00257
00258 if (ACE_OS::thr_setspecific_native (native_tss_key_,
00259 (void *) ts_storage) != 0)
00260 {
00261 ACE_ASSERT (false);
00262 return 0;
00263 }
00264 }
00265 else
00266 if (ts_created)
00267 ts_created = 0;
00268
00269 return ts_storage ? ts_storage : old_ts_storage;
00270 }
00271 # endif
00272
00273 u_int
00274 ACE_TSS_Emulation::total_keys ()
00275 {
00276 ACE_OS_Recursive_Thread_Mutex_Guard (
00277 *static_cast <ACE_recursive_thread_mutex_t *>
00278 (ACE_OS_Object_Manager::preallocated_object[
00279 ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
00280
00281 return total_keys_;
00282 }
00283
00284 int
00285 ACE_TSS_Emulation::next_key (ACE_thread_key_t &key)
00286 {
00287 ACE_OS_Recursive_Thread_Mutex_Guard (
00288 *static_cast <ACE_recursive_thread_mutex_t *>
00289 (ACE_OS_Object_Manager::preallocated_object[
00290 ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
00291
00292
00293 if (tss_keys_used_ == 0)
00294 {
00295 ACE_NEW_RETURN (tss_keys_used_, ACE_TSS_Keys, -1);
00296 }
00297
00298 if (total_keys_ < ACE_TSS_THREAD_KEYS_MAX)
00299 {
00300 u_int counter = 0;
00301
00302 for ( ;counter < ACE_TSS_THREAD_KEYS_MAX; counter++)
00303 {
00304 ACE_thread_key_t localkey;
00305 # if defined (ACE_HAS_NONSCALAR_THREAD_KEY_T)
00306 ACE_OS::memset (&localkey, 0, sizeof (ACE_thread_key_t));
00307 ACE_OS::memcpy (&localkey, &counter_, sizeof (u_int));
00308 # else
00309 localkey = counter;
00310 # endif
00311
00312
00313 if (tss_keys_used_->is_set(localkey) == 0)
00314 {
00315 tss_keys_used_->test_and_set(localkey);
00316 key = localkey;
00317 break;
00318 }
00319 }
00320
00321 ++total_keys_;
00322 return 0;
00323 }
00324 else
00325 {
00326 key = ACE_OS::NULL_key;
00327 return -1;
00328 }
00329 }
00330
00331 int
00332 ACE_TSS_Emulation::release_key (ACE_thread_key_t key)
00333 {
00334 ACE_OS_Recursive_Thread_Mutex_Guard (
00335 *static_cast <ACE_recursive_thread_mutex_t *>
00336 (ACE_OS_Object_Manager::preallocated_object[
00337 ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
00338
00339 if (tss_keys_used_ != 0 &&
00340 tss_keys_used_->test_and_clear (key) == 0)
00341 {
00342 --total_keys_;
00343 return 0;
00344 }
00345 return 1;
00346 }
00347
00348 int
00349 ACE_TSS_Emulation::is_key (ACE_thread_key_t key)
00350 {
00351 ACE_OS_Recursive_Thread_Mutex_Guard (
00352 *static_cast <ACE_recursive_thread_mutex_t *>
00353 (ACE_OS_Object_Manager::preallocated_object[
00354 ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
00355
00356 if (tss_keys_used_ != 0 &&
00357 tss_keys_used_->is_set (key) == 1)
00358 {
00359 return 1;
00360 }
00361 return 0;
00362 }
00363
00364 void *
00365 ACE_TSS_Emulation::tss_open (void *ts_storage[ACE_TSS_THREAD_KEYS_MAX])
00366 {
00367 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
00368
00369
00370
00371
00372
00373 u_int ts_created = 0;
00374 tss_base (ts_storage, &ts_created);
00375 if (ts_created)
00376 {
00377 # else
00378 tss_base () = ts_storage;
00379 # endif
00380
00381
00382
00383 void **tss_base_p = tss_base ();
00384 for (u_int i = 0; i < ACE_TSS_THREAD_KEYS_MAX; ++i, ++tss_base_p)
00385 {
00386 *tss_base_p = 0;
00387 }
00388
00389 return tss_base ();
00390 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
00391 }
00392 else
00393 {
00394 return 0;
00395 }
00396 # endif
00397 }
00398
00399 void
00400 ACE_TSS_Emulation::tss_close ()
00401 {
00402 #if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
00403 ACE_OS::thr_keyfree_native (native_tss_key_);
00404 #endif
00405 }
00406
00407 #endif
00408
00409 #endif
00410
00411
00412
00413 #if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION)
00414
00415
00416
00417
00418 ACE_TSS_Ref::ACE_TSS_Ref (ACE_thread_t id)
00419 : tid_(id)
00420 {
00421 ACE_OS_TRACE ("ACE_TSS_Ref::ACE_TSS_Ref");
00422 }
00423
00424 ACE_TSS_Ref::ACE_TSS_Ref (void)
00425 {
00426 ACE_OS_TRACE ("ACE_TSS_Ref::ACE_TSS_Ref");
00427 }
00428
00429
00430 bool
00431 ACE_TSS_Ref::operator== (const ACE_TSS_Ref &info) const
00432 {
00433 ACE_OS_TRACE ("ACE_TSS_Ref::operator==");
00434
00435 return this->tid_ == info.tid_;
00436 }
00437
00438
00439 ACE_SPECIAL_INLINE
00440 bool
00441 ACE_TSS_Ref::operator != (const ACE_TSS_Ref &tss_ref) const
00442 {
00443 ACE_OS_TRACE ("ACE_TSS_Ref::operator !=");
00444
00445 return !(*this == tss_ref);
00446 }
00447
00448
00449
00450
00451
00452 ACE_TSS_Info::ACE_TSS_Info (ACE_thread_key_t key,
00453 ACE_TSS_Info::Destructor dest)
00454 : key_ (key),
00455 destructor_ (dest),
00456 thread_count_ (-1)
00457 {
00458 ACE_OS_TRACE ("ACE_TSS_Info::ACE_TSS_Info");
00459 }
00460
00461 ACE_TSS_Info::ACE_TSS_Info (void)
00462 : key_ (ACE_OS::NULL_key),
00463 destructor_ (0),
00464 thread_count_ (-1)
00465 {
00466 ACE_OS_TRACE ("ACE_TSS_Info::ACE_TSS_Info");
00467 }
00468
00469 # if defined (ACE_HAS_NONSCALAR_THREAD_KEY_T)
00470 static inline bool operator== (const ACE_thread_key_t &lhs,
00471 const ACE_thread_key_t &rhs)
00472 {
00473 return ! ACE_OS::memcmp (&lhs, &rhs, sizeof (ACE_thread_key_t));
00474 }
00475
00476 static inline bool operator!= (const ACE_thread_key_t &lhs,
00477 const ACE_thread_key_t &rhs)
00478 {
00479 return ! (lhs == rhs);
00480 }
00481 # endif
00482
00483
00484 bool
00485 ACE_TSS_Info::operator== (const ACE_TSS_Info &info) const
00486 {
00487 ACE_OS_TRACE ("ACE_TSS_Info::operator==");
00488
00489 return this->key_ == info.key_;
00490 }
00491
00492
00493 bool
00494 ACE_TSS_Info::operator != (const ACE_TSS_Info &info) const
00495 {
00496 ACE_OS_TRACE ("ACE_TSS_Info::operator !=");
00497
00498 return !(*this == info);
00499 }
00500
00501 void
00502 ACE_TSS_Info::dump (void)
00503 {
00504 # if defined (ACE_HAS_DUMP)
00505
00506
00507 # if 0
00508 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00509 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("key_ = %u\n"), this->key_));
00510 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("destructor_ = %u\n"), this->destructor_));
00511 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00512 # endif
00513 # endif
00514 }
00515
00516
00517
00518
00519 ACE_TSS_Keys::ACE_TSS_Keys (void)
00520 {
00521 for (u_int i = 0; i < ACE_WORDS; ++i)
00522 {
00523 key_bit_words_[i] = 0;
00524 }
00525 }
00526
00527 ACE_SPECIAL_INLINE
00528 void
00529 ACE_TSS_Keys::find (const u_int key, u_int &word, u_int &bit)
00530 {
00531 word = key / ACE_BITS_PER_WORD;
00532 bit = key % ACE_BITS_PER_WORD;
00533 }
00534
00535 int
00536 ACE_TSS_Keys::test_and_set (const ACE_thread_key_t key)
00537 {
00538 ACE_KEY_INDEX (key_index, key);
00539 u_int word, bit;
00540 find (key_index, word, bit);
00541
00542 if (ACE_BIT_ENABLED (key_bit_words_[word], 1 << bit))
00543 {
00544 return 1;
00545 }
00546 else
00547 {
00548 ACE_SET_BITS (key_bit_words_[word], 1 << bit);
00549 return 0;
00550 }
00551 }
00552
00553 int
00554 ACE_TSS_Keys::test_and_clear (const ACE_thread_key_t key)
00555 {
00556 ACE_KEY_INDEX (key_index, key);
00557 u_int word, bit;
00558 find (key_index, word, bit);
00559
00560 if (word < ACE_WORDS && ACE_BIT_ENABLED (key_bit_words_[word], 1 << bit))
00561 {
00562 ACE_CLR_BITS (key_bit_words_[word], 1 << bit);
00563 return 0;
00564 }
00565 else
00566 {
00567 return 1;
00568 }
00569 }
00570
00571 int
00572 ACE_TSS_Keys::is_set (const ACE_thread_key_t key) const
00573 {
00574 ACE_KEY_INDEX (key_index, key);
00575 u_int word, bit;
00576 find (key_index, word, bit);
00577
00578 return word < ACE_WORDS ? ACE_BIT_ENABLED (key_bit_words_[word], 1 << bit) : 0;
00579 }
00580
00581
00582
00583
00584
00585 class ACE_TSS_Cleanup
00586 {
00587 public:
00588
00589
00590
00591 int insert (ACE_thread_key_t key, void (*destructor)(void *));
00592
00593
00594 void thread_use_key (ACE_thread_key_t key);
00595
00596
00597
00598 int thread_detach_key (ACE_thread_key_t key);
00599
00600
00601
00602
00603
00604 int free_key (ACE_thread_key_t key);
00605
00606
00607
00608 void thread_exit (void);
00609
00610 private:
00611 void dump (void);
00612
00613
00614
00615
00616
00617 void thread_release (
00618 ACE_TSS_Info &info,
00619 ACE_TSS_Info::Destructor & destructor,
00620 void *& tss_obj);
00621
00622
00623
00624 int remove_key (ACE_TSS_Info &info);
00625
00626
00627
00628
00629 bool find_tss_keys (ACE_TSS_Keys *& thread_keys) const;
00630
00631
00632
00633 ACE_TSS_Keys *tss_keys ();
00634
00635
00636 ACE_TSS_Cleanup (void);
00637 ~ACE_TSS_Cleanup (void);
00638
00639
00640 friend class TSS_Cleanup_Instance;
00641
00642 private:
00643
00644 typedef ACE_TSS_Info ACE_TSS_TABLE[ACE_DEFAULT_THREAD_KEYS];
00645 typedef ACE_TSS_Info *ACE_TSS_TABLE_ITERATOR;
00646
00647
00648 ACE_TSS_TABLE table_;
00649
00650
00651
00652
00653
00654 ACE_thread_key_t in_use_;
00655 };
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 class TSS_Cleanup_Instance
00677 {
00678 public:
00679 enum Purpose
00680 {
00681 CREATE,
00682 USE,
00683 DESTROY
00684 };
00685 TSS_Cleanup_Instance (Purpose purpose = USE);
00686 ~TSS_Cleanup_Instance();
00687
00688 bool valid();
00689 ACE_TSS_Cleanup * operator ->();
00690
00691 private:
00692
00693 ACE_TSS_Cleanup * operator *();
00694
00695 private:
00696 static unsigned int reference_count_;
00697 static ACE_TSS_Cleanup * instance_;
00698 static ACE_Thread_Mutex* mutex_;
00699 static ACE_Thread_Condition<ACE_Thread_Mutex>* condition_;
00700
00701 private:
00702 ACE_TSS_Cleanup * ptr_;
00703 unsigned short flags_;
00704 enum
00705 {
00706 FLAG_DELETING = 1,
00707 FLAG_VALID_CHECKED = 2
00708 };
00709 };
00710
00711 TSS_Cleanup_Instance::TSS_Cleanup_Instance (Purpose purpose)
00712 : ptr_(0)
00713 , flags_(0)
00714 {
00715
00716
00717
00718
00719 if (mutex_ == 0)
00720 {
00721 ACE_NEW (mutex_, ACE_Thread_Mutex ());
00722 ACE_NEW (condition_, ACE_Thread_Condition<ACE_Thread_Mutex> (*mutex_));
00723 }
00724
00725 ACE_Guard<ACE_Thread_Mutex> guard(*mutex_);
00726
00727 if (purpose == CREATE)
00728 {
00729 if (instance_ == 0)
00730 {
00731 instance_ = new ACE_TSS_Cleanup();
00732 }
00733 ptr_ = instance_;
00734 ++reference_count_;
00735 }
00736 else if(purpose == DESTROY)
00737 {
00738 if (instance_ != 0)
00739 {
00740 ptr_ = instance_;
00741 instance_ = 0;
00742 ACE_SET_BITS(flags_, FLAG_DELETING);
00743 while (reference_count_ > 0)
00744 {
00745 condition_->wait();
00746 }
00747 }
00748 }
00749 else
00750 {
00751 ACE_ASSERT(purpose == USE);
00752 if (instance_ != 0)
00753 {
00754 ptr_ = instance_;
00755 ++reference_count_;
00756 }
00757 }
00758 }
00759
00760 TSS_Cleanup_Instance::~TSS_Cleanup_Instance (void)
00761 {
00762
00763
00764 ACE_Thread_Mutex *del_mutex = 0;
00765
00766
00767 {
00768 ACE_Guard<ACE_Thread_Mutex> guard (*mutex_);
00769 if (ptr_ != 0)
00770 {
00771 if (ACE_BIT_ENABLED (flags_, FLAG_DELETING))
00772 {
00773 ACE_ASSERT(instance_ == 0);
00774 ACE_ASSERT(reference_count_ == 0);
00775 delete ptr_;
00776 del_mutex = mutex_ ;
00777 mutex_ = 0;
00778 }
00779 else
00780 {
00781 ACE_ASSERT (reference_count_ > 0);
00782 --reference_count_;
00783 if (reference_count_ == 0 && instance_ == NULL)
00784 condition_->signal ();
00785 }
00786 }
00787 }
00788
00789 if (del_mutex != 0)
00790 {
00791 delete condition_;
00792 condition_ = 0;
00793 delete del_mutex;
00794 }
00795 }
00796
00797 bool
00798 TSS_Cleanup_Instance::valid()
00799 {
00800 ACE_SET_BITS(flags_, FLAG_VALID_CHECKED);
00801 return (this->instance_ != NULL);
00802 }
00803
00804 ACE_TSS_Cleanup *
00805 TSS_Cleanup_Instance::operator *()
00806 {
00807 ACE_ASSERT(ACE_BIT_ENABLED(flags_, FLAG_VALID_CHECKED));
00808 return instance_;
00809 }
00810
00811 ACE_TSS_Cleanup *
00812 TSS_Cleanup_Instance::operator ->()
00813 {
00814 ACE_ASSERT(ACE_BIT_ENABLED(flags_, FLAG_VALID_CHECKED));
00815 return instance_;
00816 }
00817
00818
00819 unsigned int TSS_Cleanup_Instance::reference_count_ = 0;
00820 ACE_TSS_Cleanup * TSS_Cleanup_Instance::instance_ = 0;
00821 ACE_Thread_Mutex* TSS_Cleanup_Instance::mutex_ = 0;
00822 ACE_Thread_Condition<ACE_Thread_Mutex>* TSS_Cleanup_Instance::condition_ = 0;
00823
00824 ACE_TSS_Cleanup::~ACE_TSS_Cleanup (void)
00825 {
00826 }
00827
00828 void
00829 ACE_TSS_Cleanup::thread_exit (void)
00830 {
00831 ACE_OS_TRACE ("ACE_TSS_Cleanup::thread_exit");
00832
00833
00834
00835 ACE_TSS_Info::Destructor destructor[ACE_DEFAULT_THREAD_KEYS];
00836 void * tss_obj[ACE_DEFAULT_THREAD_KEYS];
00837
00838 unsigned int d_count = 0;
00839
00840
00841 {
00842 ACE_TSS_CLEANUP_GUARD
00843
00844
00845 ACE_TSS_Keys *this_thread_keys = 0;
00846 if (! find_tss_keys (this_thread_keys) )
00847 {
00848 return;
00849 }
00850
00851
00852
00853
00854
00855
00856 unsigned int key_index = ACE_DEFAULT_THREAD_KEYS;
00857 while( key_index > 0)
00858 {
00859 --key_index;
00860 ACE_TSS_Info & info = this->table_[key_index];
00861
00862 if (info.key_in_use () && this_thread_keys->is_set(info.key_))
00863 {
00864
00865 if(info.key_ != this->in_use_)
00866 {
00867 destructor[d_count] = 0;
00868 tss_obj[d_count] = 0;
00869 this->thread_release (info, destructor[d_count], tss_obj[d_count]);
00870 if (destructor[d_count] != 0 && tss_obj[d_count] != 0)
00871 {
00872 ++d_count;
00873 }
00874 }
00875 }
00876 }
00877
00878
00879 ACE_KEY_INDEX (use_index, this->in_use_);
00880 ACE_TSS_Info & info = this->table_[use_index];
00881 destructor[d_count] = 0;
00882 tss_obj[d_count] = 0;
00883 this->thread_release (info, destructor[d_count], tss_obj[d_count]);
00884 if (destructor[d_count] != 0 && tss_obj[d_count] != 0)
00885 {
00886 ++d_count;
00887 }
00888 #if defined (ACE_HAS_TSS_EMULATION)
00889 ACE_TSS_Emulation::ts_object (this->in_use_) = 0;
00890 #else // defined (ACE_HAS_TSS_EMULATION)
00891 ACE_OS::thr_setspecific_native (info.key_, 0);
00892 #endif // defined (ACE_HAS_TSS_EMULATION)
00893
00894 }
00895 for (unsigned int d_index = 0; d_index < d_count; ++d_index)
00896 {
00897 (*destructor[d_index])(tss_obj[d_index]);
00898 }
00899 }
00900
00901 extern "C" void
00902 ACE_TSS_Cleanup_keys_destroyer (void *tss_keys)
00903 {
00904 delete static_cast <ACE_TSS_Keys *> (tss_keys);
00905 }
00906
00907 ACE_TSS_Cleanup::ACE_TSS_Cleanup (void)
00908 : in_use_ (ACE_OS::NULL_key)
00909 {
00910 ACE_OS_TRACE ("ACE_TSS_Cleanup::ACE_TSS_Cleanup");
00911 }
00912
00913 int
00914 ACE_TSS_Cleanup::insert (ACE_thread_key_t key,
00915 void (*destructor)(void *))
00916 {
00917 ACE_OS_TRACE ("ACE_TSS_Cleanup::insert");
00918 ACE_TSS_CLEANUP_GUARD
00919
00920 ACE_KEY_INDEX (key_index, key);
00921 ACE_ASSERT (key_index < ACE_DEFAULT_THREAD_KEYS);
00922 if (key_index < ACE_DEFAULT_THREAD_KEYS)
00923 {
00924 ACE_ASSERT (table_[key_index].thread_count_ == -1);
00925 table_[key_index] = ACE_TSS_Info (key, destructor);
00926 table_[key_index].thread_count_ = 0;
00927
00928 return 0;
00929 }
00930 else
00931 {
00932 return -1;
00933 }
00934 }
00935
00936 int
00937 ACE_TSS_Cleanup::free_key (ACE_thread_key_t key)
00938 {
00939 ACE_OS_TRACE ("ACE_TSS_Cleanup::free_key");
00940 ACE_TSS_CLEANUP_GUARD
00941 ACE_KEY_INDEX (key_index, key);
00942 if (key_index < ACE_DEFAULT_THREAD_KEYS)
00943 {
00944 return remove_key (this->table_ [key_index]);
00945 }
00946 return -1;
00947 }
00948
00949 int
00950 ACE_TSS_Cleanup::remove_key (ACE_TSS_Info &info)
00951 {
00952
00953 ACE_OS_TRACE ("ACE_TSS_Cleanup::remove_key");
00954
00955 #if 0 // This was a good idea, but POSIX says it's legal to delete used keys.
00956
00957
00958
00959
00960 if (info.thread_count_ != 0)
00961 {
00962 return -1;
00963 }
00964 #endif // 0
00965
00966 #if !defined (ACE_HAS_TSS_EMULATION)
00967 ACE_OS_thread_key_t temp_key = info.key_;
00968 ACE_OS::thr_keyfree_native (temp_key);
00969 #endif
00970 if (info.key_ == this->in_use_)
00971 {
00972 this->in_use_ = ACE_OS::NULL_key;
00973 }
00974 info.key_in_use (0);
00975 info.destructor_ = 0;
00976 return 0;
00977 }
00978
00979 int
00980 ACE_TSS_Cleanup::thread_detach_key (ACE_thread_key_t key)
00981 {
00982
00983
00984 ACE_TSS_Info::Destructor destructor = 0;
00985 void * tss_obj = 0;
00986
00987
00988 {
00989 ACE_TSS_CLEANUP_GUARD
00990
00991 ACE_KEY_INDEX (key_index, key);
00992 ACE_ASSERT (key_index < sizeof(this->table_)/sizeof(this->table_[0])
00993 && this->table_[key_index].key_ == key);
00994 ACE_TSS_Info &info = this->table_ [key_index];
00995
00996
00997 if (!info.key_in_use ())
00998 {
00999 return -1;
01000 }
01001
01002 this->thread_release (info, destructor, tss_obj);
01003 }
01004
01005 if (destructor != 0 && tss_obj != 0)
01006 {
01007 (*destructor) (tss_obj);
01008 }
01009 return 0;
01010 }
01011
01012 void
01013 ACE_TSS_Cleanup::thread_release (
01014 ACE_TSS_Info &info,
01015 ACE_TSS_Info::Destructor & destructor,
01016 void *& tss_obj)
01017 {
01018
01019
01020
01021 ACE_TSS_Keys * thread_keys = 0;
01022 if (find_tss_keys (thread_keys))
01023 {
01024
01025 if (thread_keys->test_and_clear(info.key_) == 0)
01026 {
01027
01028
01029 destructor = info.destructor_;
01030 ACE_OS::thr_getspecific (info.key_, &tss_obj);
01031 ACE_ASSERT (info.thread_count_ > 0);
01032 --info.thread_count_;
01033 }
01034 }
01035 }
01036
01037 void
01038 ACE_TSS_Cleanup::thread_use_key (ACE_thread_key_t key)
01039 {
01040
01041
01042 if (! tss_keys ()->test_and_set (key))
01043 {
01044 ACE_TSS_CLEANUP_GUARD
01045
01046
01047 ACE_KEY_INDEX (key_index, key);
01048 ACE_TSS_Info &key_info = this->table_ [key_index];
01049
01050 ACE_ASSERT (key_info.key_in_use ());
01051 ++key_info.thread_count_;
01052 }
01053 }
01054
01055 void
01056 ACE_TSS_Cleanup::dump (void)
01057 {
01058 # if defined (ACE_HAS_DUMP)
01059
01060
01061 ACE_TSS_TABLE_ITERATOR key_info = table_;
01062 for (unsigned int i = 0;
01063 i < ACE_DEFAULT_THREAD_KEYS;
01064 ++key_info, ++i)
01065 key_info->dump ();
01066 # endif
01067 }
01068
01069 bool
01070 ACE_TSS_Cleanup::find_tss_keys (ACE_TSS_Keys *& tss_keys) const
01071 {
01072 if (this->in_use_ == ACE_OS::NULL_key)
01073 return false;
01074 if (ACE_OS::thr_getspecific (in_use_,
01075 reinterpret_cast<void **> (&tss_keys)) == -1)
01076 {
01077 ACE_ASSERT (false);
01078 return false;
01079 }
01080 return tss_keys != 0;
01081 }
01082
01083 ACE_TSS_Keys *
01084 ACE_TSS_Cleanup::tss_keys ()
01085 {
01086 if (this->in_use_ == ACE_OS::NULL_key)
01087 {
01088 ACE_TSS_CLEANUP_GUARD
01089
01090 if (in_use_ == ACE_OS::NULL_key)
01091 {
01092
01093 if (ACE_OS::thr_keycreate (&in_use_,
01094 &ACE_TSS_Cleanup_keys_destroyer))
01095 {
01096 ACE_ASSERT (false);
01097 return 0;
01098 }
01099 }
01100 }
01101
01102 ACE_TSS_Keys *ts_keys = 0;
01103 if (ACE_OS::thr_getspecific (in_use_,
01104 reinterpret_cast <void **> (&ts_keys)) == -1)
01105 {
01106 ACE_ASSERT (false);
01107 return 0;
01108 }
01109
01110 if (ts_keys == 0)
01111 {
01112 ACE_NEW_RETURN (ts_keys,
01113 ACE_TSS_Keys,
01114 0);
01115
01116
01117 if (ACE_OS::thr_setspecific (in_use_,
01118 reinterpret_cast <void *> (ts_keys)) == -1)
01119 {
01120 ACE_ASSERT (false);
01121 delete ts_keys;
01122 return 0;
01123 }
01124 }
01125
01126 return ts_keys;
01127 }
01128
01129 #endif
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 ACE_thread_t ACE_OS::NULL_thread;
01142 ACE_hthread_t ACE_OS::NULL_hthread;
01143 #if defined (ACE_HAS_TSS_EMULATION)
01144 ACE_thread_key_t ACE_OS::NULL_key = static_cast <ACE_thread_key_t> (-1);
01145 #else
01146 ACE_thread_key_t ACE_OS::NULL_key;
01147 #endif
01148
01149
01150
01151 void
01152 ACE_OS::cleanup_tss (const u_int main_thread)
01153 {
01154 #if defined (ACE_HAS_TSS_EMULATION) || defined (ACE_WIN32)
01155 {
01156
01157 TSS_Cleanup_Instance cleanup;
01158 if (cleanup.valid ())
01159 {
01160 cleanup->thread_exit ();
01161 }
01162 }
01163 #endif
01164
01165 if (main_thread)
01166 {
01167 #if !defined (ACE_HAS_TSS_EMULATION) && !defined (ACE_HAS_MINIMAL_ACE_OS)
01168
01169
01170
01171
01172 ACE_Base_Thread_Adapter::close_log_msg ();
01173 #endif
01174
01175 #if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION)
01176
01177
01178 TSS_Cleanup_Instance cleanup(TSS_Cleanup_Instance::DESTROY);
01179 if (cleanup.valid ())
01180 {
01181 ;
01182 }
01183
01184 #endif
01185
01186 #if defined (ACE_HAS_TSS_EMULATION)
01187 ACE_TSS_Emulation::tss_close ();
01188 #endif
01189 }
01190 }
01191
01192
01193
01194
01195
01196 #if defined (ACE_LACKS_COND_T)
01197
01198
01199
01200
01201
01202
01203 int
01204 ACE_OS::condattr_init (ACE_condattr_t &attributes,
01205 int type)
01206 {
01207 attributes.type = type;
01208 return 0;
01209 }
01210
01211 int
01212 ACE_OS::condattr_destroy (ACE_condattr_t &)
01213 {
01214 return 0;
01215 }
01216
01217 int
01218 ACE_OS::cond_broadcast (ACE_cond_t *cv)
01219 {
01220 ACE_OS_TRACE ("ACE_OS::cond_broadcast");
01221 # if defined (ACE_HAS_THREADS)
01222
01223
01224
01225
01226 ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
01227 int have_waiters = 0;
01228
01229 if (cv->waiters_ > 0)
01230 {
01231
01232
01233
01234
01235 cv->was_broadcast_ = 1;
01236 have_waiters = 1;
01237 }
01238 ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
01239 int result = 0;
01240 if (have_waiters)
01241 {
01242
01243 if (ACE_OS::sema_post (&cv->sema_, cv->waiters_) == -1)
01244 result = -1;
01245
01246
01247 # if defined (ACE_VXWORKS)
01248 else if (ACE_OS::sema_wait (&cv->waiters_done_) == -1)
01249 # else
01250 else if (ACE_OS::event_wait (&cv->waiters_done_) == -1)
01251 # endif
01252 result = -1;
01253
01254
01255 cv->was_broadcast_ = 0;
01256 }
01257 return result;
01258 # else
01259 ACE_UNUSED_ARG (cv);
01260 ACE_NOTSUP_RETURN (-1);
01261 # endif
01262 }
01263
01264 int
01265 ACE_OS::cond_destroy (ACE_cond_t *cv)
01266 {
01267 ACE_OS_TRACE ("ACE_OS::cond_destroy");
01268 # if defined (ACE_HAS_THREADS)
01269 # if defined (ACE_HAS_WTHREADS)
01270 ACE_OS::event_destroy (&cv->waiters_done_);
01271 # elif defined (ACE_VXWORKS)
01272 ACE_OS::sema_destroy (&cv->waiters_done_);
01273 # endif
01274 ACE_OS::thread_mutex_destroy (&cv->waiters_lock_);
01275 return ACE_OS::sema_destroy (&cv->sema_);
01276 # else
01277 ACE_UNUSED_ARG (cv);
01278 ACE_NOTSUP_RETURN (-1);
01279 # endif
01280 }
01281
01282 int
01283 ACE_OS::cond_init (ACE_cond_t *cv,
01284 ACE_condattr_t &attributes,
01285 const char *name, void *arg)
01286 {
01287 return
01288 ACE_OS::cond_init (cv, static_cast<short> (attributes.type), name, arg);
01289 }
01290
01291 # if defined (ACE_HAS_WCHAR)
01292 int
01293 ACE_OS::cond_init (ACE_cond_t *cv,
01294 ACE_condattr_t &attributes,
01295 const wchar_t *name, void *arg)
01296 {
01297 return
01298 ACE_OS::cond_init (cv, static_cast<short> (attributes.type), name, arg);
01299 }
01300 # endif
01301
01302 int
01303 ACE_OS::cond_init (ACE_cond_t *cv, short type, const char *name, void *arg)
01304 {
01305 ACE_OS_TRACE ("ACE_OS::cond_init");
01306 # if defined (ACE_HAS_THREADS)
01307 cv->waiters_ = 0;
01308 cv->was_broadcast_ = 0;
01309
01310 int result = 0;
01311 if (ACE_OS::sema_init (&cv->sema_, 0, type, name, arg) == -1)
01312 result = -1;
01313 else if (ACE_OS::thread_mutex_init (&cv->waiters_lock_) == -1)
01314 result = -1;
01315 # if defined (ACE_VXWORKS)
01316 else if (ACE_OS::sema_init (&cv->waiters_done_, 0, type) == -1)
01317 # else
01318 else if (ACE_OS::event_init (&cv->waiters_done_) == -1)
01319 # endif
01320 result = -1;
01321 return result;
01322 # else
01323 ACE_UNUSED_ARG (cv);
01324 ACE_UNUSED_ARG (type);
01325 ACE_UNUSED_ARG (name);
01326 ACE_UNUSED_ARG (arg);
01327 ACE_NOTSUP_RETURN (-1);
01328 # endif
01329 }
01330
01331 # if defined (ACE_HAS_WCHAR)
01332 int
01333 ACE_OS::cond_init (ACE_cond_t *cv, short type, const wchar_t *name, void *arg)
01334 {
01335 ACE_OS_TRACE ("ACE_OS::cond_init");
01336 # if defined (ACE_HAS_THREADS)
01337 cv->waiters_ = 0;
01338 cv->was_broadcast_ = 0;
01339
01340 int result = 0;
01341 if (ACE_OS::sema_init (&cv->sema_, 0, type, name, arg) == -1)
01342 result = -1;
01343 else if (ACE_OS::thread_mutex_init (&cv->waiters_lock_) == -1)
01344 result = -1;
01345 # if defined (ACE_VXWORKS)
01346 else if (ACE_OS::sema_init (&cv->waiters_done_, 0, type) == -1)
01347 # else
01348 else if (ACE_OS::event_init (&cv->waiters_done_) == -1)
01349 # endif
01350 result = -1;
01351 return result;
01352 # else
01353 ACE_UNUSED_ARG (cv);
01354 ACE_UNUSED_ARG (type);
01355 ACE_UNUSED_ARG (name);
01356 ACE_UNUSED_ARG (arg);
01357 ACE_NOTSUP_RETURN (-1);
01358 # endif
01359 }
01360 # endif
01361
01362 int
01363 ACE_OS::cond_signal (ACE_cond_t *cv)
01364 {
01365 ACE_OS_TRACE ("ACE_OS::cond_signal");
01366 # if defined (ACE_HAS_THREADS)
01367
01368
01369
01370
01371
01372
01373 ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
01374 int have_waiters = cv->waiters_ > 0;
01375 ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
01376
01377 if (have_waiters != 0)
01378 return ACE_OS::sema_post (&cv->sema_);
01379 else
01380 return 0;
01381 # else
01382 ACE_UNUSED_ARG (cv);
01383 ACE_NOTSUP_RETURN (-1);
01384 # endif
01385 }
01386
01387 int
01388 ACE_OS::cond_wait (ACE_cond_t *cv,
01389 ACE_mutex_t *external_mutex)
01390 {
01391 ACE_OS_TRACE ("ACE_OS::cond_wait");
01392 # if defined (ACE_HAS_THREADS)
01393
01394 ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
01395 cv->waiters_++;
01396 ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
01397
01398 int result = 0;
01399
01400 # if defined (ACE_HAS_SIGNAL_OBJECT_AND_WAIT)
01401 if (external_mutex->type_ == USYNC_PROCESS)
01402
01403 ACE_WIN32CALL (ACE_ADAPT_RETVAL (::SignalObjectAndWait (external_mutex->proc_mutex_,
01404 cv->sema_, INFINITE, FALSE),
01405 result),
01406 int, -1, result);
01407 else
01408 # endif
01409 {
01410
01411
01412
01413
01414 if (ACE_OS::mutex_unlock (external_mutex) != 0)
01415 return -1;
01416
01417
01418
01419 result = ACE_OS::sema_wait (&cv->sema_);
01420 }
01421
01422
01423 ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
01424
01425
01426 cv->waiters_--;
01427
01428 int last_waiter = cv->was_broadcast_ && cv->waiters_ == 0;
01429
01430
01431
01432 ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
01433
01434 if (result == -1)
01435
01436 ;
01437 # if defined (ACE_HAS_SIGNAL_OBJECT_AND_WAIT)
01438 else if (external_mutex->type_ == USYNC_PROCESS)
01439 {
01440 if (last_waiter)
01441
01442
01443
01444
01445 ACE_WIN32CALL (ACE_ADAPT_RETVAL (::SignalObjectAndWait (cv->waiters_done_,
01446 external_mutex->proc_mutex_,
01447 INFINITE, FALSE),
01448 result),
01449 int, -1, result);
01450 else
01451
01452
01453
01454 ACE_OS::mutex_lock (external_mutex);
01455
01456 return result;
01457
01458 }
01459 # endif
01460
01461
01462 else if (last_waiter)
01463 # if defined (ACE_VXWORKS)
01464 ACE_OS::sema_post (&cv->waiters_done_);
01465 # else
01466 ACE_OS::event_signal (&cv->waiters_done_);
01467 # endif
01468
01469
01470
01471 ACE_OS::mutex_lock (external_mutex);
01472
01473 return result;
01474 # else
01475 ACE_UNUSED_ARG (cv);
01476 ACE_UNUSED_ARG (external_mutex);
01477 ACE_NOTSUP_RETURN (-1);
01478 # endif
01479 }
01480
01481 int
01482 ACE_OS::cond_timedwait (ACE_cond_t *cv,
01483 ACE_mutex_t *external_mutex,
01484 ACE_Time_Value *timeout)
01485 {
01486 ACE_OS_TRACE ("ACE_OS::cond_timedwait");
01487 # if defined (ACE_HAS_THREADS)
01488
01489 if (timeout == 0)
01490 return ACE_OS::cond_wait (cv, external_mutex);
01491 # if defined (ACE_HAS_WTHREADS) || defined (ACE_VXWORKS)
01492
01493
01494 ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
01495 cv->waiters_++;
01496 ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
01497
01498 int result = 0;
01499 ACE_Errno_Guard error (errno, 0);
01500 int msec_timeout;
01501
01502 if (timeout->sec () == 0 && timeout->usec () == 0)
01503 msec_timeout = 0;
01504 else
01505 {
01506
01507
01508
01509 ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ());
01510
01511
01512
01513 if (relative_time < ACE_Time_Value::zero)
01514 msec_timeout = 0;
01515 else
01516 msec_timeout = relative_time.msec ();
01517 }
01518
01519 # if defined (ACE_HAS_SIGNAL_OBJECT_AND_WAIT)
01520 if (external_mutex->type_ == USYNC_PROCESS)
01521
01522
01523 result = ::SignalObjectAndWait (external_mutex->proc_mutex_,
01524 cv->sema_,
01525 msec_timeout,
01526 FALSE);
01527 else
01528 # endif
01529 {
01530
01531
01532
01533
01534 if (ACE_OS::mutex_unlock (external_mutex) != 0)
01535 return -1;
01536
01537
01538
01539 # if defined (ACE_WIN32)
01540 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
01541 result = ::WaitForSingleObject (cv->sema_, msec_timeout);
01542 # else
01543
01544 result = ACE_OS::sema_wait (&cv->sema_,
01545 timeout);
01546 # endif
01547 # elif defined (ACE_VXWORKS)
01548
01549
01550 int ticks_per_sec = ::sysClkRateGet ();
01551 int ticks = msec_timeout * ticks_per_sec / ACE_ONE_SECOND_IN_MSECS;
01552 result = ::semTake (cv->sema_.sema_, ticks);
01553 # endif
01554 }
01555
01556
01557 ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
01558 cv->waiters_--;
01559
01560 int last_waiter = cv->was_broadcast_ && cv->waiters_ == 0;
01561
01562 ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
01563
01564 # if defined (ACE_WIN32)
01565 if (result != WAIT_OBJECT_0)
01566 {
01567 switch (result)
01568 {
01569 case WAIT_TIMEOUT:
01570 error = ETIME;
01571 break;
01572 default:
01573 error = ::GetLastError ();
01574 break;
01575 }
01576 result = -1;
01577 }
01578 # elif defined (ACE_VXWORKS)
01579 if (result == ERROR)
01580 {
01581 switch (errno)
01582 {
01583 case S_objLib_OBJ_TIMEOUT:
01584 error = ETIME;
01585 break;
01586 case S_objLib_OBJ_UNAVAILABLE:
01587 if (msec_timeout == 0)
01588 error = ETIME;
01589 break;
01590 default:
01591 error = errno;
01592 break;
01593 }
01594 result = -1;
01595 }
01596 # endif
01597 # if defined (ACE_HAS_SIGNAL_OBJECT_AND_WAIT)
01598 if (external_mutex->type_ == USYNC_PROCESS)
01599 {
01600 if (last_waiter)
01601
01602
01603
01604 ACE_WIN32CALL (ACE_ADAPT_RETVAL (::SignalObjectAndWait (cv->waiters_done_,
01605 external_mutex->proc_mutex_,
01606 INFINITE, FALSE),
01607 result),
01608 int, -1, result);
01609 else
01610
01611
01612
01613 ACE_OS::mutex_lock (external_mutex);
01614
01615 return result;
01616
01617 }
01618 # endif
01619
01620
01621
01622 if (last_waiter)
01623
01624 # if defined (ACE_WIN32)
01625 ACE_OS::event_signal (&cv->waiters_done_);
01626 # else
01627 ACE_OS::sema_post (&cv->waiters_done_);
01628 # endif
01629
01630
01631
01632 ACE_OS::mutex_lock (external_mutex);
01633
01634 return result;
01635 # endif
01636 # else
01637 ACE_UNUSED_ARG (cv);
01638 ACE_UNUSED_ARG (external_mutex);
01639 ACE_UNUSED_ARG (timeout);
01640 ACE_NOTSUP_RETURN (-1);
01641 # endif
01642 }
01643
01644 # if defined (ACE_HAS_WTHREADS)
01645 int
01646 ACE_OS::cond_timedwait (ACE_cond_t *cv,
01647 ACE_thread_mutex_t *external_mutex,
01648 ACE_Time_Value *timeout)
01649 {
01650 ACE_OS_TRACE ("ACE_OS::cond_timedwait");
01651 # if defined (ACE_HAS_THREADS)
01652
01653 if (timeout == 0)
01654 return ACE_OS::cond_wait (cv, external_mutex);
01655
01656
01657 ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
01658 cv->waiters_++;
01659 ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
01660
01661 int result = 0;
01662 int error = 0;
01663 int msec_timeout;
01664
01665 if (timeout->sec () == 0 && timeout->usec () == 0)
01666 msec_timeout = 0;
01667 else
01668 {
01669
01670
01671
01672 ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ());
01673
01674
01675
01676 if (relative_time < ACE_Time_Value::zero)
01677 msec_timeout = 0;
01678 else
01679 msec_timeout = relative_time.msec ();
01680 }
01681
01682
01683
01684
01685
01686 if (ACE_OS::thread_mutex_unlock (external_mutex) != 0)
01687 return -1;
01688
01689
01690 # if defined (ACE_USES_WINCE_SEMA_SIMULATION)
01691
01692 result = ACE_OS::sema_wait (&cv->sema_,
01693 timeout);
01694
01695 if (result == -1 && errno == ETIME)
01696 result = WAIT_TIMEOUT;
01697 # else
01698 result = ::WaitForSingleObject (cv->sema_, msec_timeout);
01699 # endif
01700
01701
01702 ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
01703
01704 cv->waiters_--;
01705
01706 int last_waiter = cv->was_broadcast_ && cv->waiters_ == 0;
01707
01708 ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
01709
01710 if (result != WAIT_OBJECT_0)
01711 {
01712 switch (result)
01713 {
01714 case WAIT_TIMEOUT:
01715 error = ETIME;
01716 break;
01717 default:
01718 error = ::GetLastError ();
01719 break;
01720 }
01721 result = -1;
01722 }
01723
01724 if (last_waiter)
01725
01726 ACE_OS::event_signal (&cv->waiters_done_);
01727
01728
01729
01730 ACE_OS::thread_mutex_lock (external_mutex);
01731 errno = error;
01732 return result;
01733 # else
01734 ACE_NOTSUP_RETURN (-1);
01735 # endif
01736 }
01737
01738 int
01739 ACE_OS::cond_wait (ACE_cond_t *cv,
01740 ACE_thread_mutex_t *external_mutex)
01741 {
01742 ACE_OS_TRACE ("ACE_OS::cond_wait");
01743 # if defined (ACE_HAS_THREADS)
01744 ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
01745 cv->waiters_++;
01746 ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
01747
01748 int result = 0;
01749 int error = 0;
01750
01751
01752
01753
01754
01755 if (ACE_OS::thread_mutex_unlock (external_mutex) != 0)
01756 return -1;
01757
01758
01759
01760 # if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
01761 result = ::WaitForSingleObject (cv->sema_, INFINITE);
01762 # else
01763
01764 result = ACE_OS::sema_wait (&cv->sema_);
01765
01766 if (result != WAIT_OBJECT_0 && errno == ETIME)
01767 result = WAIT_TIMEOUT;
01768
01769 # endif
01770
01771
01772 ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
01773
01774 cv->waiters_--;
01775
01776 int last_waiter = cv->was_broadcast_ && cv->waiters_ == 0;
01777
01778 ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
01779
01780 if (result != WAIT_OBJECT_0)
01781 {
01782 switch (result)
01783 {
01784 case WAIT_TIMEOUT:
01785 error = ETIME;
01786 break;
01787 default:
01788 error = ::GetLastError ();
01789 break;
01790 }
01791 }
01792 else if (last_waiter)
01793
01794 ACE_OS::event_signal (&cv->waiters_done_);
01795
01796
01797
01798 ACE_OS::thread_mutex_lock (external_mutex);
01799
01800
01801 errno = error;
01802 return result;
01803 # else
01804 ACE_NOTSUP_RETURN (-1);
01805 # endif
01806 }
01807 # endif
01808 #else
01809 int
01810 ACE_OS::cond_init (ACE_cond_t *cv, short type, const char *name, void *arg)
01811 {
01812 ACE_condattr_t attributes;
01813 if (ACE_OS::condattr_init (attributes, type) == 0
01814 && ACE_OS::cond_init (cv, attributes, name, arg) == 0)
01815 {
01816 (void) ACE_OS::condattr_destroy (attributes);
01817 return 0;
01818 }
01819 return -1;
01820 }
01821 #endif
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831 int
01832 ACE_OS::mutex_init (ACE_mutex_t *m,
01833 int lock_scope,
01834 const char *name,
01835 ACE_mutexattr_t *attributes,
01836 LPSECURITY_ATTRIBUTES sa,
01837 int lock_type)
01838 {
01839
01840 #if defined (ACE_HAS_THREADS)
01841 # if defined (ACE_HAS_PTHREADS)
01842 ACE_UNUSED_ARG (name);
01843 ACE_UNUSED_ARG (sa);
01844
01845 # if defined (ACE_VXWORKS) && (ACE_VXWORKS >= 0x600) && (ACE_VXWORKS <= 0x620)
01846
01847
01848
01849
01850 pthread_mutexattr_t l_attributes = {0};
01851 # else
01852 pthread_mutexattr_t l_attributes;
01853 # endif
01854
01855 if (attributes == 0)
01856 attributes = &l_attributes;
01857 int result = 0;
01858 int attr_init = 0;
01859
01860
01861
01862 if (attributes == &l_attributes)
01863 {
01864 # if defined (ACE_HAS_PTHREADS_DRAFT4)
01865 if (::pthread_mutexattr_create (attributes) == 0)
01866 # elif defined (ACE_HAS_PTHREADS_DRAFT7) || defined (ACE_HAS_PTHREADS_STD)
01867 if (ACE_ADAPT_RETVAL (::pthread_mutexattr_init (attributes), result) == 0)
01868 # else
01869 if (::pthread_mutexattr_init (attributes) == 0)
01870 # endif
01871 {
01872 result = 0;
01873 attr_init = 1;
01874 }
01875 else
01876 result = -1;
01877 }
01878
01879 if (result == 0 && lock_scope != 0)
01880 {
01881 # if defined (ACE_HAS_PTHREADS_DRAFT7) || defined (ACE_HAS_PTHREADS_STD)
01882 # if defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_MUTEXATTR_PSHARED)
01883 (void) ACE_ADAPT_RETVAL (::pthread_mutexattr_setpshared (attributes,
01884 lock_scope),
01885 result);
01886 # endif
01887 # else
01888 # if !defined (ACE_LACKS_MUTEXATTR_PSHARED)
01889 if (::pthread_mutexattr_setpshared (attributes, lock_scope) != 0)
01890 result = -1;
01891 # endif
01892 # endif
01893 }
01894
01895 if (result == 0 && lock_type != 0)
01896 {
01897 # if defined (ACE_HAS_PTHREADS_DRAFT4)
01898 # if defined (ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP)
01899 if (::pthread_mutexattr_setkind_np (attributes, lock_type) != 0)
01900 result = -1;
01901 # endif
01902 # elif defined (ACE_HAS_RECURSIVE_MUTEXES)
01903 (void) ACE_ADAPT_RETVAL (::pthread_mutexattr_settype (attributes,
01904 lock_type),
01905 result);
01906 # endif
01907 }
01908
01909 if (result == 0)
01910 {
01911 # if defined (ACE_VXWORKS)&& (ACE_VXWORKS >= 0x600) && (ACE_VXWORKS <= 0x620)
01912
01913
01914
01915
01916
01917
01918
01919 ACE_OS::memset (m, 0, sizeof (*m));
01920 # endif
01921 # if defined (ACE_HAS_PTHREADS_DRAFT4)
01922 if (::pthread_mutex_init (m, *attributes) == 0)
01923 # elif defined (ACE_HAS_PTHREADS_DRAFT7) || defined (ACE_HAS_PTHREADS_STD)
01924 if (ACE_ADAPT_RETVAL (::pthread_mutex_init (m, attributes), result) == 0)
01925 # else
01926 if (::pthread_mutex_init (m, attributes) == 0)
01927 # endif
01928 result = 0;
01929 else
01930 result = -1;
01931 }
01932
01933
01934
01935 if (attributes == &l_attributes && attr_init)
01936 # if defined (ACE_HAS_PTHREADS_DRAFT4)
01937 ::pthread_mutexattr_delete (&l_attributes);
01938 # else
01939 ::pthread_mutexattr_destroy (&l_attributes);
01940 # endif
01941
01942 return result;
01943 # elif defined (ACE_HAS_STHREADS)
01944 ACE_UNUSED_ARG (name);
01945 ACE_UNUSED_ARG (sa);
01946 ACE_UNUSED_ARG (lock_type);
01947 int result;
01948 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_init (m,
01949 lock_scope,
01950 attributes),
01951 result),
01952 int, -1);
01953 # elif defined (ACE_HAS_WTHREADS)
01954 m->type_ = lock_scope;
01955
01956 SECURITY_ATTRIBUTES sa_buffer;
01957 SECURITY_DESCRIPTOR sd_buffer;
01958 switch (lock_scope)
01959 {
01960 case USYNC_PROCESS:
01961 # if defined (ACE_HAS_WINCE)
01962
01963 m->proc_mutex_ =
01964 ::CreateMutexW (ACE_OS::default_win32_security_attributes_r
01965 (sa, &sa_buffer, &sd_buffer),
01966 FALSE,
01967 ACE_Ascii_To_Wide (name).wchar_rep ());
01968 # else
01969 m->proc_mutex_ =
01970 ::CreateMutexA (ACE_OS::default_win32_security_attributes_r
01971 (sa, &sa_buffer, &sd_buffer),
01972 FALSE,
01973 name);
01974 # endif
01975 if (m->proc_mutex_ == 0)
01976 ACE_FAIL_RETURN (-1);
01977 else
01978 {
01979
01980 ACE_OS::set_errno_to_last_error ();
01981 return 0;
01982 }
01983 case USYNC_THREAD:
01984 return ACE_OS::thread_mutex_init (&m->thr_mutex_,
01985 lock_type,
01986 name,
01987 attributes);
01988 default:
01989 errno = EINVAL;
01990 return -1;
01991 }
01992
01993
01994 # elif defined (ACE_VXWORKS)
01995 ACE_UNUSED_ARG (name);
01996 ACE_UNUSED_ARG (attributes);
01997 ACE_UNUSED_ARG (sa);
01998 ACE_UNUSED_ARG (lock_type);
01999
02000 return (*m = ::semMCreate (lock_scope)) == 0 ? -1 : 0;
02001 # endif
02002 #else
02003 ACE_UNUSED_ARG (m);
02004 ACE_UNUSED_ARG (lock_scope);
02005 ACE_UNUSED_ARG (name);
02006 ACE_UNUSED_ARG (attributes);
02007 ACE_UNUSED_ARG (sa);
02008 ACE_UNUSED_ARG (lock_type);
02009 ACE_NOTSUP_RETURN (-1);
02010 #endif
02011 }
02012
02013 int
02014 ACE_OS::mutex_destroy (ACE_mutex_t *m)
02015 {
02016 ACE_OS_TRACE ("ACE_OS::mutex_destroy");
02017 #if defined (ACE_HAS_THREADS)
02018 # if defined (ACE_HAS_PTHREADS)
02019 # if (defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6))
02020 ACE_OSCALL_RETURN (::pthread_mutex_destroy (m), int, -1);
02021 # else
02022 int result;
02023 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_mutex_destroy (m),
02024 result), int, -1);
02025 # endif
02026 # elif defined (ACE_HAS_STHREADS)
02027 int result;
02028 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_destroy (m), result), int, -1);
02029 # elif defined (ACE_HAS_WTHREADS)
02030 switch (m->type_)
02031 {
02032 case USYNC_PROCESS:
02033 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (m->proc_mutex_),
02034 ace_result_),
02035 int, -1);
02036 case USYNC_THREAD:
02037 return ACE_OS::thread_mutex_destroy (&m->thr_mutex_);
02038 default:
02039 errno = EINVAL;
02040 return -1;
02041 }
02042
02043 # elif defined (ACE_VXWORKS)
02044 return ::semDelete (*m) == OK ? 0 : -1;
02045 # endif
02046 #else
02047 ACE_UNUSED_ARG (m);
02048 ACE_NOTSUP_RETURN (-1);
02049 #endif
02050 }
02051
02052 #if defined (ACE_HAS_WCHAR)
02053 int
02054 ACE_OS::mutex_init (ACE_mutex_t *m,
02055 int lock_scope,
02056 const wchar_t *name,
02057 ACE_mutexattr_t *attributes,
02058 LPSECURITY_ATTRIBUTES sa,
02059 int lock_type)
02060 {
02061 #if defined (ACE_HAS_THREADS) && defined (ACE_HAS_WTHREADS)
02062 m->type_ = lock_scope;
02063 SECURITY_ATTRIBUTES sa_buffer;
02064 SECURITY_DESCRIPTOR sd_buffer;
02065 switch (lock_scope)
02066 {
02067 case USYNC_PROCESS:
02068 m->proc_mutex_ =
02069 ::CreateMutexW (ACE_OS::default_win32_security_attributes_r
02070 (sa, &sa_buffer, &sd_buffer),
02071 FALSE,
02072 name);
02073 if (m->proc_mutex_ == 0)
02074 ACE_FAIL_RETURN (-1);
02075 else
02076 return 0;
02077 case USYNC_THREAD:
02078 return ACE_OS::thread_mutex_init (&m->thr_mutex_,
02079 lock_type,
02080 name,
02081 attributes);
02082 }
02083
02084 errno = EINVAL;
02085 return -1;
02086 #else
02087 return ACE_OS::mutex_init (m,
02088 lock_scope,
02089 ACE_Wide_To_Ascii (name).char_rep (),
02090 attributes,
02091 sa,
02092 lock_type);
02093 #endif
02094 }
02095 #endif
02096
02097 int
02098 ACE_OS::mutex_lock (ACE_mutex_t *m)
02099 {
02100
02101 #if defined (ACE_HAS_THREADS)
02102 # if defined (ACE_HAS_PTHREADS)
02103
02104 # if (defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6))
02105 ACE_OSCALL_RETURN (pthread_mutex_lock (m), int, -1);
02106 # else
02107 int result;
02108 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_mutex_lock (m), result),
02109 int, -1);
02110 # endif
02111 # elif defined (ACE_HAS_STHREADS)
02112 int result;
02113 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_lock (m), result), int, -1);
02114 # elif defined (ACE_HAS_WTHREADS)
02115 switch (m->type_)
02116 {
02117 case USYNC_PROCESS:
02118 switch (::WaitForSingleObject (m->proc_mutex_, INFINITE))
02119 {
02120
02121
02122
02123 case WAIT_OBJECT_0:
02124 case WAIT_ABANDONED:
02125
02126
02127 return 0;
02128 default:
02129
02130 ACE_OS::set_errno_to_last_error ();
02131 return -1;
02132 }
02133 case USYNC_THREAD:
02134 return ACE_OS::thread_mutex_lock (&m->thr_mutex_);
02135 default:
02136 errno = EINVAL;
02137 return -1;
02138 }
02139
02140 # elif defined (ACE_VXWORKS)
02141 return ::semTake (*m, WAIT_FOREVER) == OK ? 0 : -1;
02142 # endif
02143 #else
02144 ACE_UNUSED_ARG (m);
02145 ACE_NOTSUP_RETURN (-1);
02146 #endif
02147 }
02148
02149 int
02150 ACE_OS::mutex_lock (ACE_mutex_t *m,
02151 int &abandoned)
02152 {
02153 ACE_OS_TRACE ("ACE_OS::mutex_lock");
02154 #if defined (ACE_HAS_THREADS) && defined (ACE_HAS_WTHREADS)
02155 abandoned = 0;
02156 switch (m->type_)
02157 {
02158 case USYNC_PROCESS:
02159 switch (::WaitForSingleObject (m->proc_mutex_, INFINITE))
02160 {
02161
02162
02163
02164 case WAIT_OBJECT_0:
02165 return 0;
02166 case WAIT_ABANDONED:
02167 abandoned = 1;
02168 return 0;
02169 default:
02170
02171 ACE_OS::set_errno_to_last_error ();
02172 return -1;
02173 }
02174 case USYNC_THREAD:
02175 return ACE_OS::thread_mutex_lock (&m->thr_mutex_);
02176 default:
02177 errno = EINVAL;
02178 return -1;
02179 }
02180
02181 #else
02182 ACE_UNUSED_ARG (m);
02183 ACE_UNUSED_ARG (abandoned);
02184 ACE_NOTSUP_RETURN (-1);
02185 #endif
02186 }
02187
02188 int
02189 ACE_OS::mutex_lock (ACE_mutex_t *m,
02190 const ACE_Time_Value &timeout)
02191 {
02192 #if defined (ACE_HAS_THREADS) && defined (ACE_HAS_MUTEX_TIMEOUTS)
02193
02194 # if defined (ACE_HAS_PTHREADS)
02195 int result;
02196
02197
02198
02199 timespec_t ts = timeout;
02200
02201
02202
02203
02204 ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_mutex_timedlock (m, &ts), result), int, -1, result);
02205
02206
02207 if (result == -1 && errno == ETIMEDOUT)
02208 errno = ETIME;
02209 return result;
02210
02211 # elif defined (ACE_HAS_WTHREADS)
02212
02213
02214
02215 ACE_Time_Value relative_time (timeout - ACE_OS::gettimeofday ());
02216
02217 switch (m->type_)
02218 {
02219 case USYNC_PROCESS:
02220 switch (::WaitForSingleObject (m->proc_mutex_,
02221 relative_time.msec ()))
02222 {
02223 case WAIT_OBJECT_0:
02224 case WAIT_ABANDONED:
02225
02226
02227 return 0;
02228 case WAIT_TIMEOUT:
02229 errno = ETIME;
02230 return -1;
02231 default:
02232
02233 ACE_OS::set_errno_to_last_error ();
02234 return -1;
02235 }
02236 case USYNC_THREAD:
02237 ACE_NOTSUP_RETURN (-1);
02238 default:
02239 errno = EINVAL;
02240 return -1;
02241 }
02242
02243
02244 # elif defined (ACE_VXWORKS)
02245
02246
02247
02248
02249 ACE_Time_Value relative_time (timeout - ACE_OS::gettimeofday ());
02250
02251 int ticks_per_sec = ::sysClkRateGet ();
02252
02253 int ticks = relative_time.sec() * ticks_per_sec +
02254 relative_time.usec () * ticks_per_sec / ACE_ONE_SECOND_IN_USECS;
02255 if (::semTake (*m, ticks) == ERROR)
02256 {
02257 if (errno == S_objLib_OBJ_TIMEOUT)
02258
02259
02260 errno = ETIME;
02261 else if (errno == S_objLib_OBJ_UNAVAILABLE)
02262 errno = EBUSY;
02263 return -1;
02264 }
02265 else
02266 return 0;
02267 # endif
02268
02269 #else
02270 ACE_UNUSED_ARG (m);
02271 ACE_UNUSED_ARG (timeout);
02272 ACE_NOTSUP_RETURN (-1);
02273 #endif
02274 }
02275
02276 int
02277 ACE_OS::mutex_trylock (ACE_mutex_t *m)
02278 {
02279 ACE_OS_TRACE ("ACE_OS::mutex_trylock");
02280 #if defined (ACE_HAS_THREADS)
02281 # if defined (ACE_HAS_PTHREADS)
02282
02283 # if (defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6))
02284 int status = pthread_mutex_trylock (m);
02285 if (status == 1)
02286 status = 0;
02287 else if (status == 0) {
02288 status = -1;
02289 errno = EBUSY;
02290 }
02291 return status;
02292 # else
02293 int result;
02294 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_mutex_trylock (m), result),
02295 int, -1);
02296 # endif
02297 # elif defined (ACE_HAS_STHREADS)
02298 int result;
02299 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_trylock (m), result), int, -1);
02300 # elif defined (ACE_HAS_WTHREADS)
02301 switch (m->type_)
02302 {
02303 case USYNC_PROCESS:
02304 {
02305
02306 switch (::WaitForSingleObject (m->proc_mutex_, 0))
02307 {
02308 case WAIT_OBJECT_0:
02309 return 0;
02310 case WAIT_ABANDONED:
02311
02312
02313 return 0;
02314 case WAIT_TIMEOUT:
02315 errno = EBUSY;
02316 return -1;
02317 default:
02318 ACE_OS::set_errno_to_last_error ();
02319 return -1;
02320 }
02321 }
02322 case USYNC_THREAD:
02323 return ACE_OS::thread_mutex_trylock (&m->thr_mutex_);
02324 default:
02325 errno = EINVAL;
02326 return -1;
02327 }
02328
02329 # elif defined (ACE_VXWORKS)
02330 if (::semTake (*m, NO_WAIT) == ERROR)
02331 if (errno == S_objLib_OBJ_UNAVAILABLE)
02332 {
02333
02334 errno = EBUSY;
02335 return -1;
02336 }
02337 else
02338
02339 return -1;
02340 else
02341
02342 return 0;
02343 # endif
02344 #else
02345 ACE_UNUSED_ARG (m);
02346 ACE_NOTSUP_RETURN (-1);
02347 #endif
02348 }
02349
02350 int
02351 ACE_OS::mutex_trylock (ACE_mutex_t *m, int &abandoned)
02352 {
02353 #if defined (ACE_HAS_THREADS) && defined (ACE_HAS_WTHREADS)
02354 abandoned = 0;
02355 switch (m->type_)
02356 {
02357 case USYNC_PROCESS:
02358 {
02359
02360 switch (::WaitForSingleObject (m->proc_mutex_, 0))
02361 {
02362 case WAIT_OBJECT_0:
02363 return 0;
02364 case WAIT_ABANDONED:
02365 abandoned = 1;
02366 return 0;
02367 case WAIT_TIMEOUT:
02368 errno = EBUSY;
02369 return -1;
02370 default:
02371 ACE_OS::set_errno_to_last_error ();
02372 return -1;
02373 }
02374 }
02375 case USYNC_THREAD:
02376 return ACE_OS::thread_mutex_trylock (&m->thr_mutex_);
02377 default:
02378 errno = EINVAL;
02379 return -1;
02380 }
02381
02382 #else
02383 ACE_UNUSED_ARG (m);
02384 ACE_UNUSED_ARG (abandoned);
02385 ACE_NOTSUP_RETURN (-1);
02386 #endif
02387 }
02388
02389 int
02390 ACE_OS::mutex_unlock (ACE_mutex_t *m)
02391 {
02392 ACE_OS_TRACE ("ACE_OS::mutex_unlock");
02393 #if defined (ACE_HAS_THREADS)
02394 # if defined (ACE_HAS_PTHREADS)
02395
02396 # if (defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6))
02397 ACE_OSCALL_RETURN (pthread_mutex_unlock (m), int, -1);
02398 # else
02399 int result;
02400 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_mutex_unlock (m), result),
02401 int, -1);
02402 # endif
02403 # elif defined (ACE_HAS_STHREADS)
02404 int result;
02405 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_unlock (m), result), int, -1);
02406 # elif defined (ACE_HAS_WTHREADS)
02407 switch (m->type_)
02408 {
02409 case USYNC_PROCESS:
02410 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseMutex (m->proc_mutex_),
02411 ace_result_),
02412 int, -1);
02413 case USYNC_THREAD:
02414 return ACE_OS::thread_mutex_unlock (&m->thr_mutex_);
02415 default:
02416 errno = EINVAL;
02417 return -1;
02418 }
02419
02420 # elif defined (ACE_VXWORKS)
02421 return ::semGive (*m) == OK ? 0 : -1;
02422 # endif
02423 #else
02424 ACE_UNUSED_ARG (m);
02425 ACE_NOTSUP_RETURN (-1);
02426 #endif
02427 }
02428
02429 void
02430 ACE_OS::mutex_lock_cleanup (void *mutex)
02431 {
02432 ACE_OS_TRACE ("ACE_OS::mutex_lock_cleanup");
02433 #if defined (ACE_HAS_THREADS)
02434 # if defined (ACE_HAS_PTHREADS)
02435 ACE_mutex_t *p_lock = (ACE_mutex_t *) mutex;
02436 ACE_OS::mutex_unlock (p_lock);
02437 # else
02438 ACE_UNUSED_ARG (mutex);
02439 # endif
02440 #else
02441 ACE_UNUSED_ARG (mutex);
02442 #endif
02443 }
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453 int
02454 ACE_OS::event_destroy (ACE_event_t *event)
02455 {
02456 #if defined (ACE_WIN32)
02457 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (*event), ace_result_), int, -1);
02458 #elif defined (ACE_HAS_THREADS)
02459 if (event->eventdata_)
02460 {
02461
02462
02463
02464
02465
02466
02467 if (event->eventdata_->type_ == USYNC_PROCESS)
02468 {
02469 if (event->name_)
02470 {
02471
02472
02473
02474 int r1, r2;
02475 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
02476 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
02477 (!defined (ACE_USES_FIFO_SEM) && \
02478 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02479
02480 while ((r1 = ACE_OS::mutex_destroy (&event->eventdata_->lock_)) == -1
02481 && errno == EBUSY)
02482 {
02483 ACE_OS::thr_yield ();
02484 }
02485 # else
02486 r1 = ACE_OS::sema_destroy(&event->lock_);
02487 # endif
02488
02489 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
02490 (!defined (ACE_USES_FIFO_SEM) && \
02491 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02492
02493
02494 event->eventdata_->manual_reset_ = 1;
02495 while ((r2 = ACE_OS::cond_destroy (&event->eventdata_->condition_)) == -1
02496 && errno == EBUSY)
02497 {
02498 event->eventdata_->is_signaled_ = 1;
02499 ACE_OS::cond_broadcast (&event->eventdata_->condition_);
02500 ACE_OS::thr_yield ();
02501 }
02502 # else
02503 r2 = ACE_OS::sema_destroy(&event->semaphore_);
02504 # endif
02505 ACE_OS::munmap (event->eventdata_,
02506 sizeof (ACE_eventdata_t));
02507 ACE_OS::shm_unlink (ACE_TEXT_CHAR_TO_TCHAR(event->name_));
02508 ACE_OS::free (event->name_);
02509 return r1 != 0 || r2 != 0 ? -1 : 0;
02510 }
02511 else
02512 {
02513 ACE_OS::munmap (event->eventdata_,
02514 sizeof (ACE_eventdata_t));
02515 # if (!defined (ACE_HAS_PTHREADS) || !defined (_POSIX_THREAD_PROCESS_SHARED) || \
02516 (defined (ACE_LACKS_MUTEXATTR_PSHARED) && defined (ACE_LACKS_CONDATTR_PSHARED))) && \
02517 (defined (ACE_USES_FIFO_SEM) || \
02518 (defined (ACE_HAS_POSIX_SEM) && defined (ACE_HAS_POSIX_TIMEOUT) && defined (ACE_LACKS_NAMED_POSIX_SEM)))
02519 ACE_OS::sema_destroy(&event->lock_);
02520 # endif
02521 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
02522 (!defined (ACE_USES_FIFO_SEM) && \
02523 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02524 return 0;
02525 # else
02526 return ACE_OS::sema_destroy(&event->semaphore_);
02527 # endif
02528 }
02529 }
02530 else
02531 {
02532 int r1, r2;
02533
02534 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
02535 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
02536 (!defined (ACE_USES_FIFO_SEM) && \
02537 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02538
02539 while ((r1 = ACE_OS::mutex_destroy (&event->eventdata_->lock_)) == -1
02540 && errno == EBUSY)
02541 {
02542 ACE_OS::thr_yield ();
02543 }
02544 # else
02545 r1 = ACE_OS::sema_destroy(&event->lock_);
02546 # endif
02547
02548 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
02549 (!defined (ACE_USES_FIFO_SEM) && \
02550 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02551
02552
02553 event->eventdata_->manual_reset_ = 1;
02554 while ((r2 = ACE_OS::cond_destroy (&event->eventdata_->condition_)) == -1
02555 && errno == EBUSY)
02556 {
02557 event->eventdata_->is_signaled_ = 1;
02558 ACE_OS::cond_broadcast (&event->eventdata_->condition_);
02559 ACE_OS::thr_yield ();
02560 }
02561 # else
02562 r2 = ACE_OS::sema_destroy(&event->semaphore_);
02563 # endif
02564 delete event->eventdata_;
02565 return r1 != 0 || r2 != 0 ? -1 : 0;
02566 }
02567 }
02568
02569 return 0;
02570 #else
02571 ACE_UNUSED_ARG (event);
02572 ACE_NOTSUP_RETURN (-1);
02573 #endif
02574 }
02575
02576 int
02577 ACE_OS::event_init (ACE_event_t *event,
02578 int manual_reset,
02579 int initial_state,
02580 int type,
02581 const char *name,
02582 void *arg,
02583 LPSECURITY_ATTRIBUTES sa)
02584 {
02585 #if defined (ACE_WIN32)
02586 ACE_UNUSED_ARG (type);
02587 ACE_UNUSED_ARG (arg);
02588 SECURITY_ATTRIBUTES sa_buffer;
02589 SECURITY_DESCRIPTOR sd_buffer;
02590 # if defined (ACE_HAS_WINCE)
02591
02592 *event = ::CreateEventW (ACE_OS::default_win32_security_attributes_r
02593 (sa, &sa_buffer, &sd_buffer),
02594 manual_reset,
02595 initial_state,
02596 ACE_Ascii_To_Wide (name).wchar_rep ());
02597 # else
02598 *event = ::CreateEventA (ACE_OS::default_win32_security_attributes_r
02599 (sa, &sa_buffer, &sd_buffer),
02600 manual_reset,
02601 initial_state,
02602 name);
02603 # endif
02604 if (*event == 0)
02605 ACE_FAIL_RETURN (-1);
02606 else
02607 return 0;
02608 #elif defined (ACE_HAS_THREADS)
02609 ACE_UNUSED_ARG (sa);
02610 event->eventdata_ = 0;
02611 ACE_eventdata_t* evtdata;
02612
02613 if (type == USYNC_PROCESS)
02614 {
02615 int owner = 0;
02616
02617 ACE_HANDLE fd = ACE_OS::shm_open (ACE_TEXT_CHAR_TO_TCHAR (name),
02618 O_RDWR | O_CREAT | O_EXCL,
02619 ACE_DEFAULT_FILE_PERMS);
02620 if (fd == ACE_INVALID_HANDLE)
02621 {
02622 if (errno == EEXIST)
02623 fd = ACE_OS::shm_open (ACE_TEXT_CHAR_TO_TCHAR (name),
02624 O_RDWR | O_CREAT,
02625 ACE_DEFAULT_FILE_PERMS);
02626 if (fd == ACE_INVALID_HANDLE)
02627 return -1;
02628 }
02629 else
02630 {
02631
02632 if (ACE_OS::ftruncate (fd, sizeof (ACE_eventdata_t)) == -1)
02633 {
02634 ACE_OS::close (fd);
02635 return -1;
02636 }
02637 owner = 1;
02638 }
02639
02640 evtdata =
02641 (ACE_eventdata_t *) ACE_OS::mmap (0,
02642 sizeof (ACE_eventdata_t),
02643 PROT_RDWR,
02644 MAP_SHARED,
02645 fd,
02646 0);
02647 ACE_OS::close (fd);
02648 if (evtdata == MAP_FAILED)
02649 {
02650 if (owner)
02651 ACE_OS::shm_unlink (ACE_TEXT_CHAR_TO_TCHAR (name));
02652 return -1;
02653 }
02654
02655 if (owner)
02656 {
02657 event->name_ = ACE_OS::strdup (name);
02658 if (event->name_ == 0)
02659 {
02660 ACE_OS::shm_unlink (ACE_TEXT_CHAR_TO_TCHAR (name));
02661 return -1;
02662 }
02663 event->eventdata_ = evtdata;
02664 event->eventdata_->type_ = type;
02665 event->eventdata_->manual_reset_ = manual_reset;
02666 event->eventdata_->is_signaled_ = initial_state;
02667 event->eventdata_->auto_event_signaled_ = false;
02668 event->eventdata_->waiting_threads_ = 0;
02669 event->eventdata_->signal_count_ = 0;
02670
02671 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
02672 (!defined (ACE_USES_FIFO_SEM) && \
02673 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02674 int result = ACE_OS::cond_init (&event->eventdata_->condition_,
02675 static_cast<short> (type),
02676 name,
02677 arg);
02678 # else
02679 char sem_name[128];
02680 ACE_OS::strncpy (sem_name,
02681 name,
02682 sizeof (sem_name) - (1 + sizeof ("._ACE_EVTSEM_")));
02683 ACE_OS::strcat (sem_name, "._ACE_EVTSEM_");
02684 int result = ACE_OS::sema_init (&event->semaphore_,
02685 0,
02686 type,
02687 sem_name,
02688 arg);
02689 # endif
02690 if (result == 0)
02691 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
02692 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
02693 (!defined (ACE_USES_FIFO_SEM) && \
02694 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02695 result = ACE_OS::mutex_init (&event->eventdata_->lock_,
02696 type,
02697 name,
02698 (ACE_mutexattr_t *) arg);
02699 # else
02700 {
02701 char lck_name[128];
02702 ACE_OS::strncpy
02703 (lck_name,
02704 name,
02705 sizeof (lck_name) - (1 + sizeof ("._ACE_EVTLCK_")));
02706 ACE_OS::strcat (lck_name, "._ACE_EVTLCK_");
02707 result = ACE_OS::sema_init (&event->lock_,
02708 0,
02709 type,
02710 lck_name,
02711 arg);
02712 if (result == 0)
02713 result = ACE_OS::sema_post (&event->lock_);
02714 }
02715 # endif
02716 return result;
02717 }
02718 else
02719 {
02720 int result = 0;
02721
02722 event->name_ = 0;
02723 event->eventdata_ = evtdata;
02724 #if (!defined (ACE_HAS_PTHREADS) || !defined (_POSIX_THREAD_PROCESS_SHARED) || defined (ACE_LACKS_CONDATTR_PSHARED)) && \
02725 (defined (ACE_USES_FIFO_SEM) || \
02726 (defined (ACE_HAS_POSIX_SEM) && defined (ACE_HAS_POSIX_SEM_TIMEOUT) && !defined (ACE_LACKS_NAMED_POSIX_SEM)))
02727 char sem_name[128];
02728 ACE_OS::strncpy (sem_name,
02729 name,
02730 sizeof (sem_name) - (1 + sizeof ("._ACE_EVTSEM_")));
02731 ACE_OS::strcat (sem_name, "._ACE_EVTSEM_");
02732 result = ACE_OS::sema_init(&event->semaphore_,
02733 0,
02734 type,
02735 sem_name,
02736 arg);
02737 # endif
02738
02739 # if (!defined (ACE_HAS_PTHREADS) || !defined (_POSIX_THREAD_PROCESS_SHARED) || \
02740 (defined (ACE_LACKS_MUTEXATTR_PSHARED) && defined (ACE_LACKS_CONDATTR_PSHARED))) && \
02741 (defined (ACE_USES_FIFO_SEM) || \
02742 (defined (ACE_HAS_POSIX_SEM) && defined (ACE_HAS_POSIX_TIMEOUT) && defined (ACE_LACKS_NAMED_POSIX_SEM)))
02743 if (result == 0)
02744 {
02745 char lck_name[128];
02746 ACE_OS::strncpy
02747 (lck_name,
02748 name,
02749 sizeof (lck_name) - (1 + sizeof ("._ACE_EVTLCK_")));
02750 ACE_OS::strcat (lck_name, "._ACE_EVTLCK_");
02751 result = ACE_OS::sema_init (&event->lock_,
02752 0,
02753 type,
02754 lck_name,
02755 arg);
02756 }
02757 # endif
02758 return result;
02759 }
02760
02761 return 0;
02762 }
02763 else
02764 {
02765 ACE_NEW_RETURN (evtdata, ACE_eventdata_t, -1);
02766 event->name_ = 0;
02767 event->eventdata_ = evtdata;
02768 event->eventdata_->type_ = type;
02769 event->eventdata_->manual_reset_ = manual_reset;
02770 event->eventdata_->is_signaled_ = initial_state;
02771 event->eventdata_->auto_event_signaled_ = false;
02772 event->eventdata_->waiting_threads_ = 0;
02773 event->eventdata_->signal_count_ = 0;
02774
02775 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
02776 (!defined (ACE_USES_FIFO_SEM) && \
02777 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02778 int result = ACE_OS::cond_init (&event->eventdata_->condition_,
02779 static_cast<short> (type),
02780 name,
02781 arg);
02782 # else
02783 int result = ACE_OS::sema_init (&event->semaphore_,
02784 0,
02785 type,
02786 name,
02787 arg);
02788 # endif
02789 if (result == 0)
02790 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
02791 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
02792 (!defined (ACE_USES_FIFO_SEM) && \
02793 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02794 result = ACE_OS::mutex_init (&event->eventdata_->lock_,
02795 type,
02796 name,
02797 (ACE_mutexattr_t *) arg);
02798 # else
02799 result = ACE_OS::sema_init (&event->lock_,
02800 0,
02801 type,
02802 name,
02803 arg);
02804 if (result == 0)
02805 result = ACE_OS::sema_post(&event->lock_);
02806 # endif
02807
02808 return result;
02809 }
02810 #else
02811 ACE_UNUSED_ARG (event);
02812 ACE_UNUSED_ARG (manual_reset);
02813 ACE_UNUSED_ARG (initial_state);
02814 ACE_UNUSED_ARG (type);
02815 ACE_UNUSED_ARG (name);
02816 ACE_UNUSED_ARG (arg);
02817 ACE_UNUSED_ARG (sa);
02818 ACE_NOTSUP_RETURN (-1);
02819 #endif
02820 }
02821
02822 int
02823 ACE_OS::event_pulse (ACE_event_t *event)
02824 {
02825 #if defined (ACE_WIN32)
02826 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::PulseEvent (*event), ace_result_), int, -1);
02827 #elif defined (ACE_HAS_THREADS)
02828 int result = 0;
02829 int error = 0;
02830
02831
02832 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
02833 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
02834 (!defined (ACE_USES_FIFO_SEM) && \
02835 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02836 if (ACE_OS::mutex_lock (&event->eventdata_->lock_) == 0)
02837 # else
02838 if (ACE_OS::sema_wait (&event->lock_) == 0)
02839 # endif
02840 {
02841 if (event->eventdata_->waiting_threads_ > 0)
02842 {
02843
02844 if (event->eventdata_->manual_reset_ == 1)
02845 {
02846
02847 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
02848 (!defined (ACE_USES_FIFO_SEM) && \
02849 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02850 if (ACE_OS::cond_broadcast (&event->eventdata_->condition_) != 0)
02851 {
02852 result = -1;
02853 error = errno;
02854 }
02855 if (result == 0)
02856 event->eventdata_->signal_count_ = event->eventdata_->waiting_threads_;
02857 # else
02858 event->eventdata_->signal_count_ = event->eventdata_->waiting_threads_;
02859 for (unsigned long i=0; i<event->eventdata_->signal_count_ ;++i)
02860 if (ACE_OS::sema_post(&event->semaphore_) != 0)
02861 {
02862 event->eventdata_->signal_count_ = 0;
02863 result = -1;
02864 error = errno;
02865 }
02866
02867 if (result == 0)
02868 while(event->eventdata_->signal_count_!=0 && event->eventdata_->waiting_threads_!=0)
02869 ACE_OS::thr_yield ();
02870 # endif
02871 }
02872
02873 else
02874 {
02875 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
02876 (!defined (ACE_USES_FIFO_SEM) && \
02877 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02878 if (ACE_OS::cond_signal (&event->eventdata_->condition_) != 0)
02879 # else
02880 if (ACE_OS::sema_post(&event->semaphore_) != 0)
02881 # endif
02882 {
02883 result = -1;
02884 error = errno;
02885 }
02886
02887 event->eventdata_->auto_event_signaled_ = true;
02888 }
02889 }
02890
02891
02892 event->eventdata_->is_signaled_ = 0;
02893
02894
02895 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
02896 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
02897 (!defined (ACE_USES_FIFO_SEM) && \
02898 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02899 ACE_OS::mutex_unlock (&event->eventdata_->lock_);
02900 # else
02901 ACE_OS::sema_post (&event->lock_);
02902 # endif
02903 if (result == -1)
02904
02905 errno = error;
02906 }
02907 else
02908 result = -1;
02909 return result;
02910 #else
02911 ACE_UNUSED_ARG (event);
02912 ACE_NOTSUP_RETURN (-1);
02913 #endif
02914 }
02915
02916 int
02917 ACE_OS::event_reset (ACE_event_t *event)
02918 {
02919 #if defined (ACE_WIN32)
02920 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ResetEvent (*event), ace_result_), int, -1);
02921 #elif defined (ACE_HAS_THREADS)
02922 int result = 0;
02923
02924
02925 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
02926 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
02927 (!defined (ACE_USES_FIFO_SEM) && \
02928 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02929 if (ACE_OS::mutex_lock (&event->eventdata_->lock_) == 0)
02930 # else
02931 if (ACE_OS::sema_wait (&event->lock_) == 0)
02932 # endif
02933 {
02934
02935 event->eventdata_->is_signaled_ = 0;
02936 event->eventdata_->auto_event_signaled_ = false;
02937
02938
02939 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
02940 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
02941 (!defined (ACE_USES_FIFO_SEM) && \
02942 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02943 ACE_OS::mutex_unlock (&event->eventdata_->lock_);
02944 # else
02945 ACE_OS::sema_post (&event->lock_);
02946 # endif
02947 }
02948 else
02949 result = -1;
02950 return result;
02951 #else
02952 ACE_UNUSED_ARG (event);
02953 ACE_NOTSUP_RETURN (-1);
02954 #endif
02955 }
02956
02957 int
02958 ACE_OS::event_signal (ACE_event_t *event)
02959 {
02960 #if defined (ACE_WIN32)
02961 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::SetEvent (*event), ace_result_), int, -1);
02962 #elif defined (ACE_HAS_THREADS)
02963 int result = 0;
02964 int error = 0;
02965
02966
02967 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
02968 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
02969 (!defined (ACE_USES_FIFO_SEM) && \
02970 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02971 if (ACE_OS::mutex_lock (&event->eventdata_->lock_) == 0)
02972 # else
02973 if (ACE_OS::sema_wait (&event->lock_) == 0)
02974 # endif
02975 {
02976
02977 if (event->eventdata_->manual_reset_ == 1)
02978 {
02979
02980 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
02981 (!defined (ACE_USES_FIFO_SEM) && \
02982 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
02983 if (ACE_OS::cond_broadcast (&event->eventdata_->condition_) != 0)
02984 {
02985 result = -1;
02986 error = errno;
02987 }
02988 # else
02989 if (ACE_OS::sema_post(&event->semaphore_) != 0)
02990 {
02991 result = -1;
02992 error = errno;
02993 }
02994 # endif
02995
02996 if (result == 0)
02997
02998 event->eventdata_->is_signaled_ = 1;
02999 }
03000
03001 else
03002 {
03003 if (event->eventdata_->waiting_threads_ == 0)
03004
03005 event->eventdata_->is_signaled_ = 1;
03006
03007 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
03008 (!defined (ACE_USES_FIFO_SEM) && \
03009 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03010 else if (ACE_OS::cond_signal (&event->eventdata_->condition_) != 0)
03011 # else
03012 else if (ACE_OS::sema_post(&event->semaphore_) != 0)
03013 # endif
03014 {
03015 result = -1;
03016 error = errno;
03017 }
03018
03019 event->eventdata_->auto_event_signaled_ = true;
03020 }
03021
03022
03023 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
03024 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
03025 (!defined (ACE_USES_FIFO_SEM) && \
03026 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03027 ACE_OS::mutex_unlock (&event->eventdata_->lock_);
03028 # else
03029 ACE_OS::sema_post (&event->lock_);
03030 # endif
03031
03032 if (result == -1)
03033
03034 errno = error;
03035 }
03036 else
03037 result = -1;
03038
03039 return result;
03040 #else
03041 ACE_UNUSED_ARG (event);
03042 ACE_NOTSUP_RETURN (-1);
03043 #endif
03044 }
03045
03046 int
03047 ACE_OS::event_timedwait (ACE_event_t *event,
03048 ACE_Time_Value *timeout,
03049 int use_absolute_time)
03050 {
03051 #if defined (ACE_WIN32)
03052 DWORD result;
03053
03054 if (timeout == 0)
03055
03056 result = ::WaitForSingleObject (*event, INFINITE);
03057 else if (timeout->sec () == 0 && timeout->usec () == 0)
03058
03059 result = ::WaitForSingleObject (*event, 0);
03060 else
03061 {
03062
03063
03064
03065
03066
03067
03068 int msec_timeout;
03069 if (use_absolute_time)
03070 {
03071
03072
03073 ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ());
03074
03075
03076
03077
03078 if (relative_time < ACE_Time_Value::zero)
03079 msec_timeout = 0;
03080 else
03081 msec_timeout = relative_time.msec ();
03082 }
03083 else
03084
03085
03086 msec_timeout = timeout->msec ();
03087 result = ::WaitForSingleObject (*event, msec_timeout);
03088 }
03089
03090 switch (result)
03091 {
03092 case WAIT_OBJECT_0:
03093 return 0;
03094 case WAIT_TIMEOUT:
03095 errno = ETIME;
03096 return -1;
03097 default:
03098
03099 ACE_OS::set_errno_to_last_error ();
03100 return -1;
03101 }
03102 #elif defined (ACE_HAS_THREADS)
03103 int result = 0;
03104 int error = 0;
03105
03106
03107 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
03108 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
03109 (!defined (ACE_USES_FIFO_SEM) && \
03110 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03111 if (ACE_OS::mutex_lock (&event->eventdata_->lock_) == 0)
03112 # else
03113 if (ACE_OS::sema_wait (&event->lock_) == 0)
03114 # endif
03115 {
03116 if (event->eventdata_->is_signaled_ == 1)
03117
03118 {
03119 if (event->eventdata_->manual_reset_ == 0)
03120 {
03121
03122 event->eventdata_->is_signaled_ = 0;
03123 event->eventdata_->auto_event_signaled_ = false;
03124 }
03125 }
03126 else
03127
03128 {
03129 event->eventdata_->waiting_threads_++;
03130
03131 ACE_Time_Value absolute_timeout = *timeout;
03132
03133
03134
03135 if (use_absolute_time == 0)
03136 absolute_timeout += ACE_OS::gettimeofday ();
03137
03138 while (event->eventdata_->is_signaled_ == 0 &&
03139 event->eventdata_->auto_event_signaled_ == false)
03140 {
03141 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
03142 (!defined (ACE_USES_FIFO_SEM) && \
03143 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03144 if (ACE_OS::cond_timedwait (&event->eventdata_->condition_,
03145 &event->eventdata_->lock_,
03146 &absolute_timeout) != 0)
03147 {
03148 result = -1;
03149 error = errno;
03150 break;
03151 }
03152
03153 if (event->eventdata_->signal_count_ > 0)
03154 {
03155 event->eventdata_->signal_count_--;
03156 break;
03157 }
03158 # else
03159 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_MUTEXATTR_PSHARED)) || \
03160 (!defined (ACE_USES_FIFO_SEM) && (!defined (ACE_HAS_POSIX_SEM) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03161 if (ACE_OS::mutex_unlock (&event->eventdata_->lock_) != 0)
03162 # else
03163 if (ACE_OS::sema_post (&event->lock_) != 0)
03164 # endif
03165 {
03166 event->eventdata_->waiting_threads_--;
03167 return -1;
03168 }
03169
03170 if (ACE_OS::sema_wait(&event->semaphore_, absolute_timeout) !=0)
03171 {
03172 result = -1;
03173 if (errno == ETIMEDOUT)
03174 error = ETIME;
03175 else
03176 error = errno;
03177 }
03178
03179 bool signalled = false;
03180 if (result == 0 && event->eventdata_->signal_count_ > 0)
03181 {
03182 event->eventdata_->signal_count_--;
03183 signalled = true;
03184 }
03185
03186 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_MUTEXATTR_PSHARED)) || \
03187 (!defined (ACE_USES_FIFO_SEM) && (!defined (ACE_HAS_POSIX_SEM) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03188 if (ACE_OS::mutex_lock (&event->eventdata_->lock_) != 0)
03189 # else
03190 if (ACE_OS::sema_wait (&event->lock_) != 0)
03191 # endif
03192 {
03193 event->eventdata_->waiting_threads_--;
03194 return -1;
03195 }
03196
03197 if (result)
03198 break;
03199
03200 if (event->eventdata_->manual_reset_ == 1 && event->eventdata_->is_signaled_ == 1)
03201 if (ACE_OS::sema_post(&event->semaphore_) != 0)
03202 {
03203 result = -1;
03204 error = errno;
03205 break;
03206 }
03207
03208 if (signalled)
03209 break;
03210 # endif
03211 }
03212
03213
03214
03215 if (event->eventdata_->auto_event_signaled_ == true)
03216 event->eventdata_->auto_event_signaled_ = false;
03217
03218 event->eventdata_->waiting_threads_--;
03219 }
03220
03221
03222 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
03223 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
03224 (!defined (ACE_USES_FIFO_SEM) && \
03225 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03226 ACE_OS::mutex_unlock (&event->eventdata_->lock_);
03227 # else
03228 ACE_OS::sema_post (&event->lock_);
03229 # endif
03230
03231 if (result == -1)
03232
03233 errno = error;
03234 }
03235 else
03236 result = -1;
03237 return result;
03238 #else
03239 ACE_UNUSED_ARG (event);
03240 ACE_UNUSED_ARG (timeout);
03241 ACE_UNUSED_ARG (use_absolute_time);
03242 ACE_NOTSUP_RETURN (-1);
03243 #endif
03244 }
03245
03246 int
03247 ACE_OS::event_wait (ACE_event_t *event)
03248 {
03249 #if defined (ACE_WIN32)
03250 switch (::WaitForSingleObject (*event, INFINITE))
03251 {
03252 case WAIT_OBJECT_0:
03253 return 0;
03254 default:
03255 ACE_OS::set_errno_to_last_error ();
03256 return -1;
03257 }
03258 #elif defined (ACE_HAS_THREADS)
03259 int result = 0;
03260 int error = 0;
03261
03262
03263 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
03264 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
03265 (!defined (ACE_USES_FIFO_SEM) && \
03266 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03267 if (ACE_OS::mutex_lock (&event->eventdata_->lock_) == 0)
03268 # else
03269 if (ACE_OS::sema_wait (&event->lock_) == 0)
03270 # endif
03271 {
03272 if (event->eventdata_->is_signaled_ == 1)
03273
03274 {
03275 if (event->eventdata_->manual_reset_ == 0)
03276
03277 event->eventdata_->is_signaled_ = 0;
03278 }
03279 else
03280 {
03281 event->eventdata_->waiting_threads_++;
03282
03283 while (event->eventdata_->is_signaled_ == 0 &&
03284 event->eventdata_->auto_event_signaled_ == false)
03285 {
03286 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_CONDATTR_PSHARED)) || \
03287 (!defined (ACE_USES_FIFO_SEM) && \
03288 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_SEM_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03289 if (ACE_OS::cond_wait (&event->eventdata_->condition_,
03290 &event->eventdata_->lock_) != 0)
03291 {
03292 result = -1;
03293 error = errno;
03294
03295 break;
03296 }
03297 if (event->eventdata_->signal_count_ > 0)
03298 {
03299 event->eventdata_->signal_count_--;
03300 break;
03301 }
03302 # else
03303 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_MUTEXATTR_PSHARED)) || \
03304 (!defined (ACE_USES_FIFO_SEM) && (!defined (ACE_HAS_POSIX_SEM) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03305 if (ACE_OS::mutex_unlock (&event->eventdata_->lock_) != 0)
03306 # else
03307 if (ACE_OS::sema_post (&event->lock_) != 0)
03308 # endif
03309 {
03310 event->eventdata_->waiting_threads_--;
03311 return -1;
03312 }
03313
03314 if (ACE_OS::sema_wait(&event->semaphore_) !=0)
03315 {
03316 result = -1;
03317 error = errno;
03318 }
03319
03320 bool signalled = false;
03321 if (result == 0 && event->eventdata_->signal_count_ > 0)
03322 {
03323 event->eventdata_->signal_count_--;
03324 signalled = true;
03325 }
03326
03327 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_MUTEXATTR_PSHARED)) || \
03328 (!defined (ACE_USES_FIFO_SEM) && (!defined (ACE_HAS_POSIX_SEM) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03329 if (ACE_OS::mutex_lock (&event->eventdata_->lock_) != 0)
03330 # else
03331 if (ACE_OS::sema_wait (&event->lock_) != 0)
03332 # endif
03333 {
03334 event->eventdata_->waiting_threads_--;
03335 return -1;
03336 }
03337
03338 if (result)
03339 break;
03340
03341 if (event->eventdata_->manual_reset_ == 1 && event->eventdata_->is_signaled_ == 1)
03342 if (ACE_OS::sema_post(&event->semaphore_) != 0)
03343 {
03344 result = -1;
03345 error = errno;
03346 break;
03347 }
03348
03349 if (signalled)
03350 break;
03351 # endif
03352 }
03353
03354
03355 if (event->eventdata_->auto_event_signaled_ == true)
03356 event->eventdata_->auto_event_signaled_ = false;
03357
03358 event->eventdata_->waiting_threads_--;
03359 }
03360
03361
03362 # if (defined (ACE_HAS_PTHREADS) && defined (_POSIX_THREAD_PROCESS_SHARED) && \
03363 (!defined (ACE_LACKS_MUTEXATTR_PSHARED) || !defined (ACE_LACKS_CONDATTR_PSHARED))) || \
03364 (!defined (ACE_USES_FIFO_SEM) && \
03365 (!defined (ACE_HAS_POSIX_SEM) || !defined (ACE_HAS_POSIX_TIMEOUT) || defined (ACE_LACKS_NAMED_POSIX_SEM)))
03366 ACE_OS::mutex_unlock (&event->eventdata_->lock_);
03367 # else
03368 ACE_OS::sema_post (&event->lock_);
03369 # endif
03370
03371 if (result == -1)
03372
03373 errno = error;
03374 }
03375 else
03376 result = -1;
03377 return result;
03378 #else
03379 ACE_UNUSED_ARG (event);
03380 ACE_NOTSUP_RETURN (-1);
03381 #endif
03382 }
03383
03384
03385
03386
03387
03388 int
03389 ACE_OS::lwp_getparams (ACE_Sched_Params &sched_params)
03390 {
03391 #if defined (ACE_HAS_STHREADS) || defined (sun)
03392
03393 ACE_id_t rt_id;
03394 ACE_id_t ts_id;
03395 if (ACE_OS::scheduling_class ("RT", rt_id) == -1
03396 || ACE_OS::scheduling_class ("TS", ts_id) == -1)
03397 return -1;
03398
03399
03400 pcparms_t pcparms;
03401
03402
03403 ACE_OS::memset (&pcparms, 0, sizeof pcparms);
03404 pcparms.pc_cid = PC_CLNULL;
03405
03406 if (ACE_OS::priority_control (P_LWPID,
03407 P_MYID,
03408 PC_GETPARMS,
03409 (char *) &pcparms) == -1)
03410 return -1;
03411 else if (pcparms.pc_cid == rt_id)
03412 {
03413
03414 rtparms_t rtparms;
03415 ACE_OS::memcpy (&rtparms, pcparms.pc_clparms, sizeof rtparms);
03416
03417 sched_params.policy (ACE_SCHED_FIFO);
03418 sched_params.priority (rtparms.rt_pri);
03419 sched_params.scope (ACE_SCOPE_THREAD);
03420 ACE_Time_Value quantum (rtparms.rt_tqsecs,
03421 rtparms.rt_tqnsecs == RT_TQINF
03422 ? 0 : rtparms.rt_tqnsecs * 1000);
03423 sched_params.quantum (quantum);
03424 return 0;
03425 }
03426 else if (pcparms.pc_cid == ts_id)
03427 {
03428
03429 tsparms_t tsparms;
03430 ACE_OS::memcpy (&tsparms, pcparms.pc_clparms, sizeof tsparms);
03431
03432 sched_params.policy (ACE_SCHED_OTHER);
03433 sched_params.priority (tsparms.ts_upri);
03434 sched_params.scope (ACE_SCOPE_THREAD);
03435 return 0;
03436 }
03437 else
03438 return -1;
03439
03440 #else
03441 ACE_UNUSED_ARG (sched_params);
03442 ACE_NOTSUP_RETURN (-1);
03443 #endif
03444 }
03445
03446 int
03447 ACE_OS::lwp_setparams (const ACE_Sched_Params &sched_params)
03448 {
03449 #if defined (ACE_HAS_STHREADS) || defined (sun)
03450 ACE_Sched_Params lwp_params (sched_params);
03451 lwp_params.scope (ACE_SCOPE_LWP);
03452 return ACE_OS::sched_params (lwp_params);
03453 #else
03454 ACE_UNUSED_ARG (sched_params);
03455 ACE_NOTSUP_RETURN (-1);
03456 #endif
03457 }
03458
03459 #if !defined (ACE_HAS_THREADS) || (defined (ACE_LACKS_RWLOCK_T) && \
03460 !defined (ACE_HAS_PTHREADS_UNIX98_EXT))
03461 int
03462 ACE_OS::rwlock_init (ACE_rwlock_t *rw,
03463 int type,
03464 const ACE_TCHAR *name,
03465 void *arg)
03466 {
03467
03468 # if defined (ACE_HAS_THREADS) && defined (ACE_LACKS_RWLOCK_T)
03469
03470 ACE_UNUSED_ARG (name);
03471 int result = -1;
03472
03473
03474
03475 ACE_TCHAR name1[ACE_UNIQUE_NAME_LEN];
03476 ACE_TCHAR name2[ACE_UNIQUE_NAME_LEN];
03477 ACE_TCHAR name3[ACE_UNIQUE_NAME_LEN];
03478 ACE_TCHAR name4[ACE_UNIQUE_NAME_LEN];
03479
03480 ACE_OS::unique_name ((const void *) &rw->lock_,
03481 name1,
03482 ACE_UNIQUE_NAME_LEN);
03483 ACE_OS::unique_name ((const void *) &rw->waiting_readers_,
03484 name2,
03485 ACE_UNIQUE_NAME_LEN);
03486 ACE_OS::unique_name ((const void *) &rw->waiting_writers_,
03487 name3,
03488 ACE_UNIQUE_NAME_LEN);
03489 ACE_OS::unique_name ((const void *) &rw->waiting_important_writer_,
03490 name4,
03491 ACE_UNIQUE_NAME_LEN);
03492
03493 ACE_condattr_t attributes;
03494 if (ACE_OS::condattr_init (attributes, type) == 0)
03495 {
03496 if (ACE_OS::mutex_init (&rw->lock_, type, name1,
03497 (ACE_mutexattr_t *) arg) == 0
03498 && ACE_OS::cond_init (&rw->waiting_readers_,
03499 attributes, name2, arg) == 0
03500 && ACE_OS::cond_init (&rw->waiting_writers_,
03501 attributes, name3, arg) == 0
03502 && ACE_OS::cond_init (&rw->waiting_important_writer_,
03503 attributes, name4, arg) == 0)
03504 {
03505
03506 rw->ref_count_ = 0;
03507 rw->num_waiting_writers_ = 0;
03508 rw->num_waiting_readers_ = 0;
03509 rw->important_writer_ = 0;
03510 result = 0;
03511 }
03512 ACE_OS::condattr_destroy (attributes);
03513 }
03514
03515 if (result == -1)
03516 {
03517
03518 ACE_Errno_Guard error (errno);
03519 ACE_OS::mutex_destroy (&rw->lock_);
03520 ACE_OS::cond_destroy (&rw->waiting_readers_);
03521 ACE_OS::cond_destroy (&rw->waiting_writers_);
03522 ACE_OS::cond_destroy (&rw->waiting_important_writer_);
03523 }
03524 return result;
03525 # else
03526 ACE_UNUSED_ARG (rw);
03527 ACE_UNUSED_ARG (type);
03528 ACE_UNUSED_ARG (name);
03529 ACE_UNUSED_ARG (arg);
03530 ACE_NOTSUP_RETURN (-1);
03531 # endif
03532 }
03533 #endif
03534
03535 int
03536 ACE_OS::sched_params (const ACE_Sched_Params &sched_params,
03537 ACE_id_t id)
03538 {
03539 ACE_OS_TRACE ("ACE_OS::sched_params");
03540 #if defined (ACE_HAS_STHREADS)
03541 return ACE_OS::set_scheduling_params (sched_params, id);
03542 #elif defined (ACE_HAS_PTHREADS) && \
03543 (!defined (ACE_LACKS_SETSCHED) || defined (ACE_TANDEM_T1248_PTHREADS) || \
03544 defined (ACE_HAS_PTHREAD_SCHEDPARAM))
03545 if (sched_params.quantum () != ACE_Time_Value::zero)
03546 {
03547
03548 errno = EINVAL;
03549 return -1;
03550 }
03551
03552
03553
03554
03555
03556
03557 struct sched_param param;
03558 param.sched_priority = sched_params.priority ();
03559
03560 if (sched_params.scope () == ACE_SCOPE_PROCESS)
03561 {
03562 # if defined(ACE_TANDEM_T1248_PTHREADS) || defined (ACE_HAS_PTHREAD_SCHEDPARAM)
03563 ACE_NOTSUP_RETURN (-1);
03564 # else
03565 int result = ::sched_setscheduler (id == ACE_SELF ? 0 : id,
03566 sched_params.policy (),
03567 ¶m) == -1 ? -1 : 0;
03568 # if defined (DIGITAL_UNIX)
03569 return result == 0
03570 ?
03571
03572 ACE_OS::set_scheduling_params (sched_params)
03573 : result;
03574 # else
03575 return result;
03576 # endif
03577 # endif
03578 }
03579 else if (sched_params.scope () == ACE_SCOPE_THREAD)
03580 {
03581 ACE_thread_t thr_id = ACE_OS::thr_self ();
03582
03583 # if defined (ACE_HAS_PTHREADS_DRAFT4)
03584 return (::pthread_setscheduler (thr_id,
03585 sched_params.policy (),
03586 sched_params.priority()) == -1 ? -1 : 0);
03587 # else
03588 int result;
03589 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setschedparam (thr_id,
03590 sched_params.policy (),
03591 ¶m),
03592 result),
03593 int, -1);
03594 # endif
03595 }
03596 # if defined (sun)
03597
03598
03599 else if (sched_params.scope () == ACE_SCOPE_LWP)
03600 return ACE_OS::set_scheduling_params (sched_params, id);
03601 # endif
03602 else
03603 {
03604 errno = EINVAL;
03605 return -1;
03606 }
03607
03608 #elif defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
03609
03610
03611
03612
03613 # if defined (ACE_HAS_PHARLAP_RT)
03614 if (id != ACE_SELF)
03615 ACE_NOTSUP_RETURN (-1);
03616
03617 if (sched_params.quantum() != ACE_Time_Value::zero)
03618 EtsSetTimeSlice (sched_params.quantum().msec());
03619
03620 # else
03621
03622 if (sched_params.quantum () != ACE_Time_Value::zero)
03623 {
03624
03625 errno = EINVAL;
03626 return -1;
03627 }
03628
03629 if (sched_params.scope () == ACE_SCOPE_THREAD)
03630 {
03631
03632
03633
03634
03635 #ifndef ACE_DISABLE_WIN32_INCREASE_PRIORITY
03636
03637
03638 if (!::SetPriorityClass (::GetCurrentProcess (),
03639 (sched_params.policy () == ACE_SCHED_FIFO ||
03640 sched_params.policy () == ACE_SCHED_RR)
03641 ? REALTIME_PRIORITY_CLASS
03642 : NORMAL_PRIORITY_CLASS))
03643 {
03644 ACE_OS::set_errno_to_last_error ();
03645 return -1;
03646 }
03647 #endif
03648
03649 # endif
03650
03651
03652 return ACE_OS::thr_setprio (sched_params.priority ());
03653 }
03654 else if (sched_params.scope () == ACE_SCOPE_PROCESS)
03655 {
03656 HANDLE hProcess = ::OpenProcess (PROCESS_SET_INFORMATION,
03657 FALSE,
03658 id);
03659 if (!hProcess)
03660 {
03661 ACE_OS::set_errno_to_last_error();
03662 return -1;
03663 }
03664
03665
03666
03667
03668
03669
03670 if (!::SetPriorityClass (hProcess,
03671 (sched_params.policy () == ACE_SCHED_FIFO ||
03672 sched_params.policy () == ACE_SCHED_RR)
03673 ? REALTIME_PRIORITY_CLASS
03674 : NORMAL_PRIORITY_CLASS))
03675 {
03676 ACE_OS::set_errno_to_last_error ();
03677 ::CloseHandle (hProcess);
03678 return -1;
03679 }
03680 ::CloseHandle (hProcess);
03681 return 0;
03682 }
03683 else
03684 {
03685 errno = EINVAL;
03686 return -1;
03687 }
03688 #elif defined (ACE_VXWORKS)
03689 ACE_UNUSED_ARG (id);
03690
03691
03692
03693
03694 if (sched_params.policy () != ACE_SCHED_FIFO
03695 || sched_params.scope () != ACE_SCOPE_PROCESS
03696 || sched_params.quantum () != ACE_Time_Value::zero)
03697 {
03698 errno = EINVAL;
03699 return -1;
03700 }
03701
03702
03703 return ACE_OS::thr_setprio (sched_params.priority ());
03704 #else
03705 ACE_UNUSED_ARG (sched_params);
03706 ACE_UNUSED_ARG (id);
03707 ACE_NOTSUP_RETURN (-1);
03708 #endif
03709 }
03710
03711 int
03712 ACE_OS::scheduling_class (const char *class_name, ACE_id_t &id)
03713 {
03714 #if defined (ACE_HAS_PRIOCNTL)
03715
03716 pcinfo_t pcinfo;
03717
03718
03719 ACE_OS::memset (&pcinfo, 0, sizeof pcinfo);
03720
03721 ACE_OS::strcpy (pcinfo.pc_clname, class_name);
03722 if (ACE_OS::priority_control (P_ALL ,
03723 P_MYID ,
03724 PC_GETCID,
03725 (char *) &pcinfo) == -1)
03726 {
03727 return -1;
03728 }
03729 else
03730 {
03731 id = pcinfo.pc_cid;
03732 return 0;
03733 }
03734 #else
03735 ACE_UNUSED_ARG (class_name);
03736 ACE_UNUSED_ARG (id);
03737 ACE_NOTSUP_RETURN (-1);
03738 #endif
03739 }
03740
03741 int
03742 ACE_OS::set_scheduling_params (const ACE_Sched_Params &sched_params,
03743 ACE_id_t id)
03744 {
03745 #if defined (ACE_HAS_PRIOCNTL)
03746
03747
03748
03749
03750 ACE_id_t class_id;
03751 if (ACE_OS::scheduling_class (sched_params.policy() == ACE_SCHED_OTHER ?
03752 "TS" :
03753 "RT", class_id) == -1)
03754 {
03755 return -1;
03756 }
03757
03758 pcparms_t pcparms;
03759
03760
03761 ACE_OS::memset (&pcparms, 0, sizeof pcparms);
03762
03763 pcparms.pc_cid = class_id;
03764
03765 if (sched_params.policy () == ACE_SCHED_OTHER &&
03766 sched_params.quantum () == ACE_Time_Value::zero)
03767
03768
03769 {
03770 tsparms_t tsparms;
03771
03772
03773 ACE_OS::memset (&tsparms, 0, sizeof tsparms);
03774
03775
03776 tsparms.ts_uprilim = TS_NOCHANGE;
03777 tsparms.ts_upri = sched_params.priority ();
03778
03779
03780
03781 ACE_OS::memcpy (pcparms.pc_clparms, &tsparms, sizeof tsparms);
03782 }
03783 else if (sched_params.policy () == ACE_SCHED_FIFO ||
03784 (sched_params.policy () == ACE_SCHED_RR &&
03785 sched_params.quantum () != ACE_Time_Value::zero))
03786
03787
03788
03789 {
03790 rtparms_t rtparms;
03791
03792
03793 ACE_OS::memset (&rtparms, 0, sizeof rtparms);
03794
03795 rtparms.rt_pri = sched_params.priority ();
03796
03797 if (sched_params.quantum () == ACE_Time_Value::zero)
03798 {
03799
03800 rtparms.rt_tqnsecs = RT_TQINF;
03801 }
03802 else
03803 {
03804 rtparms.rt_tqsecs = (ulong) sched_params.quantum ().sec ();
03805 rtparms.rt_tqnsecs = sched_params.quantum ().usec () * 1000;
03806 }
03807
03808
03809
03810 ACE_OS::memcpy (pcparms.pc_clparms, &rtparms, sizeof rtparms);
03811 }
03812 else
03813 {
03814 errno = EINVAL;
03815 return -1;
03816 }
03817
03818 if (ACE_OS::priority_control ((idtype_t) (sched_params.scope () == ACE_SCOPE_THREAD
03819 ? ACE_SCOPE_PROCESS
03820 : sched_params.scope ()),
03821 id,
03822 PC_SETPARMS,
03823 (char *) &pcparms) < 0)
03824 {
03825 return ACE_OS::last_error ();
03826 }
03827
03828 return 0;
03829 #else
03830 ACE_UNUSED_ARG (sched_params);
03831 ACE_UNUSED_ARG (id);
03832 ACE_NOTSUP_RETURN (-1);
03833 #endif
03834 }
03835
03836 int
03837 ACE_OS::thr_create (ACE_THR_FUNC func,
03838 void *args,
03839 long flags,
03840 ACE_thread_t *thr_id,
03841 ACE_hthread_t *thr_handle,
03842 long priority,
03843 void *stack,
03844 size_t stacksize,
03845 ACE_Base_Thread_Adapter *thread_adapter)
03846 {
03847 ACE_OS_TRACE ("ACE_OS::thr_create");
03848
03849 if (ACE_BIT_DISABLED (flags, THR_DETACHED) &&
03850 ACE_BIT_DISABLED (flags, THR_JOINABLE))
03851 ACE_SET_BITS (flags, THR_JOINABLE);
03852
03853 #if defined (ACE_NO_THREAD_ADAPTER)
03854 # define ACE_THREAD_FUNCTION func
03855 # define ACE_THREAD_ARGUMENT args
03856 #else
03857 # define ACE_THREAD_FUNCTION thread_args->entry_point ()
03858 # define ACE_THREAD_ARGUMENT thread_args
03859 #endif
03860
03861
03862 ACE_Base_Thread_Adapter *thread_args = 0;
03863 if (thread_adapter == 0)
03864 #if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
03865 ACE_NEW_RETURN (thread_args,
03866 ACE_OS_Thread_Adapter (func, args,
03867 (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME,
03868 ACE_OS_Object_Manager::seh_except_selector(),
03869 ACE_OS_Object_Manager::seh_except_handler()),
03870 -1);
03871 #else
03872 ACE_NEW_RETURN (thread_args,
03873 ACE_OS_Thread_Adapter (func, args,
03874 (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME),
03875 -1);
03876
03877 #endif
03878 else
03879 thread_args = thread_adapter;
03880
03881 auto_ptr <ACE_Base_Thread_Adapter> auto_thread_args;
03882
03883 if (thread_adapter == 0)
03884 ACE_AUTO_PTR_RESET (auto_thread_args,
03885 thread_args,
03886 ACE_Base_Thread_Adapter);
03887
03888 #if defined (ACE_HAS_THREADS)
03889
03890
03891 # if defined (ACE_NEEDS_HUGE_THREAD_STACKSIZE)
03892 if (stacksize < ACE_NEEDS_HUGE_THREAD_STACKSIZE)
03893 stacksize = ACE_NEEDS_HUGE_THREAD_STACKSIZE;
03894 # endif
03895
03896 # if !(defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS))
03897
03898
03899
03900
03901 ACE_thread_t tmp_thr;
03902
03903 if (thr_id == 0)
03904 thr_id = &tmp_thr;
03905 # endif
03906
03907 ACE_hthread_t tmp_handle;
03908 if (thr_handle == 0)
03909 thr_handle = &tmp_handle;
03910
03911 # if defined (ACE_HAS_PTHREADS)
03912
03913 int result;
03914 # if defined (ACE_VXWORKS) && (ACE_VXWORKS >= 0x600) && (ACE_VXWORKS <= 0x620)
03915
03916
03917
03918
03919 pthread_attr_t attr = {0};
03920 # else
03921 pthread_attr_t attr;
03922 # endif
03923 # if defined (ACE_HAS_PTHREADS_DRAFT4)
03924 if (ACE_ADAPT_RETVAL(::pthread_attr_create (&attr), result) != 0)
03925 # else
03926 if (ACE_ADAPT_RETVAL(::pthread_attr_init(&attr), result) != 0)
03927 # endif
03928 return -1;
03929
03930 if (stacksize != 0)
03931 {
03932 size_t size = stacksize;
03933
03934 # if defined (PTHREAD_STACK_MIN)
03935 if (size < static_cast <size_t> (PTHREAD_STACK_MIN))
03936 size = PTHREAD_STACK_MIN;
03937 # endif
03938
03939 # if !defined (ACE_LACKS_THREAD_STACK_SIZE) // JCEJ 12/17/96
03940 # if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
03941 if (::pthread_attr_setstacksize (&attr, size) != 0)
03942 # else
03943 # if defined (ACE_HAS_PTHREAD_SETSTACK)
03944 int result;
03945 if (stack != 0)
03946 result = ACE_ADAPT_RETVAL (pthread_attr_setstack (&attr, stack, size), result);
03947 else
03948 result = ACE_ADAPT_RETVAL (pthread_attr_setstacksize (&attr, size), result);
03949 if (result == -1)
03950 # else
03951 if (ACE_ADAPT_RETVAL (pthread_attr_setstacksize (&attr, size), result) == -1)
03952 # endif
03953 # endif
03954 {
03955 # if defined (ACE_HAS_PTHREADS_DRAFT4)
03956 ::pthread_attr_delete (&attr);
03957 # else
03958 ::pthread_attr_destroy (&attr);
03959 # endif
03960 return -1;
03961 }
03962 # else
03963 ACE_UNUSED_ARG (size);
03964 # endif
03965 }
03966
03967
03968 # if !defined (ACE_HAS_PTHREAD_SETSTACK)
03969 # if !defined (ACE_LACKS_THREAD_STACK_ADDR)
03970 if (stack != 0)
03971 {
03972 if (ACE_ADAPT_RETVAL(::pthread_attr_setstackaddr (&attr, stack), result) != 0)
03973 {
03974 # if defined (ACE_HAS_PTHREADS_DRAFT4)
03975 ::pthread_attr_delete (&attr);
03976 # else
03977 ::pthread_attr_destroy (&attr);
03978 # endif
03979 return -1;
03980 }
03981 }
03982 # else
03983 ACE_UNUSED_ARG (stack);
03984 # endif
03985 # endif
03986
03987
03988 if (flags != 0)
03989 {
03990
03991 # if !defined (ACE_LACKS_SETDETACH)
03992 if (ACE_BIT_ENABLED (flags, THR_DETACHED)
03993 || ACE_BIT_ENABLED (flags, THR_JOINABLE))
03994 {
03995 int dstate = PTHREAD_CREATE_JOINABLE;
03996
03997 if (ACE_BIT_ENABLED (flags, THR_DETACHED))
03998 dstate = PTHREAD_CREATE_DETACHED;
03999
04000 # if defined (ACE_HAS_PTHREADS_DRAFT4)
04001 if (::pthread_attr_setdetach_np (&attr, dstate) != 0)
04002 # else
04003 # if defined (ACE_HAS_PTHREADS_DRAFT6)
04004 if (::pthread_attr_setdetachstate (&attr, &dstate) != 0)
04005 # else
04006 if (ACE_ADAPT_RETVAL(::pthread_attr_setdetachstate (&attr, dstate),
04007 result) != 0)
04008 # endif
04009 # endif
04010 {
04011 # if defined (ACE_HAS_PTHREADS_DRAFT4)
04012 ::pthread_attr_delete (&attr);
04013 # else
04014 ::pthread_attr_destroy (&attr);
04015 # endif
04016 return -1;
04017 }
04018 }
04019
04020
04021
04022
04023
04024 # endif
04025
04026
04027 # if !defined (ACE_LACKS_SETSCHED) || defined (ACE_HAS_PTHREAD_SCHEDPARAM)
04028
04029
04030 if (priority != ACE_DEFAULT_THREAD_PRIORITY)
04031 {
04032 ACE_SET_BITS (flags, THR_EXPLICIT_SCHED);
04033 if (ACE_BIT_DISABLED (flags, THR_SCHED_FIFO)
04034 && ACE_BIT_DISABLED (flags, THR_SCHED_RR)
04035 && ACE_BIT_DISABLED (flags, THR_SCHED_DEFAULT))
04036 ACE_SET_BITS (flags, THR_SCHED_DEFAULT);
04037 }
04038
04039 if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO)
04040 || ACE_BIT_ENABLED (flags, THR_SCHED_RR)
04041 || ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT))
04042 {
04043 int spolicy;
04044
04045 # if defined (ACE_HAS_ONLY_SCHED_OTHER)
04046
04047 spolicy = SCHED_OTHER;
04048 # elif defined (ACE_HAS_ONLY_SCHED_FIFO)
04049
04050 spolicy = SCHED_FIFO;
04051 # else
04052
04053
04054 ACE_SET_BITS (flags, THR_EXPLICIT_SCHED);
04055
04056 if (ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT))
04057 spolicy = SCHED_OTHER;
04058 else if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO))
04059 spolicy = SCHED_FIFO;
04060 # if defined (SCHED_IO)
04061 else if (ACE_BIT_ENABLED (flags, THR_SCHED_IO))
04062 spolicy = SCHED_IO;
04063 # else
04064 else if (ACE_BIT_ENABLED (flags, THR_SCHED_IO))
04065 {
04066 errno = ENOSYS;
04067 return -1;
04068 }
04069 # endif
04070 else
04071 spolicy = SCHED_RR;
04072
04073 # if defined (ACE_HAS_FSU_PTHREADS)
04074 int ret;
04075 switch (spolicy)
04076 {
04077 case SCHED_FIFO:
04078 case SCHED_RR:
04079 ret = 0;
04080 break;
04081 default:
04082 ret = 22;
04083 break;
04084 }
04085 if (ret != 0)
04086 {
04087 ::pthread_attr_destroy (&attr);
04088 return -1;
04089 }
04090 # endif
04091
04092 # endif
04093
04094 # if defined (ACE_HAS_PTHREADS_DRAFT4)
04095 result = ::pthread_attr_setsched (&attr, spolicy);
04096 # elif defined (ACE_HAS_PTHREADS_DRAFT6)
04097 result = ::pthread_attr_setschedpolicy (&attr, spolicy);
04098 # else
04099 (void) ACE_ADAPT_RETVAL(::pthread_attr_setschedpolicy (&attr, spolicy),
04100 result);
04101 # endif
04102 if (result != 0)
04103 {
04104 # if defined (ACE_HAS_PTHREADS_DRAFT4)
04105 ::pthread_attr_delete (&attr);
04106 # else
04107 ::pthread_attr_destroy (&attr);
04108 # endif
04109 return -1;
04110 }
04111 }
04112
04113
04114 # if defined(ACE_HAS_PTHREADS_STD)
04115
04116
04117
04118
04119 if ((ACE_BIT_ENABLED (flags, THR_SCHED_FIFO)
04120 || ACE_BIT_ENABLED (flags, THR_SCHED_RR)
04121 || ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT))
04122 && priority == ACE_DEFAULT_THREAD_PRIORITY)
04123 {
04124 if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO))
04125 priority = ACE_THR_PRI_FIFO_DEF;
04126 else if (ACE_BIT_ENABLED (flags, THR_SCHED_RR))
04127 priority = ACE_THR_PRI_RR_DEF;
04128 else
04129 priority = ACE_THR_PRI_OTHER_DEF;
04130 }
04131 # endif
04132 if (priority != ACE_DEFAULT_THREAD_PRIORITY)
04133 {
04134 struct sched_param sparam;
04135 ACE_OS::memset ((void *) &sparam, 0, sizeof sparam);
04136
04137 # if defined (ACE_HAS_IRIX62_THREADS)
04138 sparam.sched_priority = ACE_MIN (priority,
04139 (long) PTHREAD_MAX_PRIORITY);
04140 # elif defined (PTHREAD_MAX_PRIORITY) && !defined(ACE_HAS_PTHREADS_STD)
04141
04142 sparam.prio = ACE_MIN (priority, PTHREAD_MAX_PRIORITY);
04143 # elif defined(ACE_HAS_PTHREADS_STD) && !defined (ACE_HAS_STHREADS)
04144
04145 if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO))
04146 sparam.sched_priority =
04147 ACE_MIN (ACE_THR_PRI_FIFO_MAX,
04148 ACE_MAX (ACE_THR_PRI_FIFO_MIN, priority));
04149 else if (ACE_BIT_ENABLED(flags, THR_SCHED_RR))
04150 sparam.sched_priority =
04151 ACE_MIN (ACE_THR_PRI_RR_MAX,
04152 ACE_MAX (ACE_THR_PRI_RR_MIN, priority));
04153 else
04154 sparam.sched_priority =
04155 ACE_MIN (ACE_THR_PRI_OTHER_MAX,
04156 ACE_MAX (ACE_THR_PRI_OTHER_MIN, priority));
04157 # elif defined (PRIORITY_MAX)
04158 sparam.sched_priority = ACE_MIN (priority,
04159 (long) PRIORITY_MAX);
04160 # else
04161 sparam.sched_priority = priority;
04162 # endif
04163
04164 # if defined (ACE_HAS_FSU_PTHREADS)
04165 if (sparam.sched_priority >= PTHREAD_MIN_PRIORITY
04166 && sparam.sched_priority <= PTHREAD_MAX_PRIORITY)
04167 attr.prio = sparam.sched_priority;
04168 else
04169 {
04170 pthread_attr_destroy (&attr);
04171 errno = EINVAL;
04172 return -1;
04173 }
04174 # else
04175 {
04176 # if defined (sun) && defined (ACE_HAS_ONLY_SCHED_OTHER)
04177
04178
04179
04180 if (priority > 0)
04181 # endif
04182 {
04183 # if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
04184 result = ::pthread_attr_setprio (&attr,
04185 sparam.sched_priority);
04186 # else
04187 (void) ACE_ADAPT_RETVAL(::pthread_attr_setschedparam (&attr, &sparam),
04188 result);
04189 # endif
04190 if (result != 0)
04191 {
04192 # if defined (ACE_HAS_PTHREADS_DRAFT4)
04193 ::pthread_attr_delete (&attr);
04194 # else
04195 ::pthread_attr_destroy (&attr);
04196 # endif
04197 return -1;
04198 }
04199 }
04200 }
04201 # endif
04202 }
04203
04204
04205 if (ACE_BIT_ENABLED (flags, THR_INHERIT_SCHED)
04206 || ACE_BIT_ENABLED (flags, THR_EXPLICIT_SCHED))
04207 {
04208 # if defined (ACE_HAS_PTHREADS_DRAFT4)
04209 int sched = PTHREAD_DEFAULT_SCHED;
04210 # else
04211 int sched = PTHREAD_EXPLICIT_SCHED;
04212 # endif
04213 if (ACE_BIT_ENABLED (flags, THR_INHERIT_SCHED))
04214 sched = PTHREAD_INHERIT_SCHED;
04215 if (ACE_ADAPT_RETVAL(::pthread_attr_setinheritsched (&attr, sched), result) != 0)
04216 {
04217 # if defined (ACE_HAS_PTHREADS_DRAFT4)
04218 ::pthread_attr_delete (&attr);
04219 # else
04220 ::pthread_attr_destroy (&attr);
04221 # endif
04222 return -1;
04223 }
04224 }
04225 # else
04226 ACE_UNUSED_ARG (priority);
04227 # endif
04228
04229
04230 # if !defined (ACE_LACKS_THREAD_PROCESS_SCOPING)
04231 if (ACE_BIT_ENABLED (flags, THR_SCOPE_SYSTEM)
04232 || ACE_BIT_ENABLED (flags, THR_SCOPE_PROCESS))
04233 {
04234 # if defined (ACE_CONFIG_LINUX_H) || defined (HPUX)
04235
04236
04237 int scope = PTHREAD_SCOPE_SYSTEM;
04238 # else
04239 int scope = PTHREAD_SCOPE_PROCESS;
04240 # endif
04241 if (ACE_BIT_ENABLED (flags, THR_SCOPE_SYSTEM))
04242 scope = PTHREAD_SCOPE_SYSTEM;
04243
04244 if (ACE_ADAPT_RETVAL(::pthread_attr_setscope (&attr, scope), result) != 0)
04245 {
04246 # if defined (ACE_HAS_PTHREADS_DRAFT4)
04247 ::pthread_attr_delete (&attr);
04248 # else
04249 ::pthread_attr_destroy (&attr);
04250 # endif
04251 return -1;
04252 }
04253 }
04254 # endif
04255
04256 # ifdef ACE_HAS_PTHREAD_ATTR_SETCREATESUSPEND_NP
04257 if (ACE_BIT_ENABLED (flags, THR_SUSPENDED))
04258 {
04259 if (ACE_ADAPT_RETVAL(::pthread_attr_setcreatesuspend_np(&attr), result) != 0)
04260 {
04261
04262 # if defined (ACE_HAS_PTHREADS_DRAFT4)
04263 ::pthread_attr_delete (&attr);
04264 # else
04265 ::pthread_attr_destroy (&attr);
04266 # endif
04267 return -1;
04268 }
04269 }
04270 # endif
04271
04272 if (ACE_BIT_ENABLED (flags, THR_NEW_LWP))
04273 {
04274
04275
04276 int lwps = ACE_OS::thr_getconcurrency ();
04277 if (lwps == -1)
04278 {
04279 if (errno == ENOTSUP)
04280
04281 errno = 0;
04282 else
04283
04284
04285 return -1;
04286 }
04287 else if (ACE_OS::thr_setconcurrency (lwps + 1) == -1)
04288 {
04289 if (errno == ENOTSUP)
04290 {
04291
04292
04293 }
04294 else
04295 return -1;
04296 }
04297 }
04298 }
04299
04300 # if defined (ACE_HAS_PTHREADS_DRAFT4)
04301 ACE_OSCALL (::pthread_create (thr_id, attr,
04302 thread_args->entry_point (),
04303 thread_args),
04304 int, -1, result);
04305
04306 # if defined (ACE_LACKS_SETDETACH)
04307 if (ACE_BIT_ENABLED (flags, THR_DETACHED))
04308 {
04309 ::pthread_detach (thr_id);
04310 }
04311 # endif
04312
04313 ::pthread_attr_delete (&attr);
04314
04315 # elif defined (ACE_HAS_PTHREADS_DRAFT6)
04316 ACE_OSCALL (::pthread_create (thr_id, &attr,
04317 thread_args->entry_point (),
04318 thread_args),
04319 int, -1, result);
04320 ::pthread_attr_destroy (&attr);
04321
04322 # else
04323 ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_create (thr_id,
04324 &attr,
04325 thread_args->entry_point (),
04326 thread_args),
04327 result),
04328 int, -1, result);
04329 ::pthread_attr_destroy (&attr);
04330 # endif
04331
04332
04333
04334
04335 if (result != -1)
04336 *thr_handle = *thr_id;
04337
04338 # if defined (sun) && defined (ACE_HAS_ONLY_SCHED_OTHER)
04339
04340
04341
04342
04343
04344
04345
04346
04347
04348
04349
04350
04351 if (priority == 0)
04352 {
04353
04354
04355
04356
04357 struct sched_param sparam;
04358 int policy = 0;
04359 ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_getschedparam (thr_self (),
04360 &policy,
04361 &sparam),
04362 result), int,
04363 -1, result);
04364
04365
04366
04367 policy = ACE_SCHED_OTHER;
04368
04369 if (sparam.sched_priority != 0)
04370 {
04371 ACE_OS::memset ((void *) &sparam, 0, sizeof sparam);
04372
04373
04374
04375 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setschedparam (*thr_id,
04376 policy,
04377 &sparam),
04378 result),
04379 int, -1);
04380 }
04381 }
04382
04383 # if defined (ACE_NEEDS_LWP_PRIO_SET)
04384 # if 0
04385
04386
04387
04388
04389
04390
04391
04392 if (ACE_BIT_ENABLED (flags, THR_BOUND))
04393 {
04394 ACE_Sched_Params sched_params (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO) ||
04395 ACE_BIT_ENABLED (flags, THR_SCHED_RR) ?
04396 ACE_SCHED_FIFO :
04397 ACE_SCHED_OTHER,
04398 priority);
04399 result = ACE_OS::lwp_setparams (sched_params,
04400
04401 );
04402 }
04403 # endif
04404 # endif
04405
04406 # endif
04407 auto_thread_args.release ();
04408 return result;
04409 # elif defined (ACE_HAS_STHREADS)
04410 int result;
04411 int start_suspended = ACE_BIT_ENABLED (flags, THR_SUSPENDED);
04412
04413 if (priority != ACE_DEFAULT_THREAD_PRIORITY)
04414
04415
04416 ACE_SET_BITS (flags, THR_SUSPENDED);
04417
04418 ACE_OSCALL (ACE_ADAPT_RETVAL (::thr_create (stack, stacksize,
04419 thread_args->entry_point (),
04420 thread_args,
04421 flags, thr_id), result),
04422 int, -1, result);
04423
04424 if (result != -1)
04425 {
04426
04427 *thr_handle = *thr_id;
04428
04429 if (priority != ACE_DEFAULT_THREAD_PRIORITY)
04430 {
04431
04432
04433
04434 result = ACE_OS::thr_setprio (*thr_id, priority);
04435 if (result != 0)
04436 {
04437 errno = result;
04438 return -1;
04439 }
04440
04441 if (start_suspended == 0)
04442 {
04443 result = ACE_OS::thr_continue (*thr_id);
04444 if (result != 0)
04445 {
04446 errno = result;
04447 return -1;
04448 }
04449 }
04450 }
04451 }
04452 auto_thread_args.release ();
04453 return result;
04454 # elif defined (ACE_HAS_WTHREADS)
04455 ACE_UNUSED_ARG (stack);
04456 # if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
04457 if (ACE_BIT_ENABLED (flags, THR_USE_AFX))
04458 {
04459 CWinThread *cwin_thread =
04460 ::AfxBeginThread ((AFX_THREADPROC) thread_args->entry_point (),
04461 thread_args,
04462 priority,
04463 0,
04464 flags | THR_SUSPENDED);
04465
04466
04467 # if !defined (ACE_HAS_WINCE)
04468 (void) ::DuplicateHandle (::GetCurrentProcess (),
04469 cwin_thread->m_hThread,
04470 ::GetCurrentProcess (),
04471 thr_handle,
04472 0,
04473 TRUE,
04474 DUPLICATE_SAME_ACCESS);
04475 # endif
04476 *thr_id = cwin_thread->m_nThreadID;
04477
04478 if (ACE_BIT_ENABLED (flags, THR_SUSPENDED) == 0)
04479 cwin_thread->ResumeThread ();
04480
04481
04482
04483 }
04484 else
04485 # endif
04486 {
04487 int start_suspended = ACE_BIT_ENABLED (flags, THR_SUSPENDED);
04488
04489 if (priority != ACE_DEFAULT_THREAD_PRIORITY)
04490
04491
04492 ACE_SET_BITS (flags, THR_SUSPENDED);
04493
04494 *thr_handle = (void *) ACE_BEGINTHREADEX (0,
04495 static_cast <u_int> (stacksize),
04496 thread_args->entry_point (),
04497 thread_args,
04498 flags,
04499 thr_id);
04500
04501 if (priority != ACE_DEFAULT_THREAD_PRIORITY && *thr_handle != 0)
04502 {
04503
04504
04505
04506 ACE_OS::thr_setprio (*thr_handle, priority);
04507
04508 if (start_suspended == 0)
04509 ACE_OS::thr_continue (*thr_handle);
04510 }
04511 }
04512 # if 0
04513 *thr_handle = ::CreateThread
04514 (0,
04515 stacksize,
04516 LPTHREAD_START_ROUTINE (thread_args->entry_point ()),
04517 thread_args,
04518 flags,
04519 thr_id);
04520 # endif
04521
04522
04523 if (thr_handle == &tmp_handle && tmp_handle != 0)
04524 ::CloseHandle (tmp_handle);
04525
04526 if (*thr_handle != 0)
04527 {
04528 auto_thread_args.release ();
04529 return 0;
04530 }
04531 else
04532 ACE_FAIL_RETURN (-1);
04533
04534
04535 # elif defined (ACE_VXWORKS)
04536
04537
04538
04539
04540
04541
04542
04543
04544 if (priority == ACE_DEFAULT_THREAD_PRIORITY) priority = 100;
04545
04546
04547 if (flags == 0) flags = VX_FP_TASK;
04548 if (stacksize == 0) stacksize = 20000;
04549
04550 const u_int thr_id_provided =
04551 thr_id && *thr_id && (*thr_id)[0] != ACE_THR_ID_ALLOCATED;
04552
04553 ACE_hthread_t tid;
04554 # if 0
04555 if (stack == 0)
04556 {
04557 # else
04558 ACE_UNUSED_ARG (stack);
04559 # endif
04560
04561
04562
04563 tid = ::taskSpawn (thr_id_provided ? *thr_id : 0,
04564 priority,
04565 (int) flags,
04566 (int) stacksize,
04567 thread_args->entry_point (),
04568 (int) thread_args,
04569 0, 0, 0, 0, 0, 0, 0, 0, 0);
04570 # if 0
04571 }
04572 else
04573 {
04574
04575
04576
04577
04578
04579 WIND_TCB *tcb = (WIND_TCB *) stack;
04580
04581
04582 int status = ::taskInit (tcb,
04583 thr_id_provided ? *thr_id : 0,
04584 priority,
04585 (int) flags,
04586 (char *) stack + sizeof (WIND_TCB),
04587 (int) (stacksize - sizeof (WIND_TCB)),
04588 thread_args->entry_point (),
04589 (int) thread_args,
04590 0, 0, 0, 0, 0, 0, 0, 0, 0);
04591
04592 if (status == OK)
04593 {
04594
04595 status = ::taskActivate ((ACE_hthread_t) tcb);
04596 }
04597
04598 tid = status == OK ? (ACE_hthread_t) tcb : ERROR;
04599 }
04600 # endif
04601
04602 if (tid == ERROR)
04603 return -1;
04604 else
04605 {
04606 if (! thr_id_provided && thr_id)
04607 {
04608 if (*thr_id && (*thr_id)[0] == ACE_THR_ID_ALLOCATED)
04609
04610
04611
04612
04613
04614
04615
04616 ACE_OS::strsncpy (*thr_id + 1, ::taskName (tid), 10);
04617 else
04618
04619
04620
04621 *thr_id = ::taskName (tid);
04622 }
04623
04624
04625
04626
04627 if (thr_handle)
04628 *thr_handle = tid;
04629
04630 auto_thread_args.release ();
04631 return 0;
04632 }
04633
04634 # endif
04635 #else
04636 ACE_UNUSED_ARG (func);
04637 ACE_UNUSED_ARG (args);
04638 ACE_UNUSED_ARG (flags);
04639 ACE_UNUSED_ARG (thr_id);
04640 ACE_UNUSED_ARG (thr_handle);
04641 ACE_UNUSED_ARG (priority);
04642 ACE_UNUSED_ARG (stack);
04643 ACE_UNUSED_ARG (stacksize);
04644 ACE_NOTSUP_RETURN (-1);
04645 #endif
04646 }
04647
04648 void
04649 ACE_OS::thr_exit (ACE_THR_FUNC_RETURN status)
04650 {
04651 ACE_OS_TRACE ("ACE_OS::thr_exit");
04652 #if defined (ACE_HAS_THREADS)
04653 # if defined (ACE_HAS_PTHREADS)
04654 ::pthread_exit (status);
04655 # elif defined (ACE_HAS_STHREADS)
04656 ::thr_exit (status);
04657 # elif defined (ACE_HAS_WTHREADS)
04658
04659
04660
04661
04662 # if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
04663 int using_afx = -1;
04664
04665
04666 ACE_OS_Thread_Descriptor *td =
04667 ACE_Base_Thread_Adapter::thr_desc_log_msg ();
04668 if (td)
04669 using_afx = ACE_BIT_ENABLED (td->flags (), THR_USE_AFX);
04670 # endif
04671
04672
04673 ACE_OS::cleanup_tss (0 );
04674
04675
04676
04677
04678
04679 # if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
04680 if (using_afx != -1)
04681 {
04682 if (using_afx)
04683 ::AfxEndThread (status);
04684 else
04685 ACE_ENDTHREADEX (status);
04686 }
04687 else
04688 {
04689
04690
04691
04692
04693 CWinThread *pThread = ::AfxGetThread ();
04694 if (!pThread || pThread->m_nThreadID != ACE_OS::thr_self ())
04695 ACE_ENDTHREADEX (status);
04696 else
04697 ::AfxEndThread (status);
04698 }
04699 # else
04700 ACE_ENDTHREADEX (status);
04701 # endif
04702
04703 # elif defined (ACE_VXWORKS)
04704 ACE_hthread_t tid;
04705 ACE_OS::thr_self (tid);
04706 *((int *) status) = ::taskDelete (tid);
04707 # endif
04708 #else
04709 ACE_UNUSED_ARG (status);
04710 #endif
04711 }
04712
04713 #if defined (ACE_VXWORKS) && !defined (ACE_HAS_PTHREADS)
04714
04715
04716 int ACE_THR_JOIN_DELAY = 5;
04717
04718 int
04719 ACE_OS::thr_join (ACE_hthread_t thr_handle,
04720 ACE_THR_FUNC_RETURN *status)
04721 {
04722
04723 if (status != 0)
04724 {
04725 *status = 0;
04726 }
04727
04728
04729 if (ACE_OS::thr_cmp (thr_handle, ACE_OS::NULL_hthread))
04730 {
04731 ACE_NOTSUP_RETURN (-1);
04732 }
04733
04734 int retval = ESRCH;
04735 ACE_hthread_t current;
04736 ACE_OS::thr_self (current);
04737
04738
04739 if (ACE_OS::thr_cmp (thr_handle, current))
04740 {
04741 retval = EDEADLK;
04742 }
04743 else
04744 {
04745
04746
04747 retval = 0;
04748
04749
04750 while (taskIdVerify (thr_handle) == OK)
04751 {
04752
04753 ACE_OS::sleep (ACE_THR_JOIN_DELAY);
04754 }
04755 }
04756
04757
04758
04759
04760 if (retval != 0)
04761 {
04762 errno = retval;
04763 retval = -1;
04764 }
04765
04766 return retval;
04767 }
04768
04769 int
04770 ACE_OS::thr_join (ACE_thread_t waiter_id,
04771 ACE_thread_t *thr_id,
04772 ACE_THR_FUNC_RETURN *status)
04773 {
04774 thr_id = 0;
04775 return ACE_OS::thr_join (taskNameToId (waiter_id), status);
04776 }
04777 #endif
04778
04779 int
04780 ACE_OS::thr_key_detach (ACE_thread_key_t key, void *)
04781 {
04782 #if defined (ACE_HAS_WTHREADS) || defined (ACE_HAS_TSS_EMULATION)
04783 TSS_Cleanup_Instance cleanup;
04784 if (cleanup.valid ())
04785 {
04786 return cleanup->thread_detach_key (key);
04787 }
04788 else
04789 {
04790 return -1;
04791 }
04792 #else
04793 ACE_UNUSED_ARG (key);
04794 ACE_NOTSUP_RETURN (-1);
04795 #endif
04796 }
04797
04798 int
04799 ACE_OS::thr_get_affinity (ACE_hthread_t thr_id,
04800 size_t cpu_set_size,
04801 cpu_set_t * cpu_mask)
04802 {
04803 #if defined (ACE_HAS_PTHREAD_GETAFFINITY_NP)
04804
04805 if (::pthread_getaffinity_np (thr_id,
04806 cpu_set_size,
04807 cpu_mask) != 0)
04808 {
04809 return -1;
04810 }
04811 return 0;
04812 #elif defined (ACE_HAS_2_PARAM_SCHED_GETAFFINITY)
04813
04814
04815
04816
04817 ACE_UNUSED_ARG (cpu_set_size);
04818 if (::sched_getaffinity(thr_id,
04819 cpu_mask) == -1)
04820 {
04821 return -1;
04822 }
04823 return 0;
04824 #elif defined (ACE_HAS_SCHED_GETAFFINITY)
04825
04826
04827
04828
04829 if (::sched_getaffinity(thr_id,
04830 cpu_set_size,
04831 cpu_mask) == -1)
04832 {
04833 return -1;
04834 }
04835 return 0;
04836 #else
04837 ACE_UNUSED_ARG (thr_id);
04838 ACE_UNUSED_ARG (cpu_set_size);
04839 ACE_UNUSED_ARG (cpu_mask);
04840 ACE_NOTSUP_RETURN (-1);
04841 #endif
04842 }
04843
04844 int
04845 ACE_OS::thr_set_affinity (ACE_hthread_t thr_id,
04846 size_t cpu_set_size,
04847 const cpu_set_t * cpu_mask)
04848 {
04849 #if defined (ACE_HAS_PTHREAD_SETAFFINITY_NP)
04850 if (::pthread_setaffinity_np (thr_id,
04851 cpu_set_size,
04852 cpu_mask) != 0)
04853 {
04854 return -1;
04855 }
04856 return 0;
04857 #elif defined (ACE_HAS_2_PARAM_SCHED_SETAFFINITY)
04858
04859
04860
04861
04862
04863 ACE_UNUSED_ARG (cpu_set_size);
04864 if (::sched_setaffinity (thr_id,
04865 cpu_mask) == -1)
04866 {
04867 return -1;
04868 }
04869 return 0;
04870 #elif defined (ACE_HAS_SCHED_SETAFFINITY)
04871
04872
04873
04874
04875
04876 if (::sched_setaffinity (thr_id,
04877 cpu_set_size,
04878 cpu_mask) == -1)
04879 {
04880 return -1;
04881 }
04882 return 0;
04883 #else
04884 ACE_UNUSED_ARG (thr_id);
04885 ACE_UNUSED_ARG (cpu_set_size);
04886 ACE_UNUSED_ARG (cpu_mask);
04887 ACE_NOTSUP_RETURN (-1);
04888 #endif
04889 }
04890
04891 int
04892 ACE_OS::thr_key_used (ACE_thread_key_t key)
04893 {
04894 #if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION)
04895 TSS_Cleanup_Instance cleanup;
04896 if (cleanup.valid ())
04897 {
04898 cleanup->thread_use_key (key);
04899 return 0;
04900 }
04901 return -1;
04902 #else
04903 ACE_UNUSED_ARG (key);
04904 ACE_NOTSUP_RETURN (-1);
04905 #endif
04906 }
04907
04908 #if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
04909 int
04910 ACE_OS::thr_keycreate_native (ACE_OS_thread_key_t *key,
04911 # if defined (ACE_HAS_THR_C_DEST)
04912 ACE_THR_C_DEST dest
04913 # else
04914 ACE_THR_DEST dest
04915 # endif
04916 )
04917 {
04918
04919
04920 # if defined (ACE_HAS_THREADS)
04921 # if defined (ACE_HAS_PTHREADS)
04922
04923 # if defined (ACE_HAS_PTHREADS_DRAFT4)
04924 # if defined (ACE_HAS_STDARG_THR_DEST)
04925 ACE_OSCALL_RETURN (::pthread_keycreate (key, (void (*)(...)) dest), int, -1);
04926 # else
04927 ACE_OSCALL_RETURN (::pthread_keycreate (key, dest), int, -1);
04928 # endif
04929 # elif defined (ACE_HAS_PTHREADS_DRAFT6)
04930 ACE_OSCALL_RETURN (::pthread_key_create (key, dest), int, -1);
04931 # else
04932 int result;
04933 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_key_create (key, dest),
04934 result),
04935 int, -1);
04936 # endif
04937 # elif defined (ACE_HAS_STHREADS)
04938 int result;
04939 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_keycreate (key, dest),
04940 result),
04941 int, -1);
04942 # elif defined (ACE_HAS_WTHREADS)
04943 ACE_UNUSED_ARG (dest);
04944 *key = ::TlsAlloc ();
04945
04946 if (*key == ACE_SYSCALL_FAILED)
04947 ACE_FAIL_RETURN (-1);
04948 return 0;
04949 # endif
04950 # else
04951 ACE_UNUSED_ARG (key);
04952 ACE_UNUSED_ARG (dest);
04953 ACE_NOTSUP_RETURN (-1);
04954 # endif
04955 }
04956 #endif
04957
04958 int
04959 ACE_OS::thr_keycreate (ACE_thread_key_t *key,
04960 # if defined (ACE_HAS_THR_C_DEST)
04961 ACE_THR_C_DEST dest,
04962 # else
04963 ACE_THR_DEST dest,
04964 # endif
04965 void *)
04966 {
04967
04968 #if defined (ACE_HAS_THREADS)
04969 # if defined (ACE_HAS_TSS_EMULATION)
04970 if (ACE_TSS_Emulation::next_key (*key) == 0)
04971 {
04972 ACE_TSS_Emulation::tss_destructor (*key, dest);
04973
04974
04975
04976 TSS_Cleanup_Instance cleanup (TSS_Cleanup_Instance::CREATE);
04977 if (cleanup.valid ())
04978 {
04979 return cleanup->insert (*key, dest);
04980 }
04981 else
04982 {
04983 return -1;
04984 }
04985 }
04986 else
04987 return -1;
04988 # elif defined (ACE_HAS_WTHREADS)
04989 if (ACE_OS::thr_keycreate_native (key, dest) == 0)
04990 {
04991
04992
04993 TSS_Cleanup_Instance cleanup (TSS_Cleanup_Instance::CREATE);
04994 if (cleanup.valid ())
04995 {
04996 return cleanup->insert (*key, dest);
04997 }
04998 else
04999 {
05000 return -1;
05001 }
05002 }
05003 else
05004 return -1;
05005
05006 # elif defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
05007 return ACE_OS::thr_keycreate_native (key, dest);
05008 # else
05009 ACE_UNUSED_ARG (key);
05010 ACE_UNUSED_ARG (dest);
05011 ACE_NOTSUP_RETURN (-1);
05012 # endif
05013 # else
05014 ACE_UNUSED_ARG (key);
05015 ACE_UNUSED_ARG (dest);
05016 ACE_NOTSUP_RETURN (-1);
05017 # endif
05018 }
05019
05020 #if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
05021 int
05022 ACE_OS::thr_keyfree_native (ACE_OS_thread_key_t key)
05023 {
05024 ACE_OS_TRACE ("ACE_OS::thr_keyfree_native");
05025 # if defined (ACE_HAS_THREADS)
05026 # if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
05027 ACE_UNUSED_ARG (key);
05028 ACE_NOTSUP_RETURN (-1);
05029 # elif defined (ACE_HAS_PTHREADS)
05030 return ::pthread_key_delete (key);
05031 # elif defined (ACE_HAS_THR_KEYDELETE)
05032 return ::thr_keydelete (key);
05033 # elif defined (ACE_HAS_STHREADS)
05034 ACE_UNUSED_ARG (key);
05035 ACE_NOTSUP_RETURN (-1);
05036 # elif defined (ACE_HAS_WTHREADS)
05037 ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::TlsFree (key), ace_result_), int, -1);
05038 # else
05039 ACE_UNUSED_ARG (key);
05040 ACE_NOTSUP_RETURN (-1);
05041 # endif
05042 # else
05043 ACE_UNUSED_ARG (key);
05044 ACE_NOTSUP_RETURN (-1);
05045 # endif
05046 }
05047 #endif
05048
05049 int
05050 ACE_OS::thr_keyfree (ACE_thread_key_t key)
05051 {
05052 ACE_OS_TRACE ("ACE_OS::thr_keyfree");
05053 # if defined (ACE_HAS_THREADS)
05054 # if defined (ACE_HAS_TSS_EMULATION)
05055
05056 ACE_TSS_Emulation::release_key (key);
05057 TSS_Cleanup_Instance cleanup;
05058 if (cleanup.valid ())
05059 {
05060 return cleanup->free_key (key);
05061 }
05062 return -1;
05063 # elif defined (ACE_HAS_WTHREADS)
05064
05065
05066 TSS_Cleanup_Instance cleanup;
05067 if (cleanup.valid ())
05068 {
05069 return cleanup->free_key (key);
05070 }
05071 return -1;
05072 # elif defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
05073 return ACE_OS::thr_keyfree_native (key);
05074 # else
05075 ACE_UNUSED_ARG (key);
05076 ACE_NOTSUP_RETURN (-1);
05077 # endif
05078 # else
05079 ACE_UNUSED_ARG (key);
05080 ACE_NOTSUP_RETURN (-1);
05081 return 0;
05082 # endif
05083 }
05084
05085 int
05086 ACE_OS::thr_setprio (const ACE_Sched_Priority prio)
05087 {
05088
05089 ACE_hthread_t my_thread_id;
05090 ACE_OS::thr_self (my_thread_id);
05091
05092 int status = ACE_OS::thr_setprio (my_thread_id, prio);
05093
05094 #if defined (ACE_NEEDS_LWP_PRIO_SET)
05095
05096
05097
05098
05099
05100 if (status == 0)
05101 {
05102
05103 ACE_Sched_Params sched_params (ACE_SCHED_OTHER, 0);
05104 if (ACE_OS::lwp_getparams (sched_params) == -1)
05105 {
05106 return -1;
05107 }
05108 else if (sched_params.policy () == ACE_SCHED_FIFO ||
05109 sched_params.policy () == ACE_SCHED_RR)
05110 {
05111
05112
05113 sched_params.priority (prio);
05114 return ACE_OS::lwp_setparams (sched_params);
05115 }
05116
05117
05118 }
05119 #endif
05120
05121 return status;
05122 }
05123
05124 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
05125 int
05126 ACE_OS::thr_setspecific_native (ACE_OS_thread_key_t key, void *data)
05127 {
05128
05129 # if defined (ACE_HAS_THREADS)
05130 # if defined (ACE_HAS_PTHREADS)
05131 # if defined (ACE_HAS_FSU_PTHREADS)
05132
05133
05134
05135
05136
05137
05138
05139 pthread_init ();
05140 # endif
05141 # if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
05142 ACE_OSCALL_RETURN (::pthread_setspecific (key, data), int, -1);
05143 # else
05144 int result;
05145 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_setspecific (key, data),
05146 result),
05147 int, -1);
05148 # endif
05149
05150 # elif defined (ACE_HAS_STHREADS)
05151 int result;
05152 ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setspecific (key, data), result), int, -1);
05153 # elif defined (ACE_HAS_WTHREADS)
05154 ::TlsSetValue (key, data);
05155 return 0;
05156 # else
05157 ACE_UNUSED_ARG (key);
05158 ACE_UNUSED_ARG (data);
05159 ACE_NOTSUP_RETURN (-1);
05160 # endif
05161 # else
05162 ACE_UNUSED_ARG (key);
05163 ACE_UNUSED_ARG (data);
05164 ACE_NOTSUP_RETURN (-1);
05165 # endif
05166 }
05167 # endif
05168
05169 int
05170 ACE_OS::thr_setspecific (ACE_thread_key_t key, void *data)
05171 {
05172
05173 #if defined (ACE_HAS_THREADS)
05174 # if defined (ACE_HAS_TSS_EMULATION)
05175 if (ACE_TSS_Emulation::is_key (key) == 0)
05176 {
05177 errno = EINVAL;
05178 data = 0;
05179 return -1;
05180 }
05181 else
05182 {
05183 ACE_TSS_Emulation::ts_object (key) = data;
05184 TSS_Cleanup_Instance cleanup;
05185 if (cleanup.valid ())
05186 {
05187 cleanup->thread_use_key (key);
05188
05189
05190
05191 if (data == 0)
05192 {
05193 cleanup->thread_detach_key (key);
05194 }
05195 return 0;
05196 }
05197 else
05198 {
05199 return -1;
05200 }
05201 }
05202 # elif defined (ACE_HAS_WTHREADS)
05203 if (ACE_OS::thr_setspecific_native (key, data) == 0)
05204 {
05205 TSS_Cleanup_Instance cleanup;
05206 if (cleanup.valid ())
05207 {
05208 cleanup->thread_use_key (key);
05209
05210
05211
05212 if (data == 0)
05213 {
05214 cleanup->thread_detach_key (key);
05215 }
05216 return 0;
05217 }
05218 return -1;
05219 }
05220 return -1;
05221 # elif defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
05222 return ACE_OS::thr_setspecific_native (key, data);
05223 # else
05224 ACE_UNUSED_ARG (key);
05225 ACE_UNUSED_ARG (data);
05226 ACE_NOTSUP_RETURN (-1);
05227 # endif
05228 # else
05229 ACE_UNUSED_ARG (key);
05230 ACE_UNUSED_ARG (data);
05231 ACE_NOTSUP_RETURN (-1);
05232 # endif
05233 }
05234
05235 void
05236 ACE_OS::unique_name (const void *object,
05237 char *name,
05238 size_t length)
05239 {
05240
05241
05242
05243
05244
05245 char temp_name[ACE_UNIQUE_NAME_LEN];
05246 ACE_OS::sprintf (temp_name,
05247 "%p%d",
05248 object,
05249 static_cast <int> (ACE_OS::getpid ()));
05250 ACE_OS::strsncpy (name,
05251 temp_name,
05252 length);
05253 }
05254
05255 #if defined (ACE_USES_WCHAR)
05256 void
05257 ACE_OS::unique_name (const void *object,
05258 wchar_t *name,
05259 size_t length)
05260 {
05261
05262
05263
05264
05265
05266 wchar_t temp_name[ACE_UNIQUE_NAME_LEN];
05267 ACE_OS::sprintf (temp_name,
05268 ACE_LIB_TEXT ("%p%d"),
05269 object,
05270 static_cast <int> (ACE_OS::getpid ()));
05271 ACE_OS::strsncpy (name,
05272 temp_name,
05273 length);
05274 }
05275 #endif
05276
05277 ACE_END_VERSIONED_NAMESPACE_DECL
05278
05279 #if defined (ACE_VXWORKS) && !defined (__RTP__)
05280 # include <usrLib.h>
05281 # include <sysLib.h>
05282
05283
05284
05285
05286
05287
05288
05289 int
05290 spa (FUNCPTR entry, ...)
05291 {
05292 static const unsigned int ACE_MAX_ARGS = 10;
05293 static char *argv[ACE_MAX_ARGS];
05294 va_list pvar;
05295 unsigned int argc;
05296
05297
05298
05299 argv[0] = "ace_main";
05300
05301
05302
05303
05304
05305
05306
05307 va_start (pvar, entry);
05308
05309 for (argc = 1; argc <= ACE_MAX_ARGS; ++argc)
05310 {
05311 argv[argc] = va_arg (pvar, char *);
05312
05313 if (argv[argc] == 0)
05314 break;
05315 }
05316
05317 if (argc > ACE_MAX_ARGS && argv[argc-1] != 0)
05318 {
05319
05320 if (va_arg (pvar, char *) != 0)
05321 ACE_OS::fprintf (stderr, "spa(): number of arguments limited to %d\n",
05322 ACE_MAX_ARGS);
05323 }
05324 else
05325 {
05326
05327
05328 for (unsigned int i = argc; i <= ACE_MAX_ARGS; ++i)
05329 argv[i] = 0;
05330 }
05331
05332
05333
05334 const int ret = ::taskSpawn (argv[0],
05335 100,
05336 VX_FP_TASK,
05337 ACE_NEEDS_HUGE_THREAD_STACKSIZE,
05338 entry,
05339 argc,
05340 (int) argv,
05341 0, 0, 0, 0, 0, 0, 0, 0);
05342 va_end (pvar);
05343
05344
05345
05346 return ret > 0 ? 0 : ret;
05347 }
05348
05349
05350 static void
05351 add_to_argv (int& argc, char** argv, int max_args, char* string)
05352 {
05353 char indouble = 0;
05354 size_t previous = 0;
05355 size_t length = ACE_OS::strlen (string);
05356
05357
05358 for (size_t i = 0; i <= length; i++)
05359 {
05360
05361 if (string[i] == '\"' && (i == 0 || string[i - 1] != '\\'))
05362 {
05363 indouble ^= 1;
05364 if (indouble)
05365 {
05366
05367
05368 previous = i + 1;
05369 }
05370 else
05371 {
05372
05373
05374 string[i] = '\0';
05375 }
05376 }
05377 else if (string[i] == '\\')
05378 {
05379
05380
05381 ACE_OS::strcpy (string + i, string + i + 1);
05382 length--;
05383 }
05384 else if (!indouble &&
05385 (ACE_OS::ace_isspace (string[i]) || string[i] == '\0'))
05386 {
05387 string[i] = '\0';
05388 if (argc < max_args)
05389 {
05390 argv[argc] = string + previous;
05391 argc++;
05392 }
05393 else
05394 {
05395 ACE_OS::fprintf (stderr, "spae(): number of arguments "
05396 "limited to %d\n", max_args);
05397 }
05398
05399
05400 for(++i; i < length && ACE_OS::ace_isspace (string[i]); ++i)
05401 {
05402 }
05403
05404
05405 previous = i;
05406
05407
05408
05409 i--;
05410 }
05411 }
05412 }
05413
05414
05415
05416
05417
05418
05419
05420 int
05421 spae (FUNCPTR entry, ...)
05422 {
05423 static const int WINDSH_ARGS = 10;
05424 static const int ACE_MAX_ARGS = 128;
05425 static char* argv[ACE_MAX_ARGS] = { "ace_main", 0 };
05426 va_list pvar;
05427 int argc = 1;
05428
05429
05430
05431
05432
05433 va_start (pvar, entry);
05434
05435 int i = 0;
05436 for (char* str = va_arg (pvar, char*);
05437 str != 0 && i < WINDSH_ARGS; str = va_arg (pvar, char*), ++i)
05438 {
05439 add_to_argv(argc, argv, ACE_MAX_ARGS, str);
05440 }
05441
05442
05443
05444 for (i = argc; i < ACE_MAX_ARGS; ++i)
05445 argv[i] = 0;
05446
05447
05448
05449 const int ret = ::taskSpawn (argv[0],
05450 100,
05451 VX_FP_TASK,
05452 ACE_NEEDS_HUGE_THREAD_STACKSIZE,
05453 entry,
05454 argc,
05455 (int) argv,
05456 0, 0, 0, 0, 0, 0, 0, 0);
05457 va_end (pvar);
05458
05459
05460
05461 return ret > 0 ? 0 : ret;
05462 }
05463
05464
05465
05466
05467
05468
05469
05470
05471
05472
05473
05474 int
05475 spaef (FUNCPTR entry, ...)
05476 {
05477 static const int WINDSH_ARGS = 10;
05478 static const int ACE_MAX_ARGS = 128;
05479 static char* argv[ACE_MAX_ARGS] = { "ace_main", 0 };
05480 va_list pvar;
05481 int argc = 1;
05482
05483
05484
05485
05486
05487 va_start (pvar, entry);
05488
05489 int i = 0;
05490 for (char* str = va_arg (pvar, char*);
05491 str != 0 && i < WINDSH_ARGS; str = va_arg (pvar, char*), ++i)
05492 {
05493 add_to_argv(argc, argv, ACE_MAX_ARGS, str);
05494 }
05495
05496
05497
05498 for (i = argc; i < ACE_MAX_ARGS; ++i)
05499 argv[i] = 0;
05500
05501 int ret = entry (argc, argv);
05502
05503 va_end (pvar);
05504
05505
05506 return ret;
05507 }
05508
05509
05510
05511
05512
05513
05514
05515
05516
05517 static int _vx_call_rc = 0;
05518
05519 static int
05520 _vx_call_entry(FUNCPTR entry, int argc, char* argv[])
05521 {
05522 _vx_call_rc = entry (argc, argv);
05523 return _vx_call_rc;
05524 }
05525
05526 int
05527 vx_execae (FUNCPTR entry, char* arg, int prio, int opt, int stacksz, ...)
05528 {
05529 static const int ACE_MAX_ARGS = 128;
05530 static char* argv[ACE_MAX_ARGS] = { "ace_main", 0 };
05531 int argc = 1;
05532
05533
05534
05535 if (arg)
05536 add_to_argv(argc, argv, ACE_MAX_ARGS, arg);
05537
05538
05539
05540 for (int i = argc; i < ACE_MAX_ARGS; ++i)
05541 argv[i] = 0;
05542
05543
05544
05545 const int ret = ::taskSpawn (argv[0],
05546 prio==0 ? 100 : prio,
05547 opt==0 ? VX_FP_TASK : opt,
05548 stacksz==0 ? ACE_NEEDS_HUGE_THREAD_STACKSIZE : stacksz,
05549 (FUNCPTR)_vx_call_entry,
05550 (int)entry,
05551 argc,
05552 (int) argv,
05553 0, 0, 0, 0, 0, 0, 0);
05554
05555 while( ret > 0 && ::taskIdVerify (ret) != ERROR )
05556 ::taskDelay (3 * ::sysClkRateGet ());
05557
05558
05559
05560 return ret > 0 ? _vx_call_rc : 255;
05561 }
05562 #endif
05563
05564 #if defined (__DGUX) && defined (ACE_HAS_THREADS) && defined (_POSIX4A_DRAFT10_SOURCE)
05565 extern "C" int __d6_sigwait (sigset_t *set);
05566
05567 extern "C" int __d10_sigwait (const sigset_t *set, int *sig)
05568 {
05569 sigset_t unconst_set = *set;
05570 int caught_sig = __d6_sigwait (&unconst_set);
05571
05572 if (caught == -1)
05573 return -1;
05574
05575 *sig = caught_sig;
05576 return 0;
05577 }
05578 #endif