summaryrefslogtreecommitdiff
path: root/ace/Thread_Adapter.cpp
diff options
context:
space:
mode:
authorcoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-08-25 23:27:19 +0000
committercoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-08-25 23:27:19 +0000
commit07641bf3bda79873da15bd4c551806f230213d43 (patch)
tree93c1a7ae2cbb60ad88b4a06ce9b0bd9a41639279 /ace/Thread_Adapter.cpp
parent2ecfe972ecdaf8e8f5807f22d55c060efe837712 (diff)
downloadATCD-07641bf3bda79873da15bd4c551806f230213d43.tar.gz
ChangeLogTag:Fri Aug 25 16:15:50 2000 Carlos O'Ryan <coryan@uci.edu>
Diffstat (limited to 'ace/Thread_Adapter.cpp')
-rw-r--r--ace/Thread_Adapter.cpp239
1 files changed, 239 insertions, 0 deletions
diff --git a/ace/Thread_Adapter.cpp b/ace/Thread_Adapter.cpp
new file mode 100644
index 00000000000..361909a8545
--- /dev/null
+++ b/ace/Thread_Adapter.cpp
@@ -0,0 +1,239 @@
+// $Id$
+
+#include "ace/Thread_Adapter.h"
+#include "ace/Thread_Manager.h"
+#include "ace/Thread_Exit.h"
+#include "ace/Thread_Hook.h"
+
+ACE_RCSID(ace, Thread_Adapter, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/Thread_Adapter.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+ACE_INIT_LOG_MSG_HOOK ACE_Thread_Adapter::init_log_msg_hook_ = 0;
+ACE_INHERIT_LOG_MSG_HOOK ACE_Thread_Adapter::inherit_log_msg_hook_ = 0;
+ACE_CLOSE_LOG_MSG_HOOK ACE_Thread_Adapter::close_log_msg_hook_ = 0;
+ACE_SYNC_LOG_MSG_HOOK ACE_Thread_Adapter::sync_log_msg_hook_ = 0;
+
+void
+ACE_Thread_Adapter::inherit_log_msg (void)
+{
+ if (ACE_Thread_Adapter::inherit_log_msg_hook_ != 0)
+ (*ACE_Thread_Adapter::inherit_log_msg_hook_)(this->thr_desc_,
+ this->log_msg_attributes_);
+}
+
+void
+ACE_Thread_Adapter::close_log_msg (void)
+{
+ if (ACE_Thread_Adapter::close_log_msg_hook_ != 0)
+ {
+ (*ACE_Thread_Adapter::close_log_msg_hook_) ();
+ }
+}
+
+void
+ACE_Thread_Adapter::sync_log_msg (const ACE_TCHAR *prg)
+{
+ if (ACE_Thread_Adapter::sync_log_msg_hook_ != 0)
+ {
+ (*ACE_Thread_Adapter::sync_log_msg_hook_) (prg);
+ }
+}
+
+
+void *
+ACE_Thread_Adapter::invoke (void)
+{
+ // Inherit the logging features if the parent thread has an
+ // ACE_Log_Msg instance in thread-specific storage.
+ this->inherit_log_msg ();
+
+#if !defined(ACE_USE_THREAD_MANAGER_ADAPTER)
+ // 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)
+ // 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.
+ if (this->thr_mgr () != 0)
+ {
+ ACE_Thread_Exit &exit_hook = *ACE_Thread_Exit::instance ();
+ // Keep track of the <Thread_Manager> that's associated with this
+ // <exit_hook>.
+ exit_hook.thr_mgr (this->thr_mgr ());
+ }
+# 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;
+ exit_hook.thr_mgr (this->thr_mgr ());
+# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
+
+#endif /* ! ACE_USE_THREAD_MANAGER_ADAPTER */
+
+ // Extract the arguments.
+ ACE_THR_FUNC_INTERNAL func = ACE_reinterpret_cast (ACE_THR_FUNC_INTERNAL,
+ this->user_func_);
+ void *arg = this->arg_;
+
+#if defined (ACE_WIN32) && defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
+ ACE_OS_Thread_Descriptor *thr_desc = this->thr_desc_;
+#endif /* ACE_WIN32 && ACE_HAS_MFC && (ACE_HAS_MFC != 0) */
+
+ // Delete ourselves since we don't need <this> anymore. Make sure
+ // not to access <this> anywhere below this point.
+ delete this;
+
+#if defined (ACE_NEEDS_LWP_PRIO_SET)
+ // On SunOS, the LWP priority needs to be set in order to get
+ // preemption when running in the RT class. This is the ACE way to
+ // do that . . .
+ ACE_hthread_t thr_handle;
+ ACE_OS::thr_self (thr_handle);
+ int prio;
+
+ // thr_getprio () on the current thread should never fail.
+ ACE_OS::thr_getprio (thr_handle, prio);
+
+ // ACE_OS::thr_setprio () has the special logic to set the LWP priority,
+ // if running in the RT class.
+ ACE_OS::thr_setprio (prio);
+
+#endif /* ACE_NEEDS_LWP_PRIO_SET */
+
+ void *status = 0;
+
+ ACE_SEH_TRY
+ {
+ ACE_SEH_TRY
+ {
+ ACE_Thread_Hook *hook =
+ ACE_OS_Object_Manager::thread_hook ();
+
+ if (hook)
+ // Invoke the start hook to give the user a chance to
+ // perform some initialization processing before the
+ // <func> is invoked.
+ status = hook->start (ACE_reinterpret_cast (ACE_THR_FUNC, func),
+ arg);
+ else
+ {
+ // Call thread entry point.
+#if defined (ACE_PSOS)
+ (*func) (arg);
+#else /* ! ACE_PSOS */
+ status = ACE_reinterpret_cast (void *, (*func) (arg));
+#endif /* ACE_PSOS */
+ }
+#if defined (ACE_PSOS)
+ // pSOS task functions do not return a value.
+ status = 0;
+#endif /* ACE_PSOS */
+ }
+
+#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ ACE_SEH_EXCEPT (ACE_OS_Object_Manager::seh_except_selector ()(
+ (void *) GetExceptionInformation ()))
+ {
+ ACE_OS_Object_Manager::seh_except_handler ()(0);
+ }
+#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+ }
+
+ ACE_SEH_FINALLY
+ {
+ // If we changed this to 1, change the respective if in
+ // Task::svc_run to 0.
+#if 0
+ // Call the <Task->close> hook.
+ if (func == ACE_reinterpret_cast (ACE_THR_FUNC_INTERNAL,
+ ACE_Task_Base::svc_run))
+ {
+ ACE_Task_Base *task_ptr = (ACE_Task_Base *) arg;
+ ACE_Thread_Manager *thr_mgr_ptr = task_ptr->thr_mgr ();
+
+ // This calls the Task->close () hook.
+ task_ptr->cleanup (task_ptr, 0);
+
+ // This prevents a second invocation of the cleanup code
+ // (called later by <ACE_Thread_Manager::exit>.
+ thr_mgr_ptr->at_exit (task_ptr, 0, 0);
+ }
+#endif /* 0 */
+
+#if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION)
+# if defined (ACE_WIN32) && defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
+ int using_afx = -1;
+ if (thr_desc)
+ using_afx = ACE_BIT_ENABLED (thr_desc->flags (), THR_USE_AFX);
+# endif /* ACE_WIN32 && ACE_HAS_MFC && (ACE_HAS_MFC != 0) */
+ // Call TSS destructors.
+ ACE_OS::cleanup_tss (0 /* not main thread */);
+
+# if defined (ACE_WIN32)
+ // Exit the thread. Allow CWinThread-destructor to be invoked
+ // from AfxEndThread. _endthreadex will be called from
+ // AfxEndThread so don't exit the thread now if we are running
+ // an MFC thread.
+# if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
+ if (using_afx != -1)
+ {
+ if (using_afx)
+ ::AfxEndThread ((DWORD) status);
+ else
+ ACE_ENDTHREADEX (status);
+ }
+ else
+ {
+ // Not spawned by ACE_Thread_Manager, use the old buggy
+ // version. You should seriously consider using
+ // ACE_Thread_Manager to spawn threads. The following code
+ // is know to cause some problem.
+ CWinThread *pThread = ::AfxGetThread ();
+
+ if (!pThread || pThread->m_nThreadID != ACE_OS::thr_self ())
+ ACE_ENDTHREADEX (status);
+ else
+ ::AfxEndThread ((DWORD)status);
+ }
+# else
+
+ ACE_ENDTHREADEX (status);
+# endif /* ACE_HAS_MFC && ACE_HAS_MFS != 0*/
+# endif /* ACE_WIN32 */
+#endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION */
+
+#if defined (ACE_PSOS)
+ // This sequence of calls is documented by ISI as the proper way to
+ // clean up a pSOS task. They affect different components, so only
+ // try the ones for components that are built with ACE.
+# if defined (SC_PREPC) && (SC_PREPC == YES)
+ ::fclose (0); // Return pREPC+ resources
+# endif /* SC_PREPC */
+# if defined (SC_PHILE) && (SC_PHILE == YES)
+ ::close_f (0); // Return pHILE+ resources
+# endif /* SC_PHILE */
+# if defined (SC_PNA) && (SC_PNA == YES)
+ ::close (0); // Return pNA+ resources
+# endif /* SC_PNA */
+# if defined (SC_SC_PREPC) && (SC_PREPC == YES)
+ ::free (-1); // Return pREPC+ memory
+# endif /* SC_PREPC */
+ status = ::t_delete (0); // Suicide - only returns on error
+#endif /* ACE_PSOS */
+
+ return status;
+ }
+
+ ACE_NOTREACHED (return status);
+}