diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-08-25 23:27:19 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-08-25 23:27:19 +0000 |
commit | 07641bf3bda79873da15bd4c551806f230213d43 (patch) | |
tree | 93c1a7ae2cbb60ad88b4a06ce9b0bd9a41639279 /ace/Thread_Adapter.cpp | |
parent | 2ecfe972ecdaf8e8f5807f22d55c060efe837712 (diff) | |
download | ATCD-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.cpp | 239 |
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); +} |