summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>1997-09-03 00:19:05 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>1997-09-03 00:19:05 +0000
commit341cbc7c3a474f1b1350076b14c2d60652728a47 (patch)
treebbc69e58be4b9f20d77bce8e4be665b515abdfd8 /ace
parentb917f7cb29895c47c3042ca6fa352ab88d837d83 (diff)
downloadATCD-341cbc7c3a474f1b1350076b14c2d60652728a47.tar.gz
*** empty log message ***
Diffstat (limited to 'ace')
-rw-r--r--ace/OS.h14
-rw-r--r--ace/Object_Manager.cpp22
-rw-r--r--ace/Object_Manager.h22
-rw-r--r--ace/Task.cpp14
-rw-r--r--ace/Task.h4
-rw-r--r--ace/Thread_Manager.cpp56
-rw-r--r--ace/Thread_Manager.h35
7 files changed, 126 insertions, 41 deletions
diff --git a/ace/OS.h b/ace/OS.h
index 9f81136e9c4..c28be491c29 100644
--- a/ace/OS.h
+++ b/ace/OS.h
@@ -2957,6 +2957,20 @@ struct ACE_Export ACE_Str_Buf : public strbuf
// <ACE_Object_Manager> and the <ACE_Thread_Manager>.
typedef void (*ACE_CLEANUP_FUNC)(void *object, void *param) /* throw () */;
+struct ACE_Cleanup_Info
+ // = TITLE
+ // Hold cleanup information for thread/process
+{
+ void *object_;
+ // Point to object that gets passed into the <cleanup_hook_>.
+
+ ACE_CLEANUP_FUNC cleanup_hook_;
+ // Cleanup hook that gets called back.
+
+ void *param_;
+ // Parameter passed to the <cleanup_hook_>.
+};
+
// Run the thread entry point for the <ACE_Thread_Adapter>. This must
// be an extern "C" to make certain compilers happy...
extern "C" void *ace_thread_adapter (void *args);
diff --git a/ace/Object_Manager.cpp b/ace/Object_Manager.cpp
index 3c788fbff94..ac6c32fd739 100644
--- a/ace/Object_Manager.cpp
+++ b/ace/Object_Manager.cpp
@@ -17,7 +17,7 @@ ACE_Object_Manager *ACE_Object_Manager::instance_ = 0;
ACE_Object_Manager::ACE_Object_Manager (void)
: shutting_down_(0)
{
- ACE_NEW (registered_objects_, ACE_Unbounded_Queue<object_info_t>);
+ ACE_NEW (registered_objects_, ACE_Unbounded_Queue<ACE_Cleanup_Info>);
#if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
// Store the address of this static instance so that instance ()
@@ -33,7 +33,7 @@ ACE_Object_Manager::ACE_Object_Manager (void)
ACE_Object_Manager::~ACE_Object_Manager (void)
{
- object_info_t info;
+ ACE_Cleanup_Info info;
// This call closes and deletes all ACE library services and
// singletons.
@@ -92,8 +92,8 @@ ACE_Object_Manager::at_exit_i (void *object,
return -1;
// Check for already in queue, and return 1 if so.
- object_info_t *info = 0;
- for (ACE_Unbounded_Queue_Iterator<object_info_t> iter (*registered_objects_);
+ ACE_Cleanup_Info *info = 0;
+ for (ACE_Unbounded_Queue_Iterator<ACE_Cleanup_Info> iter (*registered_objects_);
iter.next (info) != 0;
iter.advance ())
{
@@ -104,7 +104,7 @@ ACE_Object_Manager::at_exit_i (void *object,
}
}
- object_info_t new_info;
+ ACE_Cleanup_Info new_info;
new_info.object_ = object;
new_info.cleanup_hook_ = cleanup_hook;
new_info.param_ = param;
@@ -115,11 +115,11 @@ ACE_Object_Manager::at_exit_i (void *object,
}
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
-template class ACE_Unbounded_Queue<ACE_Object_Manager::object_info_t>;
-template class ACE_Unbounded_Queue_Iterator<ACE_Object_Manager::object_info_t>;
-template class ACE_Node<ACE_Object_Manager::object_info_t>;
+template class ACE_Unbounded_Queue<ACE_Object_Manager::ACE_Cleanup_Info>;
+template class ACE_Unbounded_Queue_Iterator<ACE_Object_Manager::ACE_Cleanup_Info>;
+template class ACE_Node<ACE_Object_Manager::ACE_Cleanup_Info>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
-#pragma instantiate ACE_Unbounded_Queue<ACE_Object_Manager::object_info_t>
-#pragma instantiate ACE_Unbounded_Queue_Iterator<ACE_Object_Manager::object_info_t>
-#pragma instantiate ACE_Node<ACE_Object_Manager::object_info_t>
+#pragma instantiate ACE_Unbounded_Queue<ACE_Object_Manager::ACE_Cleanup_Info>
+#pragma instantiate ACE_Unbounded_Queue_Iterator<ACE_Object_Manager::ACE_Cleanup_Info>
+#pragma instantiate ACE_Node<ACE_Object_Manager::ACE_Cleanup_Info>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/ace/Object_Manager.h b/ace/Object_Manager.h
index d7f64f92848..ea66a40d570 100644
--- a/ace/Object_Manager.h
+++ b/ace/Object_Manager.h
@@ -48,8 +48,6 @@ class ACE_Export ACE_Object_Manager
// is likely to change, without providing backward capability.
{
public:
- typedef void (*ACE_CLEANUP_FUNC)(void *object, void *param) /* throw () */;
-
static int at_exit (void *object,
ACE_CLEANUP_FUNC cleanup_hook,
void *param);
@@ -74,28 +72,14 @@ public:
#endif /* 0 */
private:
- // typedef void (*ACE_CONSTRUCT_FUNC)(void *object, void *param);
- // not currently used:
-
static ACE_Object_Manager *instance_;
// Singleton pointer.
-public:
- // For template instantiation, with some compilers that need the
- // struct definition to be public.
- typedef struct object_info
- {
- void *object_;
- ACE_CLEANUP_FUNC cleanup_hook_;
- void *param_;
- } object_info_t;
-
-private:
-
- ACE_Unbounded_Queue<object_info_t> *registered_objects_;
+ ACE_Unbounded_Queue<ACE_Cleanup_Info> *registered_objects_;
// Keeps track of all the registered objects.
- int shutting_down_; // Non-zero if this being destroyed
+ int shutting_down_;
+ // Non-zero if this being destroyed
static ACE_Object_Manager *instance (void);
// Accessor to singleton instance. Because static member functions
diff --git a/ace/Task.cpp b/ace/Task.cpp
index 3ba11b9a36d..034b27f1911 100644
--- a/ace/Task.cpp
+++ b/ace/Task.cpp
@@ -121,6 +121,18 @@ ACE_Task_Base::activate (long flags,
#endif /* ACE_MT_SAFE */
}
+void
+ACE_Task_Base::cleanup (void *object, void *)
+{
+ ACE_Task_Base *t = (ACE_Task_Base *) object;
+
+ // The thread count must be decremented first in case the <close>
+ // hook does something crazy like "delete this".
+ t->thr_count_dec ();
+ // @@ Is it possible to pass in the exit status somehow?
+ t->close ();
+}
+
void *
ACE_Task_Base::svc_run (void *args)
{
@@ -128,6 +140,8 @@ ACE_Task_Base::svc_run (void *args)
ACE_Task_Base *t = (ACE_Task_Base *) args;
+ t->thr_mgr ()->at_exit (t, ACE_Task_Base::cleanup, 0);
+
// Call the Task's svc() hook method.
return (void *) t->svc ();
diff --git a/ace/Task.h b/ace/Task.h
index e3a76861d63..905a215f85a 100644
--- a/ace/Task.h
+++ b/ace/Task.h
@@ -164,6 +164,10 @@ public:
// Routine that runs the service routine as a daemon thread.
static void *svc_run (void *);
+ static void cleanup (void *object, void *params);
+ // Cleanup hook that is called when a thread exits to gracefully
+ // shutdown an <ACE_Task>.
+
// = Internal data (should be private...).
// private:
diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp
index 97f4ce6cb49..79c19e73b42 100644
--- a/ace/Thread_Manager.cpp
+++ b/ace/Thread_Manager.cpp
@@ -37,6 +37,19 @@ ACE_Thread_Manager::dump (void) const
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->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
{
@@ -343,13 +356,6 @@ ACE_Thread_Exit::status (void)
ACE_Thread_Exit::~ACE_Thread_Exit (void)
{
ACE_TRACE ("ACE_Thread_Exit::~ACE_Thread_Exit");
-
-#if 0
- // The thread count must be decremented first in case the <close>
- // hook does something crazy like "delete this".
- this->t_->thr_count_dec ();
- this->t_->close (u_long (this->status_));
-#endif /* 0 */
}
// Run the entry point for thread spawned under the control of the
@@ -665,6 +671,18 @@ ACE_Thread_Manager::insert_thr (ACE_thread_t t_id,
return grp_id;
}
+// Run the registered hooks when the thread exits.
+
+void
+ACE_Thread_Manager::run_thread_exit_hooks (int i)
+{
+ ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks");
+
+ (*this->thr_table_[i].cleanup_info_.cleanup_hook_)
+ (this->thr_table_[i].cleanup_info_.object_,
+ this->thr_table_[i].cleanup_info_.param_);
+}
+
// Remove a thread from the pool. Must be called with locks held.
void
@@ -1026,6 +1044,20 @@ ACE_Thread_Manager::wait_grp (int grp_id)
return result;
}
+int
+ACE_Thread_Manager::at_exit (void *object,
+ ACE_CLEANUP_FUNC cleanup_hook,
+ void *param)
+{
+ // 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.
@@ -1035,11 +1067,17 @@ ACE_Thread_Manager::exit (void *status, int do_thr_exit)
ACE_TRACE ("ACE_Thread_Manager::exit");
ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
+ // Locate thread id.
int i = this->find_thread (ACE_Thread::self ());
- // Locate thread id.
if (i != -1)
- this->remove_thr (i);
+ {
+ // Run all the exit hooks.
+ this->run_thread_exit_hooks (i);
+
+ // Remove thread descriptor from the table.
+ this->remove_thr (i);
+ }
if (do_thr_exit)
{
diff --git a/ace/Thread_Manager.h b/ace/Thread_Manager.h
index 7413eb39997..5ed510c68d6 100644
--- a/ace/Thread_Manager.h
+++ b/ace/Thread_Manager.h
@@ -53,8 +53,20 @@ public:
void dump (void) const;
// Dump the state of an object.
-private:
+ int at_exit (void *object,
+ ACE_CLEANUP_FUNC cleanup_hook,
+ void *param);
+ // Register an object (or array) for cleanup at thread termination.
+ // "cleanup_hook" points to a (global, or static member) function
+ // that is called for the object or array when it to be destroyed.
+ // It may perform any necessary cleanup specific for that object or
+ // its class. "param" is passed as the second parameter to the
+ // "cleanup_hook" function; the first parameter is the object (or
+ // array) to be destroyed. Returns 0 on success, non-zero on
+ // failure: -1 if virtual memory is exhausted or 1 if the object (or
+ // arrayt) had already been registered.
+private:
ACE_thread_t thr_id_;
// Unique thread ID.
@@ -66,6 +78,11 @@ private:
ACE_Thread_State thr_state_;
// Current state of the thread.
+
+ ACE_Cleanup_Info cleanup_info_;
+ // Stores the cleanup info for a thread.
+ // @@ Note, this should be generalized to be a stack of
+ // <ACE_Cleanup_Info>s.
};
// Forward declaration.
@@ -282,6 +299,18 @@ public:
int set_grp (ACE_Task_Base *task, int grp_id);
int get_grp (ACE_Task_Base *task, int &grp_id);
+ int at_exit (void *object,
+ ACE_CLEANUP_FUNC cleanup_hook,
+ void *param);
+ // Register an object (or array) for cleanup at thread termination.
+ // "cleanup_hook" points to a (global, or static member) function
+ // that is called for the object or array when it to be destroyed.
+ // It may perform any necessary cleanup specific for that object or
+ // its class. "param" is passed as the second parameter to the
+ // "cleanup_hook" function; the first parameter is the object (or
+ // array) to be destroyed. "cleanup_hook", for example, may delete
+ // the object (or array).
+
void dump (void) const;
// Dump the state of an object.
@@ -301,7 +330,9 @@ protected:
ACE_Task_Base *task = 0);
// Create a new thread (must be called with locks held).
-protected:
+ void run_thread_exit_hooks (int i);
+ // Run the registered hooks when the thread exits.
+
int resize (size_t);
// Resize the pool of Thread_Descriptors.