00001 
00002 
00003 #include "ace/Thread_Adapter.h"
00004 #include "ace/Thread_Manager.h"
00005 #include "ace/Thread_Exit.h"
00006 #include "ace/Thread_Hook.h"
00007 #include "ace/Object_Manager_Base.h"
00008 
00009 ACE_RCSID (ace,
00010            Thread_Adapter,
00011            "Thread_Adapter.cpp,v 4.17 2006/05/30 13:15:25 schmidt Exp")
00012 
00013 #if !defined (ACE_HAS_INLINED_OSCALLS)
00014 # include "ace/Thread_Adapter.inl"
00015 #endif 
00016 
00017 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00018 
00019 ACE_Thread_Adapter::ACE_Thread_Adapter (ACE_THR_FUNC user_func,
00020                                         void *arg,
00021                                         ACE_THR_C_FUNC entry_point,
00022                                         ACE_Thread_Manager *tm,
00023                                         ACE_Thread_Descriptor *td
00024 #if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
00025                                         , ACE_SEH_EXCEPT_HANDLER selector,
00026                                         ACE_SEH_EXCEPT_HANDLER handler
00027 #endif 
00028                                         )
00029   : ACE_Base_Thread_Adapter (
00030         user_func
00031         , arg
00032         , entry_point
00033         , td
00034 #if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
00035         , selector
00036         , handler
00037 #endif 
00038         )
00039   , thr_mgr_ (tm)
00040 {
00041   ACE_OS_TRACE ("ACE_Thread_Adapter::ACE_Thread_Adapter");
00042 }
00043 
00044 ACE_Thread_Adapter::~ACE_Thread_Adapter (void)
00045 {
00046 }
00047 
00048 ACE_THR_FUNC_RETURN
00049 ACE_Thread_Adapter::invoke (void)
00050 {
00051   
00052   
00053   this->inherit_log_msg ();
00054 
00055 #if !defined(ACE_USE_THREAD_MANAGER_ADAPTER)
00056   
00057   
00058   
00059   
00060 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)
00061   
00062   
00063   
00064   
00065 
00066   
00067   
00068 
00069   ACE_Thread_Exit *exit_hook_instance = ACE_Thread_Exit::instance ();
00070   ACE_Thread_Exit_Maybe exit_hook_maybe (exit_hook_instance == 0);
00071   ACE_Thread_Exit *exit_hook_ptr = exit_hook_instance
00072                                    ? exit_hook_instance
00073                                    : exit_hook_maybe.instance ();
00074   ACE_Thread_Exit &exit_hook = *exit_hook_ptr;
00075 
00076   if (this->thr_mgr () != 0)
00077     {
00078       
00079       
00080       exit_hook.thr_mgr (this->thr_mgr ());
00081     }
00082 # else
00083   
00084   
00085   
00086   
00087   
00088   
00089   ACE_Thread_Exit exit_hook;
00090   exit_hook.thr_mgr (this->thr_mgr ());
00091 # endif 
00092 
00093 #endif 
00094 
00095   return this->invoke_i ();
00096 }
00097 
00098 ACE_THR_FUNC_RETURN
00099 ACE_Thread_Adapter::invoke_i (void)
00100 {
00101   
00102   ACE_THR_FUNC func = reinterpret_cast<ACE_THR_FUNC> (this->user_func_);
00103   void *arg = this->arg_;
00104 
00105 #if defined (ACE_WIN32) && defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
00106   ACE_OS_Thread_Descriptor *thr_desc = this->thr_desc_;
00107 #endif 
00108 
00109   
00110   
00111   delete this;
00112 
00113 #if defined (ACE_NEEDS_LWP_PRIO_SET)
00114   
00115   
00116   
00117   ACE_hthread_t thr_handle;
00118   ACE_OS::thr_self (thr_handle);
00119   int prio;
00120 
00121   
00122   ACE_OS::thr_getprio (thr_handle, prio);
00123 
00124   
00125   
00126   ACE_OS::thr_setprio (prio);
00127 
00128 #endif 
00129 
00130   ACE_THR_FUNC_RETURN status = 0;
00131 
00132   ACE_SEH_TRY
00133     {
00134       ACE_SEH_TRY
00135         {
00136           ACE_Thread_Hook *hook =
00137             ACE_OS_Object_Manager::thread_hook ();
00138 
00139           if (hook)
00140             
00141             
00142             
00143             status = hook->start (func, arg);
00144           else
00145             
00146             status = (*func) (arg);
00147         }
00148 
00149 #if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
00150       ACE_SEH_EXCEPT (ACE_OS_Object_Manager::seh_except_selector ()(
00151                           (void *) GetExceptionInformation ()))
00152         {
00153           ACE_OS_Object_Manager::seh_except_handler ()(0);
00154         }
00155 #endif 
00156     }
00157 
00158   ACE_SEH_FINALLY
00159     {
00160       
00161       
00162 #if 0
00163       
00164       if (func == reinterpret_cast<ACE_THR_FUNC_INTERNAL> (
00165             ACE_Task_Base::svc_run))
00166         {
00167           ACE_Task_Base *task_ptr = (ACE_Task_Base *) arg;
00168           ACE_Thread_Manager *thr_mgr_ptr = task_ptr->thr_mgr ();
00169 
00170           
00171           task_ptr->cleanup (task_ptr, 0);
00172 
00173           
00174           
00175           thr_mgr_ptr->at_exit (task_ptr, 0, 0);
00176         }
00177 #endif 
00178 
00179 #if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION)
00180 # if defined (ACE_WIN32) && defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
00181       int using_afx = -1;
00182       if (thr_desc)
00183         using_afx = ACE_BIT_ENABLED (thr_desc->flags (), THR_USE_AFX);
00184 # endif 
00185           
00186       ACE_OS::cleanup_tss (0 );
00187 
00188 # if defined (ACE_WIN32)
00189       
00190       
00191       
00192       
00193 #   if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
00194       if (using_afx != -1)
00195         {
00196           if (using_afx)
00197             ::AfxEndThread ((DWORD) status);
00198           else
00199             ACE_ENDTHREADEX (status);
00200         }
00201       else
00202         {
00203           
00204           
00205           
00206           
00207           CWinThread *pThread = ::AfxGetThread ();
00208 
00209           if (!pThread || pThread->m_nThreadID != ACE_OS::thr_self ())
00210             ACE_ENDTHREADEX (status);
00211           else
00212             ::AfxEndThread ((DWORD)status);
00213         }
00214 #   else
00215 
00216       ACE_ENDTHREADEX (status);
00217 #   endif 
00218 # endif 
00219 #endif 
00220     }
00221 
00222   return status;
00223 }
00224 
00225 ACE_END_VERSIONED_NAMESPACE_DECL