diff options
Diffstat (limited to 'ace/Thread_Manager.cpp')
-rw-r--r-- | ace/Thread_Manager.cpp | 176 |
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>; |