summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-12-30 22:17:34 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-12-30 22:17:34 +0000
commit088067b913f11ce3b0ae072d0ebe8a89f9e452c8 (patch)
treeeb3f00008ad0a409d4027c1da4a4e32e90f3c400
parenta482d5d2f78cd1addd55d6d6023446cd2a29aeef (diff)
downloadATCD-088067b913f11ce3b0ae072d0ebe8a89f9e452c8.tar.gz
without TSS, create the ACE_Task_Exit exit_hook on the stack instead of globally, so that its destructor gets called
-rw-r--r--ace/Task.cpp28
1 files changed, 24 insertions, 4 deletions
diff --git a/ace/Task.cpp b/ace/Task.cpp
index a1217fff683..65e83ef10bf 100644
--- a/ace/Task.cpp
+++ b/ace/Task.cpp
@@ -15,6 +15,10 @@
ACE_Thread_Mutex ACE_Task_Exit::ace_task_lock_;
#endif /* defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */
+// NOTE: this preprocessor directive should match the one in
+// ACE_Task_Base::svc_run () below. This prevents the two statics
+// from being defined.
+#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) && ! defined (LINUX)
ACE_Task_Exit *
ACE_Task_Exit::instance (void)
{
@@ -42,6 +46,8 @@ ACE_Task_Exit::instance (void)
return ACE_TSS_GET (instance_, ACE_Task_Exit);
}
+#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE && ! LINUX */
+
// Grab hold of the Task * so that we can close() it in the
// destructor.
@@ -219,16 +225,30 @@ ACE_Task_Base::svc_run (void *args)
ACE_Task_Base *t = (ACE_Task_Base *) args;
+// NOTE: this preprocessor directive should match the one in
+// above ACE_Task_Exit::instance ().
+#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) && ! defined (LINUX)
// Obtain our thread-specific exit hook and make sure that it knows
- // how to clean us up!
- ACE_Task_Exit *exit_hook = ACE_Task_Exit::instance ();
+ // 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_Task_Exit &exit_hook = *ACE_Task_Exit::instance ();
+#else
+ // Without TSS, create an ACE_Task_Exit instance. When this
+ // function returns, its destructor will be call 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_Task_Exit exit_hook;
+#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
- exit_hook->set_task (t);
+ exit_hook.set_task (t);
// Call the Task's svc() method.
void *status = (void *) t->svc ();
- return exit_hook->status (status);
+ return exit_hook.status (status);
/* NOTREACHED */
}