summaryrefslogtreecommitdiff
path: root/ace/Thread_Manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ace/Thread_Manager.cpp')
-rw-r--r--ace/Thread_Manager.cpp176
1 files changed, 167 insertions, 9 deletions
diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp
index 2d749fa32bf..06ed0d7a4c2 100644
--- a/ace/Thread_Manager.cpp
+++ b/ace/Thread_Manager.cpp
@@ -6,7 +6,6 @@
#include "ace/Object_Manager.h"
#include "ace/Singleton.h"
#include "ace/Auto_Ptr.h"
-#include "ace/Thread_Exit.h"
#if !defined (__ACE_INLINE__)
#include "ace/Thread_Manager.i"
@@ -409,6 +408,99 @@ ACE_Thread_Manager::~ACE_Thread_Manager (void)
this->close ();
}
+#if defined (ACE_HAS_SIG_C_FUNC)
+extern "C" void
+ACE_Thread_Exit_cleanup (void *instance, void *)
+{
+ ACE_TRACE ("ACE_Thread_Exit_cleanup");
+
+ delete (ACE_TSS_TYPE (ACE_Thread_Exit) *) instance;
+}
+#else
+void
+ACE_Thread_Exit::cleanup (void *instance, void *)
+{
+ ACE_TRACE ("ACE_Thread_Exit::cleanup");
+
+ delete (ACE_TSS_TYPE (ACE_Thread_Exit) *) instance;
+}
+#endif /* ACE_HAS_SIG_C_FUNC */
+
+// NOTE: this preprocessor directive should match the one in
+// ACE_Task_Base::svc_run () below. This prevents the two statics
+// from being defined.
+
+ACE_Thread_Exit *
+ACE_Thread_Exit::instance (void)
+{
+#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)
+ ACE_TRACE ("ACE_Thread_Exit::instance");
+
+ // Determines if we were dynamically allocated.
+ static ACE_TSS_TYPE (ACE_Thread_Exit) *instance_;
+
+ // Implement the Double Check pattern.
+
+ if (ACE_Thread_Exit::is_constructed_ == 0)
+ {
+ ACE_MT (ACE_Thread_Mutex *lock =
+ ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object
+ (ACE_Object_Manager::ACE_THREAD_EXIT_LOCK);
+ ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *lock, 0));
+
+ if (ACE_Thread_Exit::is_constructed_ == 0)
+ {
+ ACE_NEW_RETURN (instance_,
+ ACE_TSS_TYPE (ACE_Thread_Exit),
+ 0);
+
+ ACE_Thread_Exit::is_constructed_ = 1;
+
+ // Register for destruction with ACE_Object_Manager.
+#if defined ACE_HAS_SIG_C_FUNC
+ ACE_Object_Manager::at_exit (instance_,
+ ACE_Thread_Exit_cleanup,
+ 0);
+#else
+ ACE_Object_Manager::at_exit (instance_,
+ ACE_Thread_Exit::cleanup,
+ 0);
+#endif /* ACE_HAS_SIG_C_FUNC */
+ }
+ }
+
+ return ACE_TSS_GET (instance_, ACE_Thread_Exit);
+#else
+ return 0;
+#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
+}
+
+// Grab hold of the Task * so that we can close() it in the
+// destructor.
+
+ACE_Thread_Exit::ACE_Thread_Exit (void)
+{
+ ACE_TRACE ("ACE_Thread_Exit::ACE_Thread_Exit");
+}
+
+// Set the this pointer...
+
+void
+ACE_Thread_Exit::thr_mgr (ACE_Thread_Manager *tm)
+{
+ ACE_TRACE ("ACE_Thread_Exit::thr_mgr");
+
+ if (tm != 0)
+ this->thread_control_.insert (tm, 0);
+}
+
+// When this object is destroyed the Task is automatically closed
+// down!
+
+ACE_Thread_Exit::~ACE_Thread_Exit (void)
+{
+ ACE_TRACE ("ACE_Thread_Exit::~ACE_Thread_Exit");
+}
// Run the entry point for thread spawned under the control of the
// <ACE_Thread_Manager>. This must be an extern "C" to make certain
@@ -702,8 +794,7 @@ ACE_Thread_Manager::spawn_n (ACE_thread_t thread_ids[],
int grp_id,
void *stack[],
size_t stack_size[],
- ACE_hthread_t thread_handles[],
- ACE_Task_Base *task)
+ ACE_hthread_t thread_handles[])
{
ACE_TRACE ("ACE_Thread_Manager::spawn_n");
ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
@@ -723,8 +814,7 @@ ACE_Thread_Manager::spawn_n (ACE_thread_t thread_ids[],
priority,
grp_id,
stack == 0 ? 0 : stack[i],
- stack_size == 0 ? 0 : stack_size[i],
- task) == -1)
+ stack_size == 0 ? 0 : stack_size[i]) == -1)
return -1;
}
@@ -948,9 +1038,7 @@ int
ACE_Thread_Manager::join_thr (ACE_Thread_Descriptor *td, int)
{
ACE_TRACE ("ACE_Thread_Manager::join_thr");
-#if defined (ACE_HAS_PACE)
- return ACE_Thread::join (td->thr_handle_);
-#else
+
int result = ACE_Thread::join (td->thr_handle_);
# if defined (ACE_HAS_PTHREADS_DRAFT4) && defined (ACE_LACKS_SETDETACH)
@@ -977,7 +1065,6 @@ ACE_Thread_Manager::join_thr (ACE_Thread_Descriptor *td, int)
}
return 0;
-#endif /* ACE_HAS_PACE */
}
int
@@ -2208,6 +2295,77 @@ ACE_Thread_Manager::get_grp (ACE_Task_Base *task, int &grp_id)
return 0;
}
+void
+ACE_Thread_Control::dump (void) const
+{
+ ACE_TRACE ("ACE_Thread_Control::dump");
+}
+
+int
+ACE_Thread_Control::insert (ACE_Thread_Manager *tm, int insert)
+{
+ ACE_TRACE ("ACE_Thread_Control::insert");
+
+ ACE_hthread_t t_id;
+ ACE_Thread::self (t_id);
+ this->tm_ = tm;
+
+ if (insert)
+ return this->tm_->insert_thr (ACE_Thread::self (), t_id);
+ else
+ return 0;
+}
+
+// Initialize the thread controller.
+
+ACE_Thread_Control::ACE_Thread_Control (ACE_Thread_Manager *t,
+ int insert)
+ : tm_ (t),
+ status_ (0)
+{
+ ACE_TRACE ("ACE_Thread_Control::ACE_Thread_Control");
+
+ if (this->tm_ != 0 && insert)
+ {
+ ACE_hthread_t t_id;
+ ACE_Thread::self (t_id);
+ this->tm_->insert_thr (ACE_Thread::self (), t_id);
+ }
+}
+
+// Automatically kill thread on exit.
+
+ACE_Thread_Control::~ACE_Thread_Control (void)
+{
+ ACE_TRACE ("ACE_Thread_Control::~ACE_Thread_Control");
+
+#if defined (ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS) || defined (ACE_HAS_TSS_EMULATION) || defined (ACE_WIN32)
+ this->exit (this->status_, 0);
+#else
+ this->exit (this->status_, 1);
+#endif /* ACE_HAS_RECURSIVE_THR_EXIT_SEMANTICS */
+}
+
+// Exit from thread (but clean up first).
+
+void *
+ACE_Thread_Control::exit (void *exit_status, int do_thr_exit)
+{
+ ACE_TRACE ("ACE_Thread_Control::exit");
+
+ if (this->tm_ != 0)
+ return this->tm_->exit (exit_status, do_thr_exit);
+ else
+ {
+#if !defined (ACE_HAS_TSS_EMULATION)
+ // With ACE_HAS_TSS_EMULATION, we let ACE_Thread_Adapter::invoke ()
+ // exit the thread after cleaning up TSS.
+ ACE_Thread::exit (exit_status);
+#endif /* ! ACE_HAS_TSS_EMULATION */
+ return 0;
+ }
+}
+
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
# if defined (ACE_THREAD_MANAGER_LACKS_STATICS)
template class ACE_Singleton<ACE_Thread_Manager, ACE_SYNCH_MUTEX>;