summaryrefslogtreecommitdiff
path: root/ace/Synch_T.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ace/Synch_T.cpp')
-rw-r--r--ace/Synch_T.cpp31
1 files changed, 20 insertions, 11 deletions
diff --git a/ace/Synch_T.cpp b/ace/Synch_T.cpp
index c5c552a3204..4336dbcbfd1 100644
--- a/ace/Synch_T.cpp
+++ b/ace/Synch_T.cpp
@@ -309,22 +309,31 @@ ACE_TSS<TYPE>::ts_get (void) const
// Create and initialize thread-specific ts_obj.
if (this->once_ == 0)
{
+ // We need the lock for ACE_TSS_Cleanup as well since the
+ // ACE_Thread::keycreate() method requires access to internal
+ // tables. This is to avoid deadlocks when using ACE_TSS from
+ // the close() hook of an ACE_Task.
+ ACE_OS::thr_win32_tls_table_lock ();
+
// Insure that we are serialized!
- ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, (ACE_Thread_Mutex &) this->keylock_, 0);
+ ACE_GUARD_RETURN (ACE_Mutex, ace_mon, (ACE_Mutex &) this->keylock_, 0);
+
+ int result;
// Use the Double-Check pattern to make sure we only create the
// key once!
if (this->once_ == 0)
- {
- if (ACE_Thread::keycreate ((ACE_thread_key_t *) &this->key_,
- &ACE_TSS<TYPE>::cleanup,
- (void *) this) != 0)
- return 0; // Major problems, this should *never* happen!
-
- // This *must* come last to avoid race conditions! Note
- // that we need to "cast away const..."
- *(int *) &this->once_ = 1;
- }
+ result = ACE_Thread::keycreate ((ACE_thread_key_t *) &this->key_,
+ &ACE_TSS<TYPE>::cleanup,
+ (void *) this);
+ ACE_OS::thr_win32_tls_table_release ();
+
+ if (result != 0)
+ return 0; // Major problems, this should *never* happen!
+ else
+ // This *must* come last to avoid race conditions! Note
+ // that we need to "cast away const..."
+ *(int *) &this->once_ = 1;
}
TYPE *ts_obj = 0;