summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwilson_d <wilson_d@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2005-02-17 14:39:37 +0000
committerwilson_d <wilson_d@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2005-02-17 14:39:37 +0000
commit9b916b89430d493710150dd8f400df0d342695c4 (patch)
tree24052451491a3dd0b81ec55920f3de6b4da4c0e0
parentf1292c4210e466b5043035196170f605d752ffe4 (diff)
downloadATCD-9b916b89430d493710150dd8f400df0d342695c4.tar.gz
ChangeLogTag: Thu Feb 17 08:32:08 2005 Dale Wilson <wilson_d@ociweb.com>
-rw-r--r--ChangeLog47
-rw-r--r--ace/OS_NS_Thread.cpp235
2 files changed, 150 insertions, 132 deletions
diff --git a/ChangeLog b/ChangeLog
index 7bcfced6358..24af3580881 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,37 +1,44 @@
+Thu Feb 17 08:32:08 2005 Dale Wilson <wilson_d@ociweb.com>
+
+ * ace/OS_NS_Thread.cpp:
+ Fix compile errors when TSS Emulation is enabled.
+ de-templatize the Thread_Safe_Instance object to avoid fighting
+ template instantiation issues now.
+
Wed Feb 16 17:10:14 2005 Ossama Othman <ossama@dre.vanderbilt.edu>
- * ace/OS_NS_Thread.cpp (thr_key_detach, thr_keycreate):
+ * ace/OS_NS_Thread.cpp (thr_key_detach, thr_keycreate):
- Removed "ACE_UNUSED_ARG" macro calls for non-existent "inst"
- parameter.
+ Removed "ACE_UNUSED_ARG" macro calls for non-existent "inst"
+ parameter.
Wed Feb 16 17:04:50 2005 Ossama Othman <ossama@dre.vanderbilt.edu>
- * bin/MakeProjectCreator/config/rmcast.mpb:
- * protocols/ace/RMCast/RMCast.mpc:
+ * bin/MakeProjectCreator/config/rmcast.mpb:
+ * protocols/ace/RMCast/RMCast.mpc:
- The RMCast protocol implementation currently requires thread
- support. Updated these MPC files accordingly.
+ The RMCast protocol implementation currently requires thread
+ support. Updated these MPC files accordingly.
- * protocols/ace/RMCast/Protocol.h (NAK):
+ * protocols/ace/RMCast/Protocol.h (NAK):
- Since "NAK" is now a class instead of struct, public inheritance
- must be explicitly specified. Fixes compile-time errors related
- to inaccessible members in the "Profile" base class.
+ Since "NAK" is now a class instead of struct, public inheritance
+ must be explicitly specified. Fixes compile-time errors related
+ to inaccessible members in the "Profile" base class.
Wed Feb 16 18:31:28 2005 Steve Huston <shuston@riverace.com>
- * protocols/ace/RMCast/Acknowledge.cpp:
- * protocols/ace/RMCast/Link.cpp:
- * protocols/ace/RMCast/Socket.cpp:
- Fixed some constructs to make MSVC6 happy. Primarily, MSVC6 won't
- allow type& var (ref). Must be type& var = ref.
+ * protocols/ace/RMCast/Acknowledge.cpp:
+ * protocols/ace/RMCast/Link.cpp:
+ * protocols/ace/RMCast/Socket.cpp:
+ Fixed some constructs to make MSVC6 happy. Primarily, MSVC6 won't
+ allow type& var (ref). Must be type& var = ref.
- * protocols/ace/RMCast/Protocol.h: Changed struct NAK to class NAK to
- make MSVC6 happy.
+ * protocols/ace/RMCast/Protocol.h: Changed struct NAK to class NAK to
+ make MSVC6 happy.
- MSVC6 is still not completely happy, but someone with more insight as
- to the intentions here will need to take a look.
+ MSVC6 is still not completely happy, but someone with more insight as
+ to the intentions here will need to take a look.
Wed Feb 16 16:18:45 2005 Dale Wilson <wilson_d@ociweb.com>
diff --git a/ace/OS_NS_Thread.cpp b/ace/OS_NS_Thread.cpp
index 0f388ad1686..6681b60e2e9 100644
--- a/ace/OS_NS_Thread.cpp
+++ b/ace/OS_NS_Thread.cpp
@@ -656,14 +656,102 @@ ACE_TSS_Keys::is_set (const ACE_thread_key_t key) const
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.
+ */
+class ACE_TSS_Cleanup
+{
+public:
+ /// 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
+ int insert (ACE_thread_key_t key, void (*destructor)(void *));
+
+ /// Mark a key as being used by this thread.
+ void thread_use_key (ACE_thread_key_t key);
+
+ /// This thread is no longer using this key
+ /// call destructor if appropriate
+ int thread_detach_key (ACE_thread_key_t key);
+
+ /// This key is no longer used
+ /// Release key if use count == 0
+ /// fail if use_count != 0;
+ /// @param key the key to be released
+ int free_key (ACE_thread_key_t key);
+
+ /// Cleanup the thread-specific objects. Does _NOT_ exit the thread.
+ /// For each used key perform the same actions as free_key.
+ void thread_exit (void);
+
+private:
+ void dump (void);
+
+ /// 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);
+
+ /// remove key if it's unused (thread_count == 0)
+ /// @param info reference to the info for this key
+ int remove_key (ACE_TSS_Info &info);
+
+ /// Find the TSS keys (if any) for this thread.
+ /// @param thread_keys reference to pointer to be filled in by this function.
+ /// @return false if keys don't exist.
+ bool find_tss_keys (ACE_TSS_Keys *& thread_keys) const;
+
+ /// Accessor for this threads ACE_TSS_Keys instance.
+ /// Creates the keys if necessary.
+ ACE_TSS_Keys *tss_keys ();
+
+ /// Ensure singleton.
+ ACE_TSS_Cleanup (void);
+ ~ACE_TSS_Cleanup (void);
+
+ /// ACE_TSS_Cleanup access only via TSS_Cleanup_Instance
+ friend class TSS_Cleanup_Instance;
+
+private:
+ // Array of <ACE_TSS_Info> objects.
+ typedef ACE_TSS_Info ACE_TSS_TABLE[ACE_DEFAULT_THREAD_KEYS];
+ typedef ACE_TSS_Info *ACE_TSS_TABLE_ITERATOR;
+
+ /// Table of <ACE_TSS_Info>'s.
+ ACE_TSS_TABLE table_;
+
+ /// Key for the thread-specific ACE_TSS_Keys
+ /// Used by find_tss_keys() or tss_keys() to find the
+ /// bit array that records whether each TSS key is in
+ /// use by this thread.
+ ACE_thread_key_t in_use_;
+};
+
+
/*****************************************************************************/
/**
- * @template class Thread_Safe_Instance
- * @A wrapper template to manage an instance pointer to TARGET.
+ * @class TSS_Cleanup_Instance
+ * @A class to manage an instance pointer to ACE_TSS_Cleanup.
+ * Note: that the double checked locking pattern doesn't allow
+ * safe deletion.
+ * Callers who wish to access the singleton ACE_TSS_Cleanup must
+ * do so by instantiating a TSS_Cleanup_Instance, calling the valid
+ * method to be sure the ACE_TSS_Cleanup is available, then using
+ * the TSS_Cleanup_Instance as a pointer to the instance.
+ * Construction argument to the TSS_Cleanup_Instance determines how
+ * it is to be used:
+ * CREATE means allow this call to create an ACE_TSS_Cleanup if necessary.
+ * USE means use the existing ACE_TSS_Cleanup, but do not create a new one.
+ * DESTROY means provide exclusive access to the ACE_TSS_Cleanup, then
+ * delete it when the TSS_Cleanup_Instance goes out of scope.
*/
-template<class TARGET>
-class Thread_Safe_Instance
+class TSS_Cleanup_Instance
{
public:
enum Purpose
@@ -672,21 +760,24 @@ public:
USE,
DESTROY
};
- Thread_Safe_Instance (Purpose purpose = USE);
- ~Thread_Safe_Instance();
+ TSS_Cleanup_Instance (Purpose purpose = USE);
+ ~TSS_Cleanup_Instance();
bool valid();
- TARGET * operator *();
- TARGET * operator ->();
+ ACE_TSS_Cleanup * operator ->();
+
+private:
+
+ ACE_TSS_Cleanup * operator *();
private:
static unsigned int reference_count_;
- static TARGET * instance_;
+ static ACE_TSS_Cleanup * instance_;
static ACE_Thread_Mutex mutex_;
static ACE_Thread_Condition<ACE_Thread_Mutex> condition_;
private:
- TARGET * ptr_;
+ ACE_TSS_Cleanup * ptr_;
unsigned short flags_;
enum
{
@@ -695,8 +786,7 @@ private:
};
};
-template<class TARGET>
-Thread_Safe_Instance<TARGET>::Thread_Safe_Instance (Purpose purpose)
+TSS_Cleanup_Instance::TSS_Cleanup_Instance (Purpose purpose)
: ptr_(0)
, flags_(0)
{
@@ -706,7 +796,7 @@ Thread_Safe_Instance<TARGET>::Thread_Safe_Instance (Purpose purpose)
{
if (instance_ == 0)
{
- instance_ = new TARGET();
+ instance_ = new ACE_TSS_Cleanup();
}
ptr_ = instance_;
++reference_count_;
@@ -734,8 +824,7 @@ Thread_Safe_Instance<TARGET>::Thread_Safe_Instance (Purpose purpose)
}
}
}
-template<class TARGET>
-Thread_Safe_Instance<TARGET>::~Thread_Safe_Instance()
+TSS_Cleanup_Instance::~TSS_Cleanup_Instance()
{
ACE_Guard<ACE_Thread_Mutex> guard(mutex_);
if (ptr_ != 0)
@@ -758,113 +847,32 @@ Thread_Safe_Instance<TARGET>::~Thread_Safe_Instance()
}
}
-template<class TARGET>
bool
-Thread_Safe_Instance<TARGET>::valid()
+TSS_Cleanup_Instance::valid()
{
ACE_SET_BITS(flags_, FLAG_VALID_CHECKED);
return (this->instance_ != NULL);
}
-template<class TARGET>
-TARGET *
-Thread_Safe_Instance<TARGET>::operator *()
+ACE_TSS_Cleanup *
+TSS_Cleanup_Instance::operator *()
{
ACE_ASSERT(ACE_BIT_ENABLED(flags_, FLAG_VALID_CHECKED));
return instance_;
}
-template<class TARGET>
-TARGET *
-Thread_Safe_Instance<TARGET>::operator ->()
+ACE_TSS_Cleanup *
+TSS_Cleanup_Instance::operator ->()
{
ACE_ASSERT(ACE_BIT_ENABLED(flags_, FLAG_VALID_CHECKED));
return instance_;
}
-/**
- * @class ACE_TSS_Cleanup
- * @brief Singleton that helps to manage the lifetime of TSS objects and keys.
- */
-class ACE_TSS_Cleanup
-{
-public:
- /// 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
- int insert (ACE_thread_key_t key, void (*destructor)(void *));
-
- /// Mark a key as being used by this thread.
- void thread_use_key (ACE_thread_key_t key);
-
- /// This thread is no longer using this key
- /// call destructor if appropriate
- int thread_detach_key (ACE_thread_key_t key);
-
- /// This key is no longer used
- /// Release key if use count == 0
- /// fail if use_count != 0;
- /// @param key the key to be released
- int free_key (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);
-
-private:
- void dump (void);
-
- /// 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);
-
- /// remove key if it's unused (thread_count == 0 and inst == 0)
- /// @param info reference to the info for this key
- int remove_key (ACE_TSS_Info &info);
-
- /// Find the TSS keys (if any) for this thread.
- /// @param thread_keys reference to pointer to be filled in by this function.
- /// @return false if keys don't exist.
- bool find_tss_keys (ACE_TSS_Keys *& thread_keys) const;
-
- /// Accessor for this threads ACE_TSS_Keys instance.
- /// Creates the keys if necessary.
- ACE_TSS_Keys *tss_keys ();
-
- /// Ensure singleton.
- ACE_TSS_Cleanup (void);
- ~ACE_TSS_Cleanup (void);
-
- /// ACE_TSS_Cleanup access only via template Thread_Safe_Instance
- friend class Thread_Safe_Instance<ACE_TSS_Cleanup>;
-
-private:
- // Array of <ACE_TSS_Info> objects.
- typedef ACE_TSS_Info ACE_TSS_TABLE[ACE_DEFAULT_THREAD_KEYS];
- typedef ACE_TSS_Info *ACE_TSS_TABLE_ITERATOR;
-
- /// Table of <ACE_TSS_Info>'s.
- ACE_TSS_TABLE table_;
-
- /// Key for the thread-specific ACE_TSS_Keys
- /// Used by find_tss_keys() or tss_keys() to find the
- /// bit array that records whether each TSS key is in
- /// use by this thread.
- ACE_thread_key_t in_use_;
-};
-
-typedef Thread_Safe_Instance<ACE_TSS_Cleanup> TSS_Cleanup_Instance;
-
// = Static object initialization.
-ACE_TEMPLATE_SPECIALIZATION unsigned int TSS_Cleanup_Instance::reference_count_ = 0;
-ACE_TEMPLATE_SPECIALIZATION ACE_TSS_Cleanup * TSS_Cleanup_Instance::instance_ = 0;
-ACE_TEMPLATE_SPECIALIZATION ACE_Thread_Mutex TSS_Cleanup_Instance::mutex_ (0, 0);
-ACE_TEMPLATE_SPECIALIZATION ACE_Thread_Condition<ACE_Thread_Mutex> TSS_Cleanup_Instance::condition_
+unsigned int TSS_Cleanup_Instance::reference_count_ = 0;
+ACE_TSS_Cleanup * TSS_Cleanup_Instance::instance_ = 0;
+ACE_Thread_Mutex TSS_Cleanup_Instance::mutex_ (0, 0);
+ACE_Thread_Condition<ACE_Thread_Mutex> TSS_Cleanup_Instance::condition_
(TSS_Cleanup_Instance::mutex_);
ACE_TSS_Cleanup::~ACE_TSS_Cleanup (void)
@@ -3454,7 +3462,7 @@ ACE_OS::thr_keycreate (ACE_thread_key_t *key,
TSS_Cleanup_Instance cleanup (TSS_Cleanup_Instance::CREATE);
if (cleanup.valid ())
{
- return cleanup->insert (*key, dest, inst);
+ return cleanup->insert (*key, dest);
}
else
{
@@ -3531,7 +3539,12 @@ ACE_OS::thr_keyfree (ACE_thread_key_t key)
# 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);
+ TSS_Cleanup_Instance cleanup;
+ if (cleanup.valid ())
+ {
+ return cleanup->free_key (key);
+ }
+ return -1;
# 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.
@@ -3540,16 +3553,14 @@ ACE_OS::thr_keyfree (ACE_thread_key_t key)
{
return cleanup->free_key (key);
}
- else
- {
- return -1;
- }
+ return -1;
# 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);
+ return 0;
# endif /* ACE_HAS_THREADS */
}
@@ -3658,7 +3669,7 @@ ACE_OS::thr_setspecific (ACE_thread_key_t key, void *data)
else
{
ACE_TSS_Emulation::ts_object (key) = data;
- TSS_Cleanup_Instance cleanup ();
+ TSS_Cleanup_Instance cleanup;
if (cleanup.valid ())
{
cleanup->thread_use_key (key);