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.cpp1524
1 files changed, 0 insertions, 1524 deletions
diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp
deleted file mode 100644
index 3fe852d6caa..00000000000
--- a/ace/Thread_Manager.cpp
+++ /dev/null
@@ -1,1524 +0,0 @@
-// Thread_Manager.cpp
-// $Id$
-
-#define ACE_BUILD_DLL
-#include "ace/Synch_T.h"
-#include "ace/Thread_Manager.h"
-#include "ace/Dynamic.h"
-#include "ace/Object_Manager.h"
-
-#if !defined (__ACE_INLINE__)
-#include "ace/Thread_Manager.i"
-#endif /* __ACE_INLINE__ */
-
-ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Control)
-ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Manager)
-
-// Process-wide Thread Manager.
-ACE_Thread_Manager *ACE_Thread_Manager::thr_mgr_ = 0;
-
-// Controls whether the Thread_Manager is deleted when we shut down
-// (we can only delete it safely if we created it!)
-int ACE_Thread_Manager::delete_thr_mgr_ = 0;
-
-void
-ACE_Thread_Manager::dump (void) const
-{
- ACE_TRACE ("ACE_Thread_Manager::dump");
- // Cast away const-ness of this in order to use its non-const lock_.
- ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon,
- ((ACE_Thread_Manager *) this)->lock_));
-
- ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
-
- ACE_DEBUG ((LM_DEBUG, "\ngrp_id_ = %d", this->grp_id_));
- ACE_DEBUG ((LM_DEBUG, "\nmax_table_size_ = %d", this->max_table_size_));
- ACE_DEBUG ((LM_DEBUG, "\ncurrent_count_ = %d", this->current_count_));
-
- for (size_t i = 0; i < this->current_count_; i++)
- this->thr_table_[i].dump ();
-
- ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
-}
-
-int
-ACE_Thread_Descriptor::at_exit (void *object,
- ACE_CLEANUP_FUNC cleanup_hook,
- void *param)
-{
- ACE_TRACE ("ACE_Thread_Descriptor::at_exit");
-
- // @@ This should really store these values into a stack, but we're
- // just solving one problem at a time now...
- this->cleanup_info_.object_ = object;
- this->cleanup_info_.cleanup_hook_ = cleanup_hook;
- this->cleanup_info_.param_ = param;
- return 0;
-}
-
-void
-ACE_Thread_Descriptor::dump (void) const
-{
- ACE_TRACE ("ACE_Thread_Descriptor::dump");
- ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
-
- ACE_DEBUG ((LM_DEBUG, "\nthr_id_ = %d", this->thr_id_));
- ACE_DEBUG ((LM_DEBUG, "\nthr_handle_ = %d", this->thr_handle_));
- ACE_DEBUG ((LM_DEBUG, "\ngrp_id_ = %d", this->grp_id_));
- ACE_DEBUG ((LM_DEBUG, "\nthr_state_ = %d", this->thr_state_));
- ACE_DEBUG ((LM_DEBUG, "\ncleanup_info_.cleanup_hook_ = %x\n", this->cleanup_info_.cleanup_hook_));
-
- ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
-}
-
-ACE_Thread_Descriptor::ACE_Thread_Descriptor (void)
- : task_ (0),
- thr_id_ (ACE_OS::NULL_thread),
- thr_handle_ (ACE_OS::NULL_hthread),
- grp_id_ (0),
- thr_state_ (ACE_THR_IDLE)
-{
- ACE_TRACE ("ACE_Thread_Descriptor::ACE_Thread_Descriptor");
-
- this->cleanup_info_.cleanup_hook_ = 0;
- this->cleanup_info_.object_ = 0;
- this->cleanup_info_.param_ = 0;
-}
-
-// The following macro simplifies subsequence code.
-#define ACE_FIND(OP,INDEX) \
- int INDEX = OP; \
- if (INDEX == -1) return -1
-
-int
-ACE_Thread_Manager::thread_descriptor (ACE_thread_t thr_id,
- ACE_Thread_Descriptor &descriptor)
-{
- ACE_TRACE ("ACE_Thread_Descriptor::thread_descriptor");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- ACE_FIND (this->find_thread (thr_id), index);
- descriptor = this->thr_table_[index];
- return 0;
-}
-
-
-int
-ACE_Thread_Manager::hthread_descriptor (ACE_hthread_t thr_handle,
- ACE_Thread_Descriptor &descriptor)
-{
- ACE_TRACE ("ACE_Thread_Descriptor::hthread_descriptor");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- ACE_FIND (this->find_hthread (thr_handle), index);
- descriptor = this->thr_table_[index];
- return 0;
-}
-
-// Return the thread descriptor (indexed by ACE_hthread_t).
-
-int
-ACE_Thread_Manager::thr_self (ACE_hthread_t &self)
-{
- ACE_TRACE ("ACE_Thread_Descriptor::thr_self");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- // Try to get the cached HANDLE out of TSS to avoid lookup.
- ACE_hthread_t *handle = ACE_LOG_MSG->thr_handle ();
-
- // Wasn't in the cache, so we'll have to look it up and cache it.
- if (handle == 0)
- {
- ACE_thread_t id = ACE_OS::thr_self ();
-
- ACE_FIND (this->find_thread (id), index);
- handle = &this->thr_table_[index].thr_handle_;
-
- // Update the TSS cache.
- ACE_LOG_MSG->thr_handle (handle);
- }
- self = *handle;
- return 0;
-}
-
-int
-ACE_Thread_Manager::resize (size_t size)
-{
- ACE_TRACE ("ACE_Thread_Manager::resize");
- ACE_Thread_Descriptor *temp;
-
- ACE_NEW_RETURN (temp, ACE_Thread_Descriptor[size], -1);
-
- for (size_t i = 0; i < this->max_table_size_; i++)
- temp[i] = this->thr_table_[i]; // Structure assignment.
-
- this->max_table_size_ = size;
-
- delete [] this->thr_table_;
- this->thr_table_ = temp;
-
- return 0;
-}
-
-// Create and initialize the table to keep track of the thread pool.
-
-int
-ACE_Thread_Manager::open (size_t size)
-{
- ACE_TRACE ("ACE_Thread_Manager::open");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- if (this->max_table_size_ < size)
- this->resize (size);
- return 0;
-}
-
-// Initialize the synchronization variables.
-
-ACE_Thread_Manager::ACE_Thread_Manager (size_t size)
- : thr_table_ (0),
- max_table_size_ (0),
- current_count_ (0),
- grp_id_ (1)
-#if defined (ACE_HAS_THREADS)
- , zero_cond_ (lock_)
-#endif /* ACE_HAS_THREADS */
-{
- ACE_TRACE ("ACE_Thread_Manager::ACE_Thread_Manager");
- if (this->open (size) == -1)
- ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread_Manager"));
-}
-
-ACE_Thread_Manager *
-ACE_Thread_Manager::instance (void)
-{
- ACE_TRACE ("ACE_Thread_Manager::instance");
-
- if (ACE_Thread_Manager::thr_mgr_ == 0)
- {
- // Perform Double-Checked Locking Optimization.
- ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Static_Object_Lock::instance (), 0));
-
- if (ACE_Thread_Manager::thr_mgr_ == 0)
- {
- ACE_NEW_RETURN (ACE_Thread_Manager::thr_mgr_, ACE_Thread_Manager, 0);
- ACE_Thread_Manager::delete_thr_mgr_ = 1;
- }
- }
-
- return ACE_Thread_Manager::thr_mgr_;
-}
-
-ACE_Thread_Manager *
-ACE_Thread_Manager::instance (ACE_Thread_Manager *tm)
-{
- ACE_TRACE ("ACE_Thread_Manager::instance");
- ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Static_Object_Lock::instance (), 0));
-
- ACE_Thread_Manager *t = ACE_Thread_Manager::thr_mgr_;
- // We can't safely delete it since we don't know who created it!
- ACE_Thread_Manager::delete_thr_mgr_ = 0;
-
- ACE_Thread_Manager::thr_mgr_ = tm;
- return t;
-}
-
-void
-ACE_Thread_Manager::close_singleton (void)
-{
- ACE_TRACE ("ACE_Thread_Manager::close_singleton");
-
- ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Static_Object_Lock::instance ()));
-
- if (ACE_Thread_Manager::delete_thr_mgr_)
- {
- delete ACE_Thread_Manager::thr_mgr_;
- ACE_Thread_Manager::thr_mgr_ = 0;
- ACE_Thread_Manager::delete_thr_mgr_ = 0;
- }
-}
-
-// Close up and release all resources.
-
-int
-ACE_Thread_Manager::close (void)
-{
- ACE_TRACE ("ACE_Thread_Manager::close");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- if (this->thr_table_ != 0)
- {
- delete [] this->thr_table_;
- this->thr_table_ = 0;
- this->max_table_size_ = 0;
- this->current_count_ = 0;
- }
- return 0;
-}
-
-ACE_Thread_Manager::~ACE_Thread_Manager (void)
-{
- ACE_TRACE ("ACE_Thread_Manager::~ACE_Thread_Manager");
- this->close ();
-}
-
-#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
-// Lock the creation of the Singleton.
-ACE_Thread_Mutex ACE_Thread_Exit::ace_thread_exit_lock_;
-#endif /* defined (ACE_MT_SAFE) */
-
-#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)) && ! defined (ACE_HAS_PTHREAD_SIGMASK) && !defined (ACE_HAS_FSU_PTHREADS)
- 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 (instance_ == 0)
- {
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, ace_thread_exit_lock_, 0));
-
- if (instance_ == 0)
- {
- ACE_NEW_RETURN (instance_, ACE_TSS_TYPE (ACE_Thread_Exit), 0);
-
- // 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) && ! ACE_HAS_PTHREAD_SIGMASK && ! ACE_HAS_FSU_PTHREADS */
-}
-
-// Grab hold of the Task * so that we can close() it in the
-// destructor.
-
-ACE_Thread_Exit::ACE_Thread_Exit (void)
- : status_ ((void *) -1)
-{
- 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);
-}
-
-// Set the thread exit status value.
-
-void *
-ACE_Thread_Exit::status (void *s)
-{
- ACE_TRACE ("ACE_Thread_Exit::status");
- return this->status_ = s;
-}
-
-void *
-ACE_Thread_Exit::status (void)
-{
- ACE_TRACE ("ACE_Thread_Exit::status");
- return this->status_;
-}
-
-// 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
-// compilers happy...
-//
-// The interaction with <ACE_Thread_Exit> and
-// <ace_thread_manager_adapter> works like this, with
-// ACE_HAS_THREAD_SPECIFIC_STORAGE or ACE_HAS_TSS_EMULATION:
-//
-// o Every thread in the <ACE_Thread_Manager> is run with
-// <ace_thread_manager_adapter>.
-//
-// o <ace_thread_manager_adapter> retrieves the singleton
-// <ACE_Thread_Exit> instance from <ACE_Thread_Exit::instance>.
-// The singleton gets created in thread-specific storage
-// in the first call to that function. The key point is that the
-// instance is in thread-specific storage.
-//
-// o A thread can exit by various means, such as <ACE_Thread::exit>, C++
-// or Win32 exception, "falling off the end" of the thread entry
-// point function, etc.
-//
-// o If you follow this so far, now it gets really fun . . .
-// When the thread-specific storage (for the thread that
-// is being destroyed) is cleaned up, the OS threads package (or
-// the ACE emulation of thread-specific storage) will destroy any
-// objects that are in thread-specific storage. It has a list of
-// them, and just walks down the list and destroys each one.
-//
-// o That's where the ACE_Thread_Exit destructor gets called.
-
-extern "C" void *
-ace_thread_manager_adapter (void *args)
-{
-#if defined (ACE_HAS_TSS_EMULATION)
- // As early as we can in the execution of the new thread, allocate
- // its local TS storage. Allocate it on the stack, to save dynamic
- // allocation/dealloction.
- void *ts_storage[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX];
- ACE_TSS_Emulation::tss_open (ts_storage);
-#endif /* ACE_HAS_TSS_EMULATION */
-
- ACE_Thread_Adapter *thread_args = (ACE_Thread_Adapter *) args;
-
- // NOTE: this preprocessor directive should match the one in above
- // ACE_Thread_Exit::instance (). With the Xavier Pthreads package,
- // the exit_hook in TSS causes a seg fault. So, this works around
- // that by creating exit_hook on the stack.
-#if (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)) && ! defined (ACE_HAS_PTHREAD_SIGMASK) && !defined (ACE_HAS_FSU_PTHEADS)
- // Obtain our thread-specific exit hook and make sure that it knows
- // how to clean us up! Note that we never use this pointer directly
- // (it's stored in thread-specific storage), so it's ok to
- // dereference it here and only store it as a reference.
- ACE_Thread_Exit &exit_hook = *ACE_Thread_Exit::instance ();
-#else
- // Without TSS, create an <ACE_Thread_Exit> instance. When this
- // function returns, its destructor will be called because the
- // object goes out of scope. The drawback with this appraoch is
- // that the destructor _won't_ get called if <thr_exit> is called.
- // So, threads shouldn't exit that way. Instead, they should return
- // from <svc>.
- ACE_Thread_Exit exit_hook;
-#endif /* (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION) && ! ACE_HAS_PTHREAD_SIGMASK && !ACE_HAS_FSU_PTHREADS */
-
- // Keep track of the <Thread_Manager> that's associated with this
- // <exit_hook>.
- exit_hook.thr_mgr (thread_args->thr_mgr ());
-
- // Invoke the user-supplied function with the args.
- void *status = thread_args->invoke ();
-
-#if defined (ACE_HAS_TSS_EMULATION)
- // Lastly, close the thread's local TS storage.
- ACE_TSS_Emulation::tss_close (ts_storage);
-#endif /* ACE_HAS_TSS_EMULATION */
-
- return status;
-}
-
-// Call the appropriate OS routine to spawn a thread. Should *not* be
-// called with the lock_ held...
-
-// HEY! Consider duping the handles so that users can have something
-// to manipulate if they want.
-
-int
-ACE_Thread_Manager::spawn_i (ACE_THR_FUNC func,
- void *args,
- long flags,
- ACE_thread_t *t_id,
- ACE_hthread_t *t_handle,
- long priority,
- int grp_id,
- void *stack,
- size_t stack_size,
- ACE_Task_Base *task)
-{
- ACE_Thread_Adapter *thread_args = 0;
-#if !defined (ACE_NO_THREAD_ADAPTER)
- ACE_NEW_RETURN (thread_args,
- ACE_Thread_Adapter (func,
- args,
- (ACE_THR_C_FUNC) ace_thread_manager_adapter,
- this),
- -1);
-#endif /* ACE_NO_THREAD_ADAPTER */
-
- ACE_TRACE ("ACE_Thread_Manager::spawn_i");
- ACE_thread_t thr_id;
- ACE_hthread_t thr_handle;
-
- if (t_id == 0)
- t_id = &thr_id;
-
- if (t_handle == 0)
- t_handle = &thr_handle;
-
- int result = ACE_Thread::spawn (func,
- args,
- flags,
- t_id,
- t_handle,
- priority,
- stack,
- stack_size,
- thread_args);
- if (result != 0)
- // _Don't_ clobber errno here! result is either 0 or -1, and
- // ACE_OS::thr_create () already set errno! D. Levine 28 Mar 1997
- // errno = result;
- return -1;
- else
- return this->append_thr (*t_id,
- *t_handle,
- ACE_THR_SPAWNED,
- grp_id,
- task);
-}
-
-// Create a new thread running <func>. *Must* be called with the
-// <lock_> held...
-
-int
-ACE_Thread_Manager::spawn (ACE_THR_FUNC func,
- void *args,
- long flags,
- ACE_thread_t *t_id,
- ACE_hthread_t *t_handle,
- long priority,
- int grp_id,
- void *stack,
- size_t stack_size)
-{
- ACE_TRACE ("ACE_Thread_Manager::spawn");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- if (grp_id == -1)
- grp_id = this->grp_id_++; // Increment the group id.
-
- if (this->spawn_i (func, args, flags, t_id, t_handle,
- priority, grp_id, stack, stack_size) == -1)
- return -1;
- else
- return grp_id;
-}
-
-// Create N new threads running FUNC.
-
-int
-ACE_Thread_Manager::spawn_n (size_t n,
- ACE_THR_FUNC func,
- void *args,
- long flags,
- long priority,
- int grp_id,
- 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));
-
- if (grp_id == -1)
- grp_id = this->grp_id_++; // Increment the group id.
-
- for (size_t i = 0; i < n; i++)
- {
- // @@ What should happen if this fails?! e.g., should we try to
- // cancel the other threads that we've already spawned or what?
- if (this->spawn_i (func,
- args,
- flags,
- 0,
- thread_handles == 0 ? 0 : &thread_handles[i],
- priority,
- grp_id,
- 0,
- 0,
- task) == -1)
- return -1;
- }
-
- return grp_id;
-}
-
-// Create N new threads running FUNC.
-
-int
-ACE_Thread_Manager::spawn_n (ACE_thread_t thread_ids[],
- size_t n,
- ACE_THR_FUNC func,
- void *args,
- long flags,
- long priority,
- int grp_id,
- void *stack[],
- size_t stack_size[],
- 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));
-
- if (grp_id == -1)
- grp_id = this->grp_id_++; // Increment the group id.
-
- for (size_t i = 0; i < n; i++)
- {
- // @@ What should happen if this fails?! e.g., should we try to
- // cancel the other threads that we've already spawned or what?
- if (this->spawn_i (func,
- args,
- flags,
- thread_ids == 0 ? 0 : &thread_ids[i],
- thread_handles == 0 ? 0 : &thread_handles[i],
- priority,
- grp_id,
- stack == 0 ? 0 : stack[i],
- stack_size == 0 ? 0 : stack_size[i]) == -1)
- return -1;
- }
-
- return grp_id;
-}
-
-// Append a thread into the pool (does not check for duplicates).
-// Must be called with locks held.
-
-int
-ACE_Thread_Manager::append_thr (ACE_thread_t t_id,
- ACE_hthread_t t_handle,
- ACE_Thread_State thr_state,
- int grp_id,
- ACE_Task_Base *task)
-{
- ACE_TRACE ("ACE_Thread_Manager::append_thr");
- // Try to resize the array to twice its existing size if we run out
- // of space...
- if (this->current_count_ >= this->max_table_size_
- && this->resize (this->max_table_size_ * 2) == -1)
- return -1;
- else
- {
- ACE_Thread_Descriptor &thr_desc =
- this->thr_table_[this->current_count_];
-
- thr_desc.thr_id_ = t_id;
- thr_desc.thr_handle_ = t_handle;
- thr_desc.grp_id_ = grp_id;
- thr_desc.thr_state_ = thr_state;
- thr_desc.task_ = task;
- thr_desc.cleanup_info_.cleanup_hook_ = 0;
- thr_desc.cleanup_info_.object_ = 0;
- thr_desc.cleanup_info_.param_ = 0;
-
- this->current_count_++;
- return 0;
- }
-}
-
-// Return the thread descriptor (indexed by ACE_hthread_t).
-
-int
-ACE_Thread_Manager::find_hthread (ACE_hthread_t h_id)
-{
- ACE_TRACE ("ACE_Thread_Descriptor::find_hthread");
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (ACE_OS::thr_cmp (h_id, this->thr_table_[i].thr_handle_))
- return i;
-
- return -1;
-}
-
-// Locate the index in the table associated with <t_id>. Must be
-// called with the lock held.
-
-int
-ACE_Thread_Manager::find_thread (ACE_thread_t t_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::find_thread");
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (ACE_OS::thr_equal (t_id, this->thr_table_[i].thr_id_))
- return i;
-
- return -1;
-}
-
-// Insert a thread into the pool (checks for duplicates and doesn't
-// allow them to be inserted twice).
-
-int
-ACE_Thread_Manager::insert_thr (ACE_thread_t t_id,
- ACE_hthread_t t_handle,
- int grp_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::insert_thr");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- // Check for duplicates and bail out if we're already registered...
- if (this->find_thread (t_id) != -1)
- return -1;
-
- if (grp_id == -1)
- grp_id = this->grp_id_++;
-
- if (this->append_thr (t_id, t_handle,
- ACE_THR_SPAWNED,
- grp_id) == -1)
- return -1;
- else
- return grp_id;
-}
-
-// Run the registered hooks when the thread exits.
-
-void
-ACE_Thread_Manager::run_thread_exit_hooks (int i)
-{
-#if 0 // currently unused!
- ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks");
-
- // @@ Currently, we have just one hook. This should clearly be
- // generalized to support an arbitrary number of hooks.
-
- if (this->thr_table_[i].cleanup_info_.cleanup_hook_ != 0)
- {
- (*this->thr_table_[i].cleanup_info_.cleanup_hook_)
- (this->thr_table_[i].cleanup_info_.object_,
- this->thr_table_[i].cleanup_info_.param_);
-
- this->thr_table_[i].cleanup_info_.cleanup_hook_ = 0;
- }
-#else
- ACE_UNUSED_ARG (i);
-#endif // 0
-}
-
-// Remove a thread from the pool. Must be called with locks held.
-
-void
-ACE_Thread_Manager::remove_thr (int i)
-{
- ACE_TRACE ("ACE_Thread_Manager::remove_thr");
-
- this->current_count_--;
-
- // This compaction strategy should be removed so that we can use the
- // TSS trick.
-
- if (this->current_count_ > 0)
- // Compact the table by moving the last item into the slot vacated
- // by the index being removed (this is a structure assignment).
- this->thr_table_[i] = this->thr_table_[this->current_count_];
-
-#if defined (ACE_HAS_THREADS)
- // Tell all waiters when there are no more threads left in the pool.
- if (this->current_count_ == 0)
- this->zero_cond_.broadcast ();
-#endif /* ACE_HAS_THREADS */
-}
-
-// Factor out some common behavior to simplify the following methods.
-#define ACE_THR_OP(OP,STATE) \
- int result = OP (this->thr_table_[i].thr_handle_); \
- if (result != 0) { \
- this->remove_thr (i); \
- errno = result; \
- return -1; \
- } \
- else { \
- this->thr_table_[i].thr_state_ = STATE; \
- return 0; \
- }
-
-int
-ACE_Thread_Manager::join_thr (int i)
-{
- ACE_TRACE ("ACE_Thread_Manager::join_thr");
-
- ACE_THR_OP (ACE_Thread::join, ACE_THR_TERMINATED);
-}
-
-int
-ACE_Thread_Manager::suspend_thr (int i)
-{
- ACE_TRACE ("ACE_Thread_Manager::suspend_thr");
-
- ACE_THR_OP (ACE_Thread::suspend, ACE_THR_SUSPENDED);
-}
-
-int
-ACE_Thread_Manager::resume_thr (int i)
-{
- ACE_TRACE ("ACE_Thread_Manager::resume_thr");
-
- ACE_THR_OP (ACE_Thread::resume, ACE_THR_RUNNING);
-}
-
-int
-ACE_Thread_Manager::cancel_thr (int i)
-{
- ACE_TRACE ("ACE_Thread_Manager::cancel_thr");
- this->thr_table_[i].thr_state_ = ACE_THR_CANCELLED;
- return 0;
-}
-
-int
-ACE_Thread_Manager::kill_thr (int i, int arg)
-{
- ACE_TRACE ("ACE_Thread_Manager::kill_thr");
-
- int signum = (int) arg;
-
- int result = ACE_Thread::kill ((ACE_thread_t) this->thr_table_[i].thr_id_,
- signum);
-
- if (result != 0)
- {
- // We need to save this across calls to remove_thr() since that
- // call may reset errno.
- int error = errno;
-
- this->remove_thr (i);
- errno = error;
- return -1;
- }
- else
- return 0;
-}
-
-#define ACE_EXECUTE_OP(OP) \
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); \
- ACE_FIND (this->find_thread (t_id), index); \
- return OP (index);
-
-// Suspend a single thread.
-
-int
-ACE_Thread_Manager::suspend (ACE_thread_t t_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::suspend");
- ACE_EXECUTE_OP (this->suspend_thr);
-}
-
-// Resume a single thread.
-
-int
-ACE_Thread_Manager::resume (ACE_thread_t t_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::resume");
- ACE_EXECUTE_OP (this->resume_thr);
-}
-
-// Cancel a single thread.
-
-int
-ACE_Thread_Manager::cancel (ACE_thread_t t_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::cancel");
- ACE_EXECUTE_OP (this->cancel_thr);
-}
-
-// Send a signal to a single thread.
-
-int
-ACE_Thread_Manager::kill (ACE_thread_t t_id, int signum)
-{
- ACE_TRACE ("ACE_Thread_Manager::kill");
- return ACE_Thread::kill (t_id, signum);
-}
-
-int
-ACE_Thread_Manager::check_state (ACE_Thread_State state,
- ACE_thread_t id)
-{
- ACE_TRACE ("ACE_Thread_Manager::check_state");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- ACE_Thread_State *thr_state = 0;
-#if 0
- int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ());
-
- // If we're checking the state of our thread, try to get the cached
- // value out of TSS to avoid lookup.
- if (self_check)
- thr_state = ACE_LOG_MSG->thr_state ();
-
- // Wasn't in the cache, so we'll have to look it up.
- if (thr_state == 0)
- {
- ACE_FIND (this->find_thread (id), index);
- thr_state = &this->thr_table_[index].thr_state_;
-
- if (self_check) // Update the TSS cache.
- ACE_LOG_MSG->thr_state (thr_state);
- }
-#else
- // Turn off caching for the time being until we figure out
- // how to do it correctly in the face of deletions...
- ACE_FIND (this->find_thread (id), index);
- thr_state = &this->thr_table_[index].thr_state_;
-#endif /* 0 */
- return *thr_state == state;
-}
-
-// Test if a single thread is suspended.
-
-int
-ACE_Thread_Manager::testsuspend (ACE_thread_t t_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::testsuspend");
- return this->check_state (ACE_THR_SUSPENDED, t_id);
-}
-
-// Test if a single thread is active (i.e., resumed).
-
-int
-ACE_Thread_Manager::testresume (ACE_thread_t t_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::testresume");
- return this->check_state (ACE_THR_RUNNING, t_id);
-}
-
-// Test if a single thread is cancelled.
-
-int
-ACE_Thread_Manager::testcancel (ACE_thread_t t_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::testcancel");
- return this->check_state (ACE_THR_CANCELLED, t_id);
-}
-
-// Get group ids for a particular thread id.
-
-int
-ACE_Thread_Manager::get_grp (ACE_thread_t t_id, int &grp_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::get_grp");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- ACE_FIND (this->find_thread (t_id), index);
- grp_id = this->thr_table_[index].grp_id_;
- return 0;
-}
-
-// Set group ids for a particular thread id.
-
-int
-ACE_Thread_Manager::set_grp (ACE_thread_t t_id, int grp_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::set_grp");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- ACE_FIND (this->find_thread (t_id), index);
- this->thr_table_[index].grp_id_ = grp_id;
- return 0;
-}
-
-// Suspend a group of threads.
-
-int
-ACE_Thread_Manager::apply_grp (int grp_id,
- THR_FUNC func,
- int arg)
-{
- ACE_TRACE ("ACE_Thread_Manager::apply_grp");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- int result = 0;
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (this->thr_table_[i].grp_id_ == grp_id
- && (this->*func)(i, arg) == -1)
- result = -1;
-
- return result;
-}
-
-int
-ACE_Thread_Manager::suspend_grp (int grp_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::suspend_grp");
- return this->apply_grp (grp_id,
- THR_FUNC (&ACE_Thread_Manager::suspend_thr));
-}
-
-// Resume a group of threads.
-
-int
-ACE_Thread_Manager::resume_grp (int grp_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::resume_grp");
- return this->apply_grp (grp_id,
- THR_FUNC (&ACE_Thread_Manager::resume_thr));
-}
-
-// Kill a group of threads.
-
-int
-ACE_Thread_Manager::kill_grp (int grp_id, int signum)
-{
- ACE_TRACE ("ACE_Thread_Manager::kill_grp");
- return this->apply_grp (grp_id,
- THR_FUNC (&ACE_Thread_Manager::kill_thr), signum);
-}
-
-// Cancel a group of threads.
-
-int
-ACE_Thread_Manager::cancel_grp (int grp_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::resume_grp");
- return this->apply_grp (grp_id,
- THR_FUNC (&ACE_Thread_Manager::cancel_thr));
-}
-
-int
-ACE_Thread_Manager::apply_all (THR_FUNC func, int arg)
-{
- ACE_TRACE ("ACE_Thread_Manager::apply_all");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- int result = 0;
-
- for (size_t i = 0; i < this->current_count_; i++)
- if ((this->*func)(i, arg) == -1)
- result = -1;
-
- return result;
-}
-
-// Resume all threads that are suspended.
-
-int
-ACE_Thread_Manager::resume_all (void)
-{
- ACE_TRACE ("ACE_Thread_Manager::resume_all");
- return this->apply_all (THR_FUNC (&ACE_Thread_Manager::resume_thr));
-}
-
-int
-ACE_Thread_Manager::suspend_all (void)
-{
- ACE_TRACE ("ACE_Thread_Manager::suspend_all");
- return this->apply_all (THR_FUNC (&ACE_Thread_Manager::suspend_thr));
-}
-
-int
-ACE_Thread_Manager::kill_all (int sig)
-{
- ACE_TRACE ("ACE_Thread_Manager::kill_all");
- return this->apply_all (&ACE_Thread_Manager::kill_thr, sig);
-}
-
-int
-ACE_Thread_Manager::cancel_all (void)
-{
- ACE_TRACE ("ACE_Thread_Manager::cancel_all");
- return this->apply_all (THR_FUNC (&ACE_Thread_Manager::cancel_thr));
-}
-
-// Wait for group of threads
-
-int
-ACE_Thread_Manager::wait_grp (int grp_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::wait_grp");
-
- int copy_count = 0;
- ACE_Thread_Descriptor *copy_table = 0;
-
- // We have to make sure that while we wait for these threads to
- // exit, we do not have the lock. Therefore we make a copy of all
- // interesting entries and let go of the lock.
- {
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- copy_table = new ACE_Thread_Descriptor [this->current_count_];
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (this->thr_table_[i].grp_id_ == grp_id)
- {
- copy_table[copy_count] = this->thr_table_[i];
- copy_count++;
- }
- }
-
- // Now to do the actual work
- int result = 0;
-
- for (int i = 0;
- i < copy_count && result != -1;
- i++)
- if (ACE_Thread::join (copy_table[i].thr_handle_) == -1)
- result = -1;
-
- delete [] copy_table;
-
- return result;
-}
-
-int
-ACE_Thread_Manager::at_exit (void *object,
- ACE_CLEANUP_FUNC cleanup_hook,
- void *param)
-{
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
-
- // Locate thread id.
- int i = this->find_thread (ACE_Thread::self ());
-
- if (i != -1)
- return this->thr_table_[i].at_exit (object, cleanup_hook, param);
- else
- return -1;
-}
-
-// Must be called when thread goes out of scope to clean up its table
-// slot.
-
-void *
-ACE_Thread_Manager::exit (void *status, int do_thr_exit)
-{
- ACE_TRACE ("ACE_Thread_Manager::exit");
-
- int i;
- ACE_Cleanup_Info cleanup_info;
-
- // Just hold onto the guard while finding this thread's id and
- // copying the exit hook.
- {
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
-
- // Locate thread id.
- i = this->find_thread (ACE_Thread::self ());
-
- if (i != -1)
- {
- // @@ Currently, we have just one hook. This should clearly
- // be generalized to support an arbitrary number of hooks.
-
- if (this->thr_table_[i].cleanup_info_.cleanup_hook_ != 0)
- {
- // Copy the hook so that we can call it after releasing
- // the guard.
- cleanup_info = this->thr_table_[i].cleanup_info_;
- this->thr_table_[i].cleanup_info_.cleanup_hook_ = 0;
- }
-
- // Remove thread descriptor from the table.
- this->remove_thr (i);
- }
- // Release the guard.
- }
-
- // Call the cleanup hook.
- if (cleanup_info.cleanup_hook_ != 0)
- (*cleanup_info.cleanup_hook_) (cleanup_info.object_,
- cleanup_info.param_);
-
- if (do_thr_exit)
- {
- ACE_Thread::exit (status);
- // On reasonable systems <ACE_Thread::exit> should not return.
- // However, due to horrible semantics with Win32 thread-specific
- // storage this call can return (don't ask...).
- }
-
- return 0;
-}
-
-// Wait for all the threads to exit.
-
-int
-ACE_Thread_Manager::wait (const ACE_Time_Value *timeout)
-{
- // HEY! What we should do is build a table of threads which have
- // been removed so that we can ``join'' with them later.
-
- ACE_TRACE ("ACE_Thread_Manager::wait");
-
-#if defined (ACE_HAS_THREADS)
- size_t threads_waited_on;
-
- // Just hold onto the guard while waiting.
- {
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- threads_waited_on = this->current_count_;
-
- while (this->current_count_ > 0)
- if (this->zero_cond_.wait (timeout) == -1)
- return -1;
- }
- // Let go of the guard, giving other threads a chance to run.
-
- // Yield (four times) for each thread that we had to wait on. This
- // should give each of those threads a chance to clean up. The
- // problem arises because the threads that signalled zero_cond_ may
- // not have had a chance to run after that, and therefore may not
- // have finished cleaning themselves up. This isn't a guaranteed
- // fix, of course, but that would be very complicated.
- for (size_t i = 0; i < 4 * threads_waited_on; ++i)
- ACE_OS::thr_yield ();
-#else
- ACE_UNUSED_ARG (timeout);
-#endif /* ACE_HAS_THREADS */
-
- return 0;
-}
-
-int
-ACE_Thread_Manager::apply_task (ACE_Task_Base *task,
- THR_FUNC func,
- int arg)
-{
- ACE_TRACE ("ACE_Thread_Manager::apply_task");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- int result = 0;
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (this->thr_table_[i].task_ == task
- && (this->*func)(i, arg) == -1)
- result = -1;
-
- return result;
-}
-
-// Wait for task
-int
-ACE_Thread_Manager::wait_task (ACE_Task_Base *task)
-{
- int copy_count = 0;
- ACE_Thread_Descriptor *copy_table = 0;
-
- // We have to make sure that while we wait for these threads to
- // exit, we do not have the lock. Therefore we make a copy of all
- // interesting entries and let go of the lock.
- {
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- ACE_NEW_RETURN (copy_table,
- ACE_Thread_Descriptor [this->current_count_],
- -1);
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (this->thr_table_[i].task_ == task)
- {
- copy_table[copy_count] = this->thr_table_[i];
- copy_count++;
- }
- }
-
- // Now to do the actual work
- int result = 0;
-
- for (int i = 0; i < copy_count && result != -1; i++)
- if (ACE_Thread::join (copy_table[i].thr_handle_) == -1)
- result = -1;
-
- delete [] copy_table;
-
- return result;
-}
-
-// Suspend a task
-int
-ACE_Thread_Manager::suspend_task (ACE_Task_Base *task)
-{
- ACE_TRACE ("ACE_Thread_Manager::suspend_task");
- return this->apply_task (task,
- THR_FUNC (&ACE_Thread_Manager::suspend_thr));
-}
-
-// Resume a task.
-int
-ACE_Thread_Manager::resume_task (ACE_Task_Base *task)
-{
- ACE_TRACE ("ACE_Thread_Manager::resume_task");
- return this->apply_task (task,
- THR_FUNC (&ACE_Thread_Manager::resume_thr));
-}
-
-// Kill a task.
-int
-ACE_Thread_Manager::kill_task (ACE_Task_Base *task, int /* signum */)
-{
- ACE_TRACE ("ACE_Thread_Manager::kill_task");
- return this->apply_task (task,
- THR_FUNC (&ACE_Thread_Manager::kill_thr));
-}
-
-// Cancel a task.
-int
-ACE_Thread_Manager::cancel_task (ACE_Task_Base *task)
-{
- ACE_TRACE ("ACE_Thread_Manager::cancel_task");
- return this->apply_task (task,
- THR_FUNC (&ACE_Thread_Manager::cancel_thr));
-}
-
-// Locate the index in the table associated with <task> from the
-// beginning of the table up to an index. Must be called with the
-// lock held.
-
-int
-ACE_Thread_Manager::find_task (ACE_Task_Base *task,
- int index)
-{
- ACE_TRACE ("ACE_Thread_Manager::find_task");
-
- if (index == -1)
- index = current_count_;
-
- for (int i = 0; i < index; i++)
- if (task == this->thr_table_[i].task_)
- return i;
-
- return -1;
-}
-
-// Returns the number of ACE_Task in a group.
-
-int
-ACE_Thread_Manager::num_tasks_in_group (int grp_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::num_tasks_in_group");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- int tasks_count = 0;
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (this->thr_table_[i].grp_id_ == grp_id
- && this->find_task (thr_table_[i].task_, i) == -1)
- tasks_count++;
-
- return tasks_count;
-}
-
-// Returns the number of threads in an ACE_Task.
-
-int
-ACE_Thread_Manager::num_threads_in_task (ACE_Task_Base *task)
-{
- ACE_TRACE ("ACE_Thread_Manager::num_threads_in_task");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- int threads_count = 0;
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (this->thr_table_[i].task_ == task)
- threads_count++;
-
- return threads_count;
-}
-
-// Returns in task_list a list of ACE_Tasks in a group.
-
-int
-ACE_Thread_Manager::task_list (int grp_id,
- ACE_Task_Base *task_list[],
- size_t n)
-{
- ACE_TRACE ("ACE_Thread_Manager::task_list");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- ACE_Task_Base **task_list_iterator = task_list;
- size_t task_list_count = 0;
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (task_list_count < n
- && this->thr_table_[i].grp_id_ == grp_id
- && this->find_task (thr_table_[i].task_, i) == -1)
- {
- task_list_iterator[task_list_count] = this->thr_table_[i].task_;
- task_list_count++;
- }
-
- return 0;
-}
-
-// Returns in thread_list a list of thread ids in an ACE_Task.
-
-int
-ACE_Thread_Manager::thread_list (ACE_Task_Base *task,
- ACE_thread_t thread_list[],
- size_t n)
-{
- ACE_TRACE ("ACE_Thread_Manager::thread_list");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- ACE_thread_t *thread_list_iterator = thread_list;
- size_t thread_list_count = 0;
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (thread_list_count < n && this->thr_table_[i].task_ == task)
- {
- thread_list_iterator[thread_list_count] = this->thr_table_[i].thr_id_;
- thread_list_count++;
- }
-
- return 0;
-}
-
-// Returns in thread_list a list of thread handles in an ACE_Task.
-
-int
-ACE_Thread_Manager::hthread_list (ACE_Task_Base *task,
- ACE_hthread_t hthread_list[],
- size_t n)
-{
- ACE_TRACE ("ACE_Thread_Manager::thread_list");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- ACE_hthread_t *hthread_list_iterator = hthread_list;
- size_t hthread_list_count = 0;
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (this->thr_table_[i].task_ == task
- && hthread_list_count < n)
- {
- hthread_list_iterator[hthread_list_count] =
- this->thr_table_[i].thr_handle_;
- hthread_list_count++;
- }
-
- return 0;
-}
-
-int
-ACE_Thread_Manager::set_grp (ACE_Task_Base *task, int grp_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::set_grp");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- for (size_t i = 0; i < this->current_count_; i++)
- if (this->thr_table_[i].task_ == task)
- this->thr_table_[i].grp_id_ = grp_id;
- return 0;
-}
-
-int
-ACE_Thread_Manager::get_grp (ACE_Task_Base *task, int &grp_id)
-{
- ACE_TRACE ("ACE_Thread_Manager::get_grp");
- ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
-
- ACE_FIND (this->find_task (task), index);
- grp_id = this->thr_table_[index].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)
-{
- ACE_TRACE ("ACE_Thread_Control::insert");
-
- ACE_hthread_t t_id;
- ACE_Thread::self (t_id);
- this->tm_ = tm;
-
- return this->tm_->insert_thr (ACE_Thread::self (), t_id);
-}
-
-// 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)
- 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_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)))
- // This doesn't necessarily belong here, but it's a convenient place for it.
- template class ACE_TSS<ACE_Dynamic>;
- template class ACE_TSS<ACE_Thread_Exit>;
-#endif /* ACE_HAS_THREADS && (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION) */
-#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
-#if (defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)))
- // This doesn't necessarily belong here, but it's a convenient place for it.
- #pragma instantiate ACE_TSS<ACE_Dynamic>
- #pragma instantiate ACE_TSS<ACE_Thread_Exit>
-#endif /* ACE_HAS_THREADS && (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION) */
-#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */