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