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