summaryrefslogtreecommitdiff
path: root/ace/OS_NS_Thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ace/OS_NS_Thread.cpp')
-rw-r--r--ace/OS_NS_Thread.cpp760
1 files changed, 393 insertions, 367 deletions
diff --git a/ace/OS_NS_Thread.cpp b/ace/OS_NS_Thread.cpp
index 2286002754e..5f5cfd52fd0 100644
--- a/ace/OS_NS_Thread.cpp
+++ b/ace/OS_NS_Thread.cpp
@@ -18,6 +18,7 @@ ACE_RCSID (ace,
#include "ace/OS_NS_ctype.h"
#include "ace/Log_Msg.h" // for ACE_ASSERT
// This is necessary to work around nasty problems with MVS C++.
+#include "ace/Auto_Ptr.h"
extern "C" void
ace_mutex_lock_cleanup_adapter (void *args)
@@ -138,8 +139,7 @@ ACE_Thread_ID::to_string (char *thr_string)
ACE_OS::strcpy (fp, "u");
ACE_OS::sprintf (thr_string,
format,
- ACE_static_cast (unsigned,
- thread_id_));
+ static_cast <unsigned> (thread_id_));
#elif defined (ACE_AIX_VERS) && (ACE_AIX_VERS <= 402)
// AIX's pthread_t (ACE_hthread_t) is a pointer, and it's
// a little ugly to send that through a %u format. So,
@@ -258,9 +258,10 @@ ACE_TSS_Emulation::tss_base (void* ts_storage[], u_int *ts_created)
if (key_created_ == 0)
{
ACE_NO_HEAP_CHECK;
- if (ACE_OS::thr_keycreate (&native_tss_key_,
+ if (ACE_OS::thr_keycreate_native (&native_tss_key_,
&ACE_TSS_Emulation_cleanup) != 0)
{
+ ACE_ASSERT (0);
return 0; // Major problems, this should *never* happen!
}
key_created_ = 1;
@@ -270,9 +271,12 @@ ACE_TSS_Emulation::tss_base (void* ts_storage[], u_int *ts_created)
void **old_ts_storage = 0;
// Get the tss_storage from thread-OS specific storage.
- if (ACE_OS::thr_getspecific (native_tss_key_,
+ if (ACE_OS::thr_getspecific_native (native_tss_key_,
(void **) &old_ts_storage) == -1)
- return 0; // This should not happen!
+ {
+ ACE_ASSERT (false);
+ return 0; // This should not happen!
+ }
// Check to see if this is the first time in for this thread.
// This block can also be entered after a fork () in the child process,
@@ -309,9 +313,12 @@ ACE_TSS_Emulation::tss_base (void* ts_storage[], u_int *ts_created)
// Store the pointer in thread-specific storage. It gets
// deleted via the ACE_TSS_Emulation_cleanup function when the
// thread terminates.
- if (ACE_OS::thr_setspecific (native_tss_key_,
+ if (ACE_OS::thr_setspecific_native (native_tss_key_,
(void *) ts_storage) != 0)
- return 0; // Major problems, this should *never* happen!
+ {
+ ACE_ASSERT (false);
+ return 0; // This should not happen!
+ }
}
else
if (ts_created)
@@ -325,8 +332,8 @@ u_int
ACE_TSS_Emulation::total_keys ()
{
ACE_OS_Recursive_Thread_Mutex_Guard (
- *ACE_static_cast (ACE_recursive_thread_mutex_t *,
- ACE_OS_Object_Manager::preallocated_object[
+ *static_cast <ACE_recursive_thread_mutex_t *>
+ (ACE_OS_Object_Manager::preallocated_object[
ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
return total_keys_;
@@ -336,8 +343,8 @@ int
ACE_TSS_Emulation::next_key (ACE_thread_key_t &key)
{
ACE_OS_Recursive_Thread_Mutex_Guard (
- *ACE_static_cast (ACE_recursive_thread_mutex_t *,
- ACE_OS_Object_Manager::preallocated_object[
+ *static_cast <ACE_recursive_thread_mutex_t *>
+ (ACE_OS_Object_Manager::preallocated_object[
ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
// Initialize the tss_keys_used_ pointer on first use.
@@ -383,8 +390,8 @@ int
ACE_TSS_Emulation::release_key (ACE_thread_key_t key)
{
ACE_OS_Recursive_Thread_Mutex_Guard (
- *ACE_static_cast (ACE_recursive_thread_mutex_t *,
- ACE_OS_Object_Manager::preallocated_object[
+ *static_cast <ACE_recursive_thread_mutex_t *>
+ (ACE_OS_Object_Manager::preallocated_object[
ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
if (tss_keys_used_ != 0 &&
@@ -396,6 +403,22 @@ ACE_TSS_Emulation::release_key (ACE_thread_key_t key)
return 1;
}
+int
+ACE_TSS_Emulation::is_key (ACE_thread_key_t key)
+{
+ ACE_OS_Recursive_Thread_Mutex_Guard (
+ *static_cast <ACE_recursive_thread_mutex_t *>
+ (ACE_OS_Object_Manager::preallocated_object[
+ ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
+
+ if (tss_keys_used_ != 0 &&
+ tss_keys_used_->is_set (key) == 1)
+ {
+ return 1;
+ }
+ return 0;
+}
+
void *
ACE_TSS_Emulation::tss_open (void *ts_storage[ACE_TSS_THREAD_KEYS_MAX])
{
@@ -451,9 +474,9 @@ ACE_TSS_Emulation::tss_open (void *ts_storage[ACE_TSS_THREAD_KEYS_MAX])
void
ACE_TSS_Emulation::tss_close ()
{
-# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
- // Free native_tss_key_ here.
-# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
+#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ ACE_OS::thr_keyfree_native (native_tss_key_);
+#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
}
#endif /* ACE_HAS_TSS_EMULATION */
@@ -613,7 +636,7 @@ ACE_TSS_Keys::test_and_clear (const ACE_thread_key_t key)
u_int word, bit;
find (key_index, word, bit);
- if (ACE_BIT_ENABLED (key_bit_words_[word], 1 << bit))
+ if (word < ACE_WORDS && ACE_BIT_ENABLED (key_bit_words_[word], 1 << bit))
{
ACE_CLR_BITS (key_bit_words_[word], 1 << bit);
return 0;
@@ -631,38 +654,14 @@ ACE_TSS_Keys::is_set (const ACE_thread_key_t key) const
u_int word, bit;
find (key_index, word, bit);
- return ACE_BIT_ENABLED (key_bit_words_[word], 1 << bit);
+ return word < ACE_WORDS ? ACE_BIT_ENABLED (key_bit_words_[word], 1 << bit) : 0;
}
/*****************************************************************************/
/**
* @class ACE_TSS_Cleanup
- *
* @brief Singleton that helps to manage the lifetime of TSS objects and keys.
- *
- ***********************************************************************
- * Behavior of TSS_Cleanup was changed to eliminate leaks:
- * +------OLD------------+--------NEW---------
- * Action | exit| detach | exit : detach : remove
- * -------------------------- | Always: Last | : : (if...)
- * --key_info->thread_count_ X | X : | X : :
- * destructor(tss_obj) X | [4] : | X : :
- * tss_keys ()->test_and_clear X | X[2] : X[2] | X : :
- * key_info->inst = 0 | X[2] : X[1] | : X :
- * | | remove : remove :
- * key_info->in_use (0) | : X[1] | : : X
- * key_info->key_ = NULL [6] | : X[1] | : :
- * key_info->destructor=0 | : X[1] | : : X
- * release tss key [4] | : X | : : X
- * clear key in_use_ | : [5] | : : X
- *----------------------------------------------------------------------
- * [1] delegated to remove
- * [2] done twice;
- * [3] this is a bug. It should not be done here
- * [4] Resource leak--should be done, but it's not.
- * [5] Should be done here, but it's not.
- * [6] Unnecessary and problematic.
*/
class ACE_TSS_Cleanup
{
@@ -670,21 +669,28 @@ public:
static ACE_TSS_Cleanup *instance (void);
~ACE_TSS_Cleanup (void);
-
- /// Cleanup the thread-specific objects. Does _NOT_ exit the thread.
- void exit (void *status);
-
- /// Insert a <key, destructor> tuple into the table.
+ /// Register a newly-allocated key
+ /// @param key the key to be monitored
+ /// @param destructor the function to call to delete objects stored via this key
+ /// @param inst an opaque value used to reserve this key. If inst is zero then
+ /// the key is freed when the thread-use count goes to zero.
int insert (ACE_thread_key_t key, void (*destructor)(void *), void *inst);
- /// Remove a <key, destructor> tuple from the table.
- int remove (ACE_thread_key_t key);
+ /// Mark a key as being used by this thread.
+ void thread_use_key (ACE_thread_key_t key);
- /// Detaches a tss_instance from its key.
- int detach (ACE_thread_key_t key, void * inst);
+ /// This thread is no longer using this key
+ /// Deletes the TSS object associated with this thread/key.
+ /// Clears reservation if inst != 0.
+ /// Release key if use count == 0 and reservation is cleared.
+ /// @param key the key to be released
+ /// @param inst a opaque value. If it is non-zero, it must match the inst value
+ /// given to insert and the key will no longer be reserved.
+ int thread_free_key (ACE_thread_key_t key, void * inst);
- /// Mark a key as being used by this thread.
- void key_used (ACE_thread_key_t key);
+ /// Cleanup the thread-specific objects. Does _NOT_ exit the thread.
+ /// For each used key perform the same actions as thread_free_key.
+ void thread_exit (void);
/// Indication of whether the ACE_TSS_CLEANUP_LOCK is usable, and
/// therefore whether we are in static constructor/destructor phase
@@ -694,11 +700,24 @@ public:
return instance_ != 0;
}
-protected:
+private:
void dump (void);
- /// Implementation remove key if it's unused
- int remove_key (ACE_thread_key_t key);
+ /// Perform the actual free actions for thread_free_key and thread_exit.
+ int free_key (ACE_thread_key_t key);
+
+ /// remove key if it's unused (thread_count == 0 and inst == 0)
+ /// @param info reference to the info for this key
+ void remove_key (ACE_TSS_Info &info);
+
+ /// Release a key used by this thread
+ /// @param info reference to the info for this key
+ /// @param destructor out arg to receive destructor function ptr
+ /// @param tss_obj out arg to receive pointer to deletable object
+ void thread_release (
+ ACE_TSS_Info &info,
+ ACE_TSS_Info::Destructor & destructor,
+ void *& tss_obj);
/// Find the TSS keys (if any) for this thread.
/// @param thread_keys reference to pointer to be filled in by this function.
@@ -743,49 +762,83 @@ ACE_TSS_Cleanup::~ACE_TSS_Cleanup (void)
}
void
-ACE_TSS_Cleanup::exit (void * /* status */)
+ACE_TSS_Cleanup::thread_exit (void)
{
- ACE_OS_TRACE ("ACE_TSS_Cleanup::exit");
+ ACE_OS_TRACE ("ACE_TSS_Cleanup::thread_exit");
+ // variables to hold the destructors
+ // and pointers to the object to be destructed
+ // the actual destruction is deferred until the guard is released
+ ACE_TSS_Info::Destructor destructor[ACE_DEFAULT_THREAD_KEYS];
+ void * tss_obj[ACE_DEFAULT_THREAD_KEYS];
+ // count of items to be destroyed
+ unsigned int d_count = 0;
- // if not initialized or already cleaned up
- ACE_TSS_Keys *this_thread_keys = 0;
- if (! find_tss_keys (this_thread_keys) )
- {
- return;
- }
+ // scope the guard
+ {
+ ACE_TSS_CLEANUP_GUARD
+
+ // if not initialized or already cleaned up
+ ACE_TSS_Keys *this_thread_keys = 0;
+ if (! find_tss_keys (this_thread_keys) )
+ {
+ return;
+ }
- // note: tss_keys is thread specific
- // and the key_ value of a table_ entry won't change while
- // thread_count_ shows this thread using the entry, so no lock is
- // necessary here
- // Minor hack: Iterating in reverse order means the LOG buffer which is
- // accidentally allocated first will be accidentally deallocated (almost)
- // last -- in case someone logs something from the other destructors.
- unsigned int key = ACE_DEFAULT_THREAD_KEYS;
- while( key > 0)
+ // Minor hack: Iterating in reverse order means the LOG buffer which is
+ // accidentally allocated first will be accidentally deallocated (almost)
+ // last -- in case someone logs something from the other destructors.
+ // applications should not count on this behavior because platforms which
+ // do not use ACE_TSS_Cleanup may delete objects in other orders.
+ unsigned int key_index = ACE_DEFAULT_THREAD_KEYS;
+ while( key_index > 0)
+ {
+ --key_index;
+ ACE_TSS_Info & info = this->table_[key_index];
+ // if this key is in use by this thread
+ if (info.key_in_use () && this_thread_keys->is_set(info.key_))
+ {
+ // defer deleting the in-use key until all others have been deleted
+ if(info.key_ != this->in_use_)
+ {
+ destructor[d_count] = 0;
+ tss_obj[d_count] = 0;
+ this->thread_release (info, destructor[d_count], tss_obj[d_count]);
+ if (destructor[d_count] != 0 && tss_obj[d_count] != 0)
+ {
+ ++d_count;
+ }
+ this->remove_key (info);
+ }
+ }
+ }
+
+ // remove the in_use bit vector last
+ ACE_KEY_INDEX (use_index, this->in_use_);
+ ACE_TSS_Info & info = this->table_[use_index];
+ destructor[d_count] = 0;
+ tss_obj[d_count] = 0;
+ this->thread_release (info, destructor[d_count], tss_obj[d_count]);
+ if (destructor[d_count] != 0 && tss_obj[d_count] != 0)
+ {
+ ++d_count;
+ }
+ this->remove_key (info);
+ } // end of guard scope
+ // WARNING:
+ // Once the guard is released this ACE_TSS_Cleanup may be deleted -- especially
+ // because we are about to delete a Thread_Exit object.
+ // Do not attempt to use any data members for the rest of this method.
+
+ for (unsigned int d_index = 0; d_index < d_count; ++d_index)
{
- --key;
- ACE_TSS_Info & info = this->table_[key];
- // if this key is in use by this thread
- if (this_thread_keys->is_set(info.key_))
- {
- // defer deleting the in-use key until all others have been deleted
- if(info.key_ != this->in_use_)
- {
- detach (info.key_, 0);
- // Warning: we may have just detached the log buffer. This thread
- // can no longer log anything.
- }
- }
+ (*destructor[d_index])(tss_obj[d_index]);
}
- // delete the in_use_ bit buffer last (and very carefully!)
- detach (this->in_use_, 0);
}
extern "C" void
ACE_TSS_Cleanup_keys_destroyer (void *tss_keys)
{
- delete ACE_reinterpret_cast (ACE_TSS_Keys *, tss_keys);
+ delete reinterpret_cast <ACE_TSS_Keys *> (tss_keys);
}
ACE_TSS_Cleanup::ACE_TSS_Cleanup (void)
@@ -825,9 +878,13 @@ ACE_TSS_Cleanup::insert (ACE_thread_key_t key,
ACE_TSS_CLEANUP_GUARD
ACE_KEY_INDEX (key_index, key);
+ ACE_ASSERT (key_index < ACE_DEFAULT_THREAD_KEYS);
if (key_index < ACE_DEFAULT_THREAD_KEYS)
{
+ ACE_ASSERT (table_[key_index].thread_count_ == -1);
table_[key_index] = ACE_TSS_Info (key, destructor, inst);
+ table_[key_index].thread_count_ = 0; // inserting it does not use it
+ // but it does "allocate" it
return 0;
}
else
@@ -837,50 +894,43 @@ ACE_TSS_Cleanup::insert (ACE_thread_key_t key,
}
int
-ACE_TSS_Cleanup::remove (ACE_thread_key_t key)
+ACE_TSS_Cleanup::free_key (ACE_thread_key_t key)
{
- ACE_OS_TRACE ("ACE_TSS_Cleanup::remove");
+ ACE_OS_TRACE ("ACE_TSS_Cleanup::free_key");
ACE_TSS_CLEANUP_GUARD
- return remove_key (key);
-}
+ ACE_KEY_INDEX (key_index, key);
+ if (key_index < ACE_DEFAULT_THREAD_KEYS)
+ {
+ remove_key (this->table_ [key_index]);
+ return 0;
+ }
+ return -1;}
-int
-ACE_TSS_Cleanup::remove_key (ACE_thread_key_t key)
+void
+ACE_TSS_Cleanup::remove_key (ACE_TSS_Info &info)
{
// assume CLEANUP_GUARD is held by caller
ACE_OS_TRACE ("ACE_TSS_Cleanup::remove_key");
- ACE_KEY_INDEX (key_index, key);
- if (key_index < ACE_DEFAULT_THREAD_KEYS)
+ // only remove it if all threads are done with it
+ // and there is no ACE_TSS holding on to it.
+ if (info.thread_count_ == 0 && info.tss_inst_ == 0)
{
- // find the TSS_Info table entry.
- // only remove it if all threads are done with it
- // and there is no ACE_TSS holding on to it.
- ACE_TSS_Info &info = this->table_ [key_index];
- if (info.thread_count_ == 0 && info.tss_inst_ == 0)
+#if !defined (ACE_HAS_TSS_EMULATION)
+ ACE_OS_thread_key_t temp_key = info.key_;
+ ACE_OS::thr_keyfree_native (temp_key);
+#endif /* !ACE_HAS_TSS_EMULATION */
+ if (info.key_ == this->in_use_)
{
-# if defined (ACE_WIN32)
- ACE_thread_key_t temp_key = info.key_;
- ::TlsFree (temp_key);
-# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
- ACE_thread_key_t temp_key = info.key_;
- ::tsd_delete (temp_key);
-# endif /* ACE_WIN32 */
- if (info.key_ == this->in_use_)
- {
- this->in_use_ = ACE_OS::NULL_key;
- }
- info.key_in_use (0);
- info.destructor_ = 0;
+ this->in_use_ = ACE_OS::NULL_key;
}
- return 0;
+ info.key_in_use (0);
+ info.destructor_ = 0;
}
- else
- return -1;
}
int
-ACE_TSS_Cleanup::detach (ACE_thread_key_t key, void *inst)
+ACE_TSS_Cleanup::thread_free_key (ACE_thread_key_t key, void *inst)
{
// variables to hold the destructor and the object to be destructed
// the actual call is deferred until the guard is released
@@ -909,31 +959,11 @@ ACE_TSS_Cleanup::detach (ACE_thread_key_t key, void *inst)
ACE_ASSERT (info.tss_inst_ == inst);
info.tss_inst_ = 0;
}
- // Find the TSS keys (if any) for this thread
- // do not create them if they don't exist
- ACE_TSS_Keys * thread_keys = 0;
- if (find_tss_keys (thread_keys))
- {
- // if this key is in use by this thread
- if (thread_keys->test_and_clear(info.key_) == 0)
- {
- // save destructor & pointer to tss object
- // until after the guard is released
- destructor = info.destructor_;
- ACE_OS::thr_getspecific (info.key_, &tss_obj);
- ACE_ASSERT (info.thread_count_ > 0);
- --info.thread_count_;
-#ifdef ACE_DEBUGGING_TSS_CLEANUP
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%P|%t) ACE_TSS_Cleanup::detach[%d] decrement %d\n"),
- key,info.thread_count_));
-#endif //ACE_DEBUGGING_TSS_CLEANUP
- }
- }
+ this->thread_release (info, destructor, tss_obj);
// try to remove this key
- this->remove_key (info.key_);
-
+ this->remove_key (info);
+
} // end of scope for the Guard
// if there's a destructor and an object to be destroyed
if (destructor != 0 && tss_obj != 0)
@@ -944,7 +974,32 @@ ACE_TSS_Cleanup::detach (ACE_thread_key_t key, void *inst)
}
void
-ACE_TSS_Cleanup::key_used (ACE_thread_key_t key)
+ACE_TSS_Cleanup::thread_release (
+ ACE_TSS_Info &info,
+ ACE_TSS_Info::Destructor & destructor,
+ void *& tss_obj)
+{
+ // assume guard is held by caller
+ // Find the TSS keys (if any) for this thread
+ // do not create them if they don't exist
+ ACE_TSS_Keys * thread_keys = 0;
+ if (find_tss_keys (thread_keys))
+ {
+ // if this key is in use by this thread
+ if (thread_keys->test_and_clear(info.key_) == 0)
+ {
+ // save destructor & pointer to tss object
+ // until after the guard is released
+ destructor = info.destructor_;
+ ACE_OS::thr_getspecific (info.key_, &tss_obj);
+ ACE_ASSERT (info.thread_count_ > 0);
+ --info.thread_count_;
+ }
+ }
+}
+
+void
+ACE_TSS_Cleanup::thread_use_key (ACE_thread_key_t key)
{
// If the key's ACE_TSS_Info in-use bit for this thread is not set,
// set it and increment the key's thread_count_.
@@ -955,10 +1010,9 @@ ACE_TSS_Cleanup::key_used (ACE_thread_key_t key)
// Retrieve the key's ACE_TSS_Info and increment its thread_count_.
ACE_KEY_INDEX (key_index, key);
ACE_TSS_Info &key_info = this->table_ [key_index];
- if (!key_info.key_in_use ())
- key_info.key_in_use (1);
- else
- ++key_info.thread_count_;
+
+ ACE_ASSERT (key_info.key_in_use ());
+ ++key_info.thread_count_;
}
}
@@ -1011,7 +1065,7 @@ ACE_TSS_Cleanup::tss_keys ()
ACE_TSS_Keys *ts_keys = 0;
if (ACE_OS::thr_getspecific (in_use_,
- ACE_reinterpret_cast (void **, &ts_keys)) == -1)
+ reinterpret_cast <void **> (&ts_keys)) == -1)
{
ACE_ASSERT (false);
return 0; // This should not happen!
@@ -1025,8 +1079,7 @@ ACE_TSS_Cleanup::tss_keys ()
// Store the dynamically allocated pointer in thread-specific
// storage.
if (ACE_OS::thr_setspecific (in_use_,
- ACE_reinterpret_cast (void *,
- ts_keys)) == -1)
+ reinterpret_cast <void *> (ts_keys)) == -1)
{
ACE_ASSERT (false);
delete ts_keys;
@@ -1052,7 +1105,7 @@ ACE_TSS_Cleanup::tss_keys ()
ACE_thread_t ACE_OS::NULL_thread;
ACE_hthread_t ACE_OS::NULL_hthread;
#if defined (ACE_HAS_TSS_EMULATION) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
- ACE_thread_key_t ACE_OS::NULL_key = ACE_static_cast (ACE_thread_key_t, -1);
+ ACE_thread_key_t ACE_OS::NULL_key = static_cast <ACE_thread_key_t> (-1);
#else /* ! ACE_HAS_TSS_EMULATION */
ACE_thread_key_t ACE_OS::NULL_key;
#endif /* ! ACE_HAS_TSS_EMULATION */
@@ -1071,7 +1124,7 @@ ACE_OS::cleanup_tss (const u_int main_thread)
#if defined (ACE_HAS_TSS_EMULATION) || defined (ACE_WIN32) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
// Call TSS destructors for current thread.
if (ACE_TSS_Cleanup::lockable ())
- ACE_TSS_Cleanup::instance ()->exit (0);
+ ACE_TSS_Cleanup::instance ()->thread_exit ();
#endif /* ACE_HAS_TSS_EMULATION || ACE_WIN32 || ACE_PSOS_HAS_TSS */
if (main_thread)
@@ -1917,7 +1970,8 @@ ACE_OS::sched_params (const ACE_Sched_Params &sched_params,
int, -1);
#elif defined (ACE_HAS_STHREADS)
return ACE_OS::set_scheduling_params (sched_params, id);
-#elif defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_SETSCHED)
+#elif defined (ACE_HAS_PTHREADS) && \
+ (!defined (ACE_LACKS_SETSCHED) || defined (ACE_TANDEM_T1248_PTHREADS))
ACE_UNUSED_ARG (id);
if (sched_params.quantum () != ACE_Time_Value::zero)
{
@@ -1936,6 +1990,9 @@ ACE_OS::sched_params (const ACE_Sched_Params &sched_params,
if (sched_params.scope () == ACE_SCOPE_PROCESS)
{
+# if defined(ACE_TANDEM_T1248_PTHREADS)
+ ACE_NOTSUP_RETURN (-1);
+# else /* ! ACE_TANDEM_T1248_PTHREADS */
int result = ::sched_setscheduler (0, // this process
sched_params.policy (),
&param) == -1 ? -1 : 0;
@@ -1948,6 +2005,7 @@ ACE_OS::sched_params (const ACE_Sched_Params &sched_params,
# else /* ! DIGITAL_UNIX */
return result;
# endif /* ! DIGITAL_UNIX */
+# endif /* ! ACE_TANDEM_T1248_PTHREADS */
}
else if (sched_params.scope () == ACE_SCOPE_THREAD)
{
@@ -2199,7 +2257,6 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
ACE_Base_Thread_Adapter *thread_args;
if (thread_adapter == 0)
-
#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
ACE_NEW_RETURN (thread_args,
ACE_OS_Thread_Adapter (func, args,
@@ -2217,6 +2274,13 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
else
thread_args = thread_adapter;
+ auto_ptr <ACE_Base_Thread_Adapter> auto_thread_args;
+
+ if (thread_adapter == 0)
+ ACE_AUTO_PTR_RESET (auto_thread_args,
+ thread_args,
+ ACE_Base_Thread_Adapter);
+
#if defined (ACE_HAS_THREADS)
// *** Set Stack Size
@@ -2270,7 +2334,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
size_t size = stacksize;
# if defined (PTHREAD_STACK_MIN)
- if (size < ACE_static_cast (size_t, PTHREAD_STACK_MIN))
+ if (size < static_cast <size_t> (PTHREAD_STACK_MIN))
size = PTHREAD_STACK_MIN;
# endif /* PTHREAD_STACK_MIN */
@@ -2378,6 +2442,9 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
# if defined (ACE_HAS_ONLY_SCHED_OTHER)
// SunOS, thru version 5.6, only supports SCHED_OTHER.
spolicy = SCHED_OTHER;
+# elif defined (ACE_HAS_ONLY_SCHED_FIFO)
+ // NonStop OSS standard pthread supports only SCHED_FIFO.
+ spolicy = SCHED_FIFO;
# else
// Make sure to enable explicit scheduling, in case we didn't
// enable it above (for non-default priority).
@@ -2729,6 +2796,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
# endif /* ACE_NEEDS_LWP_PRIO_SET */
# endif /* sun && ACE_HAS_ONLY_SCHED_OTHER */
+ auto_thread_args.release ();
return result;
# elif defined (ACE_HAS_STHREADS)
int result;
@@ -2771,6 +2839,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
}
}
}
+ auto_thread_args.release ();
return result;
# elif defined (ACE_HAS_WTHREADS)
ACE_UNUSED_ARG (stack);
@@ -2800,7 +2869,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
cwin_thread->ResumeThread ();
// cwin_thread will be deleted in AfxThreadExit()
// Warning: If AfxThreadExit() is called from within the
- // thread, ACE_TSS_Cleanup->exit() never gets called !
+ // thread, ACE_TSS_Cleanup->thread_exit() never gets called !
}
else
# endif /* ACE_HAS_MFC */
@@ -2813,8 +2882,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
ACE_SET_BITS (flags, THR_SUSPENDED);
*thr_handle = (void *) ACE_BEGINTHREADEX (0,
- ACE_static_cast
- (u_int, stacksize),
+ static_cast <u_int> (stacksize),
thread_args->entry_point (),
thread_args,
flags,
@@ -2846,7 +2914,10 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
::CloseHandle (tmp_handle);
if (*thr_handle != 0)
- return 0;
+ {
+ auto_thread_args.release ();
+ return 0;
+ }
else
ACE_FAIL_RETURN (-1);
/* NOTREACHED */
@@ -2913,6 +2984,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
// store the task id in the handle and return success
*thr_handle = tid;
+ auto_thread_args.release ();
return 0;
# elif defined (VXWORKS)
@@ -3010,6 +3082,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
if (thr_handle)
*thr_handle = tid;
+ auto_thread_args.release ();
return 0;
}
@@ -3039,7 +3112,7 @@ ACE_OS::thr_exit (ACE_THR_FUNC_RETURN status)
# elif defined (ACE_HAS_WTHREADS)
// Can't call it here because on NT, the thread is exited
// directly by ACE_Thread_Adapter::invoke ().
- // ACE_TSS_Cleanup::instance ()->exit (status);
+ // ACE_TSS_Cleanup::instance ()->thread_exit (status);
# if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
int using_afx = -1;
@@ -3102,7 +3175,7 @@ ACE_OS::thr_exit (ACE_THR_FUNC_RETURN status)
#endif /* ACE_HAS_THREADS */
}
-#if defined (VXWORKS)
+#if defined (VXWORKS) && !defined (ACE_HAS_PTHREADS)
// Leave this in the global scope to allow
// users to adjust the delay value.
int ACE_THR_JOIN_DELAY = 5;
@@ -3171,9 +3244,9 @@ ACE_OS::thr_join (ACE_thread_t waiter_id,
int
ACE_OS::thr_key_detach (ACE_thread_key_t key, void * inst)
{
-#if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
+#if defined (ACE_HAS_WTHREADS) || defined (ACE_HAS_TSS_EMULATION) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
if (ACE_TSS_Cleanup::lockable ())
- return ACE_TSS_Cleanup::instance()->detach (key, inst);
+ return ACE_TSS_Cleanup::instance()->thread_free_key (key, inst);
else
// We're in static constructor/destructor phase. Don't
// try to use the ACE_TSS_Cleanup instance because its lock
@@ -3184,14 +3257,14 @@ ACE_OS::thr_key_detach (ACE_thread_key_t key, void * inst)
ACE_UNUSED_ARG (key);
ACE_UNUSED_ARG (inst);
ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION */
+#endif /* ACE_HAS_WTHREADS || ACE_HAS_TSS_EMULATION */
}
int
ACE_OS::thr_key_used (ACE_thread_key_t key)
{
#if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
- ACE_TSS_Cleanup::instance ()->key_used (key);
+ ACE_TSS_Cleanup::instance ()->thread_use_key (key);
return 0;
#else
ACE_UNUSED_ARG (key);
@@ -3199,199 +3272,167 @@ ACE_OS::thr_key_used (ACE_thread_key_t key)
#endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION || ACE_PSOS_HAS_TSS */
}
-#if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
int
-ACE_OS::thr_keycreate (ACE_OS_thread_key_t *key,
+ACE_OS::thr_keycreate_native (ACE_OS_thread_key_t *key,
# if defined (ACE_HAS_THR_C_DEST)
- ACE_THR_C_DEST dest,
+ ACE_THR_C_DEST dest
# else
- ACE_THR_DEST dest,
+ ACE_THR_DEST dest
# endif /* ACE_HAS_THR_C_DEST */
- void *inst)
+ )
{
- // ACE_OS_TRACE ("ACE_OS::thr_keycreate");
+ // can't trace here. Trace uses TSS
+ // ACE_OS_TRACE ("ACE_OS::thr_keycreate_native");
# if defined (ACE_HAS_THREADS)
# if defined (ACE_HAS_PTHREADS)
- ACE_UNUSED_ARG (inst);
-
# if defined (ACE_HAS_PTHREADS_DRAFT4)
# if defined (ACE_HAS_STDARG_THR_DEST)
- ACE_OSCALL_RETURN (::pthread_keycreate (key, (void (*)(...)) dest), int, -1);
+ ACE_OSCALL_RETURN (::pthread_keycreate (key, (void (*)(...)) dest), int, -1);
# else /* ! ACE_HAS_STDARG_THR_DEST */
- ACE_OSCALL_RETURN (::pthread_keycreate (key, dest), int, -1);
+ ACE_OSCALL_RETURN (::pthread_keycreate (key, dest), int, -1);
# endif /* ! ACE_HAS_STDARG_THR_DEST */
# elif defined (ACE_HAS_PTHREADS_DRAFT6)
- ACE_OSCALL_RETURN (::pthread_key_create (key, dest), int, -1);
+ ACE_OSCALL_RETURN (::pthread_key_create (key, dest), int, -1);
# else
- int result;
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_key_create (key, dest),
- result),
- int, -1);
+ int result;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_key_create (key, dest),
+ result),
+ int, -1);
# endif /* ACE_HAS_PTHREADS_DRAFT4 */
# elif defined (ACE_HAS_STHREADS)
- ACE_UNUSED_ARG (inst);
- int result;
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_keycreate (key, dest),
- result),
- int, -1);
+ int result;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_keycreate (key, dest),
+ result),
+ int, -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
+ ACE_UNUSED_ARG (dest);
+
+ static u_long unique_name = 0;
+ void *tsdanchor;
+
+ ++unique_name;
+ if (::tsd_create (reinterpret_cast <char *> (&unique_name),
+ 0,
+ TSD_NOALLOC,
+ (void ****) &tsdanchor,
+ key) != 0)
+ {
+ return -1;
+ }
+ return 0;
# elif defined (ACE_HAS_WTHREADS)
- *key = ::TlsAlloc ();
+ ACE_UNUSED_ARG (dest);
+ *key = ::TlsAlloc ();
- if (*key != ACE_SYSCALL_FAILED)
- {
- // Extract out the thread-specific table instance and stash away
- // the key and destructor so that we can free it up later on...
- return ACE_TSS_Cleanup::instance ()->insert (*key, dest, inst);
- }
- else
- ACE_FAIL_RETURN (-1);
- /* NOTREACHED */
+ if (*key == ACE_SYSCALL_FAILED)
+ ACE_FAIL_RETURN (-1);
+ return 0;
# endif /* ACE_HAS_STHREADS */
# else
ACE_UNUSED_ARG (key);
ACE_UNUSED_ARG (dest);
- ACE_UNUSED_ARG (inst);
ACE_NOTSUP_RETURN (-1);
# endif /* ACE_HAS_THREADS */
}
-#endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */
+#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
int
ACE_OS::thr_keycreate (ACE_thread_key_t *key,
-#if defined (ACE_HAS_THR_C_DEST)
+# if defined (ACE_HAS_THR_C_DEST)
ACE_THR_C_DEST dest,
-#else
+# else
ACE_THR_DEST dest,
-#endif /* ACE_HAS_THR_C_DEST */
+# endif /* ACE_HAS_THR_C_DEST */
void *inst)
{
// ACE_OS_TRACE ("ACE_OS::thr_keycreate");
#if defined (ACE_HAS_THREADS)
-# if defined (ACE_HAS_TSS_EMULATION)
+# if defined (ACE_HAS_TSS_EMULATION)
if (ACE_TSS_Emulation::next_key (*key) == 0)
{
- ACE_TSS_Emulation::tss_destructor (
- *key,
- (ACE_TSS_Emulation::ACE_TSS_DESTRUCTOR) dest);
+ ACE_TSS_Emulation::tss_destructor (*key, dest);
// Extract out the thread-specific table instance and stash away
// the key and destructor so that we can free it up later on...
return ACE_TSS_Cleanup::instance ()->insert (*key, dest, inst);
}
else
- {
- errno = EAGAIN;
- return -1;
- }
-# elif defined (ACE_HAS_PTHREADS)
- ACE_UNUSED_ARG (inst);
-
-# if defined (ACE_HAS_PTHREADS_DRAFT4)
-# if defined (ACE_HAS_STDARG_THR_DEST)
- ACE_OSCALL_RETURN (::pthread_keycreate (key, (void (*)(...)) dest), int, -1);
-# else /* ! ACE_HAS_STDARG_THR_DEST */
- ACE_OSCALL_RETURN (::pthread_keycreate (key, dest), int, -1);
-# endif /* ! ACE_HAS_STDARG_THR_DEST */
-# elif defined (ACE_HAS_PTHREADS_DRAFT6)
- ACE_OSCALL_RETURN (::pthread_key_create (key, dest), int, -1);
-# else
- int result;
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_key_create (key, dest),
- result),
- int, -1);
-# endif /* ACE_HAS_PTHREADS_DRAFT4 */
-
-# elif defined (ACE_HAS_STHREADS)
- ACE_UNUSED_ARG (inst);
- int result;
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_keycreate (key, dest),
- result),
- int, -1);
-# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
-
- static u_long unique_name = 0;
- void *tsdanchor;
-
- ++unique_name;
- if (::tsd_create (ACE_reinterpret_cast (char *, &unique_name),
- 0,
- TSD_NOALLOC,
- (void ****) &tsdanchor,
- key) != 0)
- {
- return -1;
- }
-
- return ACE_TSS_Cleanup::instance ()->insert (*key, dest, inst);
-# elif defined (ACE_HAS_WTHREADS)
- *key = ::TlsAlloc ();
-
- if (*key != ACE_SYSCALL_FAILED)
+ return -1;
+# elif (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)) || defined (ACE_HAS_WTHREADS)
+ if (ACE_OS::thr_keycreate_native (key, dest) == 0)
{
// Extract out the thread-specific table instance and stash away
// the key and destructor so that we can free it up later on...
return ACE_TSS_Cleanup::instance ()->insert (*key, dest, inst);
- }
+ }
else
- ACE_FAIL_RETURN (-1);
+ return -1;
/* NOTREACHED */
-# else
- ACE_UNUSED_ARG (key);
- ACE_UNUSED_ARG (dest);
+# else /* ACE_HAS_TSS_EMULATION */
ACE_UNUSED_ARG (inst);
- ACE_NOTSUP_RETURN (-1);
-# endif /* ACE_HAS_TSS_EMULATION */
-#else
+ return ACE_OS::thr_keycreate_native (key, dest);
+# endif /* ACE_HAS_TSS_EMULATION */
+# else /* ACE_HAS_THREADS */
ACE_UNUSED_ARG (key);
ACE_UNUSED_ARG (dest);
ACE_UNUSED_ARG (inst);
ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_THREADS */
+# endif /* ACE_HAS_THREADS */
}
+#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
int
-ACE_OS::thr_keyfree (ACE_thread_key_t key)
+ACE_OS::thr_keyfree_native (ACE_OS_thread_key_t key)
{
- ACE_OS_TRACE ("ACE_OS::thr_keyfree");
-#if defined (ACE_HAS_THREADS)
-# if defined (ACE_HAS_TSS_EMULATION)
- // Release the key in the TSS_Emulation administration
- ACE_TSS_Emulation::release_key (key);
- if (ACE_TSS_Cleanup::lockable ())
- return ACE_TSS_Cleanup::instance ()->remove (key);
- else
- return -1;
-# elif defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_OS_TRACE ("ACE_OS::thr_keyfree_native");
+# if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
ACE_UNUSED_ARG (key);
ACE_NOTSUP_RETURN (-1);
-# elif defined (ACE_HAS_PTHREADS)
+# elif defined (ACE_HAS_PTHREADS)
return ::pthread_key_delete (key);
-# elif defined (ACE_HAS_THR_KEYDELETE)
+# elif defined (ACE_HAS_THR_KEYDELETE)
return ::thr_keydelete (key);
-# elif defined (ACE_HAS_STHREADS)
+# elif defined (ACE_HAS_STHREADS)
ACE_UNUSED_ARG (key);
ACE_NOTSUP_RETURN (-1);
-# elif defined (ACE_HAS_WTHREADS)
- // Extract out the thread-specific table instance and free up
- // the key and destructor.
- if (ACE_TSS_Cleanup::lockable ())
- return ACE_TSS_Cleanup::instance ()->remove (key);
+# elif defined (ACE_HAS_WTHREADS)
ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::TlsFree (key), ace_result_), int, -1);
-# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
- // Extract out the thread-specific table instance and free up
- // the key and destructor.
- if (ACE_TSS_Cleanup::lockable ())
- return ACE_TSS_Cleanup::instance ()->remove (key);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
return (::tsd_delete (key) == 0) ? 0 : -1;
-# else
+# else
ACE_UNUSED_ARG (key);
ACE_NOTSUP_RETURN (-1);
-# endif /* ACE_HAS_TSS_EMULATION */
-#else
+# endif /* ACE_HAS_PTHREADS */
+# else
ACE_UNUSED_ARG (key);
ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_THREADS */
+# endif /* ACE_HAS_THREADS */
+}
+#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
+
+int
+ACE_OS::thr_keyfree (ACE_thread_key_t key)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_keyfree");
+# if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_TSS_EMULATION)
+ // Release the key in the TSS_Emulation administration
+ ACE_TSS_Emulation::release_key (key);
+ return ACE_TSS_Cleanup::instance ()->thread_free_key (key, 0);
+# elif (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)) || defined (ACE_HAS_WTHREADS)
+ // Extract out the thread-specific table instance and free up
+ // the key and destructor.
+ return ACE_TSS_Cleanup::instance ()->thread_free_key (key, 0);
+# else /* ACE_HAS_TSS_EMULATION */
+ return ACE_OS::thr_keyfree_native (key);
+# endif /* ACE_HAS_TSS_EMULATION */
+# else /* ACE_HAS_THREADS */
+ ACE_UNUSED_ARG (key);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
}
int
@@ -3433,49 +3474,64 @@ ACE_OS::thr_setprio (const ACE_Sched_Priority prio)
return status;
}
-#if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
int
-ACE_OS::thr_setspecific (ACE_OS_thread_key_t key, void *data)
+ACE_OS::thr_setspecific_native (ACE_OS_thread_key_t key, void *data)
{
- // ACE_OS_TRACE ("ACE_OS::thr_setspecific");
-# if defined (ACE_HAS_THREADS)
-# if defined (ACE_HAS_PTHREADS)
-# if defined (ACE_HAS_FSU_PTHREADS)
- // Call pthread_init() here to initialize threads package. FSU
- // threads need an initialization before the first thread
- // constructor. This seems to be the one; however, a segmentation
- // fault may indicate that another pthread_init() is necessary,
- // perhaps in Synch.cpp or Synch_T.cpp. FSU threads will not reinit
- // if called more than once, so another call to pthread_init will
- // not adversely affect existing threads.
- pthread_init ();
-# endif /* ACE_HAS_FSU_PTHREADS */
- int result;
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setspecific (key, data), result), int, -1);
-# elif defined (ACE_HAS_STHREADS)
- int result;
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setspecific (key, data), result), int, -1);
-# elif defined (ACE_HAS_WTHREADS)
- ::TlsSetValue (key, data);
- return 0;
-# endif /* ACE_HAS_STHREADS */
-# else
- ACE_UNUSED_ARG (key);
- ACE_UNUSED_ARG (data);
- ACE_NOTSUP_RETURN (-1);
-# endif /* ACE_HAS_THREADS */
+ // ACE_OS_TRACE ("ACE_OS::thr_setspecific_native");
+# if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_FSU_PTHREADS)
+ // Call pthread_init() here to initialize threads package. FSU
+ // threads need an initialization before the first thread constructor.
+ // This seems to be the one; however, a segmentation fault may
+ // indicate that another pthread_init() is necessary, perhaps in
+ // Synch.cpp or Synch_T.cpp. FSU threads will not reinit if called
+ // more than once, so another call to pthread_init will not adversely
+ // affect existing threads.
+ pthread_init ();
+# endif /* ACE_HAS_FSU_PTHREADS */
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_OSCALL_RETURN (::pthread_setspecific (key, data), int, -1);
+# else
+ int result;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setspecific (key, data),
+ result),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */
+
+# elif defined (ACE_HAS_STHREADS)
+ int result;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setspecific (key, data), result), int, -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
+ ACE_hthread_t tid;
+ ACE_OS::thr_self (tid);
+ if (::tsd_setval (key, tid, data) != 0)
+ return -1;
+ return 0;
+# elif defined (ACE_HAS_WTHREADS)
+ ::TlsSetValue (key, data);
+ return 0;
+# else /* ACE_HAS_STHREADS */
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (data);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (data);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
}
-#endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */
+# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
int
ACE_OS::thr_setspecific (ACE_thread_key_t key, void *data)
{
// ACE_OS_TRACE ("ACE_OS::thr_setspecific");
#if defined (ACE_HAS_THREADS)
-# if defined (ACE_HAS_TSS_EMULATION)
- ACE_KEY_INDEX (key_index, key);
-
- if (key_index >= ACE_TSS_Emulation::total_keys ())
+# if defined (ACE_HAS_TSS_EMULATION)
+ if (ACE_TSS_Emulation::is_key (key) == 0)
{
errno = EINVAL;
data = 0;
@@ -3484,55 +3540,25 @@ ACE_OS::thr_setspecific (ACE_thread_key_t key, void *data)
else
{
ACE_TSS_Emulation::ts_object (key) = data;
- ACE_TSS_Cleanup::instance ()->key_used (key);
+ ACE_TSS_Cleanup::instance ()->thread_use_key (key);
return 0;
}
-# elif defined (ACE_HAS_PTHREADS)
-# if defined (ACE_HAS_FSU_PTHREADS)
- // Call pthread_init() here to initialize threads package. FSU
- // threads need an initialization before the first thread
- // constructor. This seems to be the one; however, a segmentation
- // fault may indicate that another pthread_init() is necessary,
- // perhaps in Synch.cpp or Synch_T.cpp. FSU threads will not
- // reinit if called more than once, so another call to
- // pthread_init will not adversely affect existing threads.
- pthread_init ();
-# endif /* ACE_HAS_FSU_PTHREADS */
-
-# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
- ACE_OSCALL_RETURN (::pthread_setspecific (key, data), int, -1);
-# else
- int result;
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setspecific (key, data),
- result),
- int, -1);
-# endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */
-
-# elif defined (ACE_HAS_STHREADS)
- int result;
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setspecific (key, data), result), int, -1);
-# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
- ACE_hthread_t tid;
- ACE_OS::thr_self (tid);
- if (::tsd_setval (key, tid, data) != 0)
- return -1;
- ACE_TSS_Cleanup::instance ()->key_used (key);
- return 0;
-# elif defined (ACE_HAS_WTHREADS)
- ::TlsSetValue (key, data);
- ACE_TSS_Cleanup::instance ()->key_used (key);
- return 0;
-# else
- ACE_UNUSED_ARG (key);
- ACE_UNUSED_ARG (data);
- ACE_NOTSUP_RETURN (-1);
-# endif /* ACE_HAS_STHREADS */
-#else
+# elif (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)) || defined (ACE_HAS_WTHREADS)
+ if (ACE_OS::thr_setspecific_native (key, data) == 0)
+ {
+ ACE_TSS_Cleanup::instance ()->thread_use_key (key);
+ return 0;
+ }
+ return -1;
+# else /* ACE_HAS_TSS_EMULATION */
+ return ACE_OS::thr_setspecific_native (key, data);
+# endif /* ACE_HAS_TSS_EMULATION */
+# else /* ACE_HAS_THREADS */
ACE_UNUSED_ARG (key);
ACE_UNUSED_ARG (data);
ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_THREADS */
+# endif /* ACE_HAS_THREADS */
}
void
@@ -3549,7 +3575,7 @@ ACE_OS::unique_name (const void *object,
ACE_OS::sprintf (temp_name,
ACE_LIB_TEXT ("%p%d"),
object,
- ACE_static_cast (int, ACE_OS::getpid ()));
+ static_cast <int> (ACE_OS::getpid ()));
ACE_OS::strsncpy (name,
temp_name,
length);