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