#include "ace/OS_Thread_Adapter.h" #include "ace/Thread_Hook.h" #include "ace/Object_Manager_Base.h" #include "ace/Global_Macros.h" #include "ace/OS_NS_Thread.h" #if defined (ACE_HAS_ALLOC_HOOKS) # include "ace/Malloc_Base.h" #endif /* ACE_HAS_ALLOC_HOOKS */ ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_OS_Thread_Adapter::ACE_OS_Thread_Adapter ( ACE_THR_FUNC user_func , void *arg , ACE_THR_C_FUNC entry_point #if defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS) , ACE_SEH_EXCEPT_HANDLER selector , ACE_SEH_EXCEPT_HANDLER handler #endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */ , long cancel_flags ) : ACE_Base_Thread_Adapter (user_func, arg, entry_point , 0 #if defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS) , selector , handler #endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */ , cancel_flags ) { } ACE_OS_Thread_Adapter::~ACE_OS_Thread_Adapter () { } ACE_ALLOC_HOOK_DEFINE(ACE_OS_Thread_Adapter) ACE_THR_FUNC_RETURN ACE_OS_Thread_Adapter::invoke () { // Inherit the logging features if the parent thread has an // ACE_Log_Msg instance in thread-specific storage. this->inherit_log_msg (); // Extract the arguments. ACE_THR_FUNC_INTERNAL func = reinterpret_cast (this->user_func_); void *arg = this->arg_; // Pick up the cancel-related flags before deleting this. long cancel_flags = this->flags_; // Delete ourselves since we don't need anymore. Make sure // not to access anywhere below this point. delete this; if (cancel_flags != 0) { // If both flags are set, ignore this. int old = 0; int val = cancel_flags & (THR_CANCEL_ENABLE | THR_CANCEL_DISABLE); if (val == THR_CANCEL_ENABLE || val == THR_CANCEL_DISABLE) ACE_OS::thr_setcancelstate (val, &old); val = cancel_flags & (THR_CANCEL_DEFERRED | THR_CANCEL_ASYNCHRONOUS); if (val == THR_CANCEL_DEFERRED || val == THR_CANCEL_ASYNCHRONOUS) ACE_OS::thr_setcanceltype (val, &old); } ACE_THR_FUNC_RETURN 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 // is invoked. status = hook->start (reinterpret_cast (func), arg); else { // Call thread entry point. status = (*func) (arg); } } #if defined (ACE_HAS_WIN32_STRUCTURED_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_STRUCTURED_EXCEPTIONS */ } ACE_SEH_FINALLY { // If we changed this to 1, change the respective if in // Task::svc_run to 0. #if 0 // Call the close> hook. if (func == reinterpret_cast (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 . thr_mgr_ptr->at_exit (task_ptr, 0, 0); } #endif /* 0 */ #if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) // 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) // 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 (status); # else ACE_ENDTHREADEX (status); # endif /* ACE_HAS_MFC && ACE_HAS_MFS != 0*/ # endif /* ACE_WIN32 */ #endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION */ } return status; } ACE_END_VERSIONED_NAMESPACE_DECL