#include <Thread_Adapter.h>
Inheritance diagram for ACE_Thread_Adapter:
Public Member Functions | |
ACE_Thread_Adapter (ACE_THR_FUNC user_func, void *arg, ACE_THR_C_FUNC entry_point=(ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME, ACE_Thread_Manager *thr_mgr=0, ACE_Thread_Descriptor *td=0) | |
Constructor. | |
virtual ACE_THR_FUNC_RETURN | invoke (void) |
ACE_Thread_Manager * | thr_mgr (void) |
Accessor for the optional ACE_Thread_Manager. | |
Protected Member Functions | |
~ACE_Thread_Adapter (void) | |
Ensure that this object must be allocated on the heap. | |
Private Member Functions | |
virtual ACE_THR_FUNC_RETURN | invoke_i (void) |
Private Attributes | |
ACE_Thread_Manager * | thr_mgr_ |
Optional thread manager. |
This class is used in ACE_OS::thr_create(). In general, the thread that creates an object of this class is different from the thread that calls invoke()
on this object. Therefore, the invoke()
method is responsible for deleting itself.
Definition at line 46 of file Thread_Adapter.h.
ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_Thread_Adapter::ACE_Thread_Adapter | ( | ACE_THR_FUNC | user_func, | |
void * | arg, | |||
ACE_THR_C_FUNC | entry_point = (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME , |
|||
ACE_Thread_Manager * | thr_mgr = 0 , |
|||
ACE_Thread_Descriptor * | td = 0 | |||
) |
Constructor.
Definition at line 20 of file Thread_Adapter.cpp.
References ACE_OS_TRACE.
00030 : ACE_Base_Thread_Adapter ( 00031 user_func 00032 , arg 00033 , entry_point 00034 , td 00035 #if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) 00036 , selector 00037 , handler 00038 #endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ 00039 ) 00040 , thr_mgr_ (tm) 00041 { 00042 ACE_OS_TRACE ("ACE_Thread_Adapter::ACE_Thread_Adapter"); 00043 }
ACE_Thread_Adapter::~ACE_Thread_Adapter | ( | void | ) | [protected] |
Ensure that this object must be allocated on the heap.
Definition at line 45 of file Thread_Adapter.cpp.
ACE_THR_FUNC_RETURN ACE_Thread_Adapter::invoke | ( | void | ) | [virtual] |
Execute the <user_func_> with the <arg>. This function deletes this
, thereby rendering the object useless after the call returns.
Implements ACE_Base_Thread_Adapter.
Definition at line 50 of file Thread_Adapter.cpp.
References ACE_Service_Config::current(), ACE_Service_Config::global(), ACE_Base_Thread_Adapter::inherit_log_msg(), ACE_Thread_Exit_Maybe::instance(), ACE_Thread_Exit::instance(), invoke_i(), and ACE_Thread_Exit::thr_mgr().
00051 { 00052 // Inherit the logging features if the parent thread has an 00053 // ACE_Log_Msg instance in thread-specific storage. 00054 this->inherit_log_msg (); 00055 00056 ACE_Service_Config::current (ACE_Service_Config::global()); 00057 00058 #if !defined(ACE_USE_THREAD_MANAGER_ADAPTER) 00059 // NOTE: this preprocessor directive should match the one in above 00060 // ACE_Thread_Exit::instance (). With the Xavier Pthreads package, 00061 // the exit_hook in TSS causes a seg fault. So, this works around 00062 // that by creating exit_hook on the stack. 00063 # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION) 00064 // Obtain our thread-specific exit hook and make sure that it knows 00065 // how to clean us up! Note that we never use this pointer directly 00066 // (it's stored in thread-specific storage), so it's ok to 00067 // dereference it here and only store it as a reference. 00068 00069 // Except if it is null, then the thr_mgr() method crashes. 00070 // -jxh 00071 00072 ACE_Thread_Exit *exit_hook_instance = ACE_Thread_Exit::instance (); 00073 ACE_Thread_Exit_Maybe exit_hook_maybe (exit_hook_instance == 0); 00074 ACE_Thread_Exit *exit_hook_ptr = exit_hook_instance 00075 ? exit_hook_instance 00076 : exit_hook_maybe.instance (); 00077 ACE_Thread_Exit &exit_hook = *exit_hook_ptr; 00078 00079 if (this->thr_mgr () != 0) 00080 { 00081 // Keep track of the <Thread_Manager> that's associated with this 00082 // <exit_hook>. 00083 exit_hook.thr_mgr (this->thr_mgr ()); 00084 } 00085 # else 00086 // Without TSS, create an <ACE_Thread_Exit> instance. When this 00087 // function returns, its destructor will be called because the 00088 // object goes out of scope. The drawback with this appraoch is 00089 // that the destructor _won't_ get called if <thr_exit> is called. 00090 // So, threads shouldn't exit that way. Instead, they should return 00091 // from <svc>. 00092 ACE_Thread_Exit exit_hook; 00093 exit_hook.thr_mgr (this->thr_mgr ()); 00094 # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */ 00095 00096 #endif /* ! ACE_USE_THREAD_MANAGER_ADAPTER */ 00097 00098 return this->invoke_i (); 00099 }
ACE_THR_FUNC_RETURN ACE_Thread_Adapter::invoke_i | ( | void | ) | [private, virtual] |
Called by invoke, mainly here to separate the SEH stuff because SEH on Win32 doesn't compile with local vars with destructors.
Definition at line 102 of file Thread_Adapter.cpp.
References ACE_BIT_ENABLED, ACE_SEH_EXCEPT, ACE_SEH_FINALLY, ACE_SEH_TRY, ACE_Base_Thread_Adapter::arg_, ACE_Thread_Manager::at_exit(), ACE_Task_Base::cleanup(), ACE_OS::cleanup_tss(), ACE_OS_Thread_Descriptor::flags(), ACE_Thread_Hook::start(), ACE_Task_Base::svc_run(), ACE_Base_Thread_Adapter::thr_desc_, ACE_OS::thr_getprio(), ACE_Task_Base::thr_mgr(), ACE_OS::thr_self(), ACE_OS::thr_setprio(), ACE_OS_Object_Manager::thread_hook(), and ACE_Base_Thread_Adapter::user_func_.
Referenced by invoke().
00103 { 00104 // Extract the arguments. 00105 ACE_THR_FUNC func = reinterpret_cast<ACE_THR_FUNC> (this->user_func_); 00106 void *arg = this->arg_; 00107 00108 #if defined (ACE_WIN32) && defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0) 00109 ACE_OS_Thread_Descriptor *thr_desc = this->thr_desc_; 00110 #endif /* ACE_WIN32 && ACE_HAS_MFC && (ACE_HAS_MFC != 0) */ 00111 00112 // Delete ourselves since we don't need <this> anymore. Make sure 00113 // not to access <this> anywhere below this point. 00114 delete this; 00115 00116 #if defined (ACE_NEEDS_LWP_PRIO_SET) 00117 // On SunOS, the LWP priority needs to be set in order to get 00118 // preemption when running in the RT class. This is the ACE way to 00119 // do that . . . 00120 ACE_hthread_t thr_handle; 00121 ACE_OS::thr_self (thr_handle); 00122 int prio; 00123 00124 // thr_getprio () on the current thread should never fail. 00125 ACE_OS::thr_getprio (thr_handle, prio); 00126 00127 // ACE_OS::thr_setprio () has the special logic to set the LWP priority, 00128 // if running in the RT class. 00129 ACE_OS::thr_setprio (prio); 00130 00131 #endif /* ACE_NEEDS_LWP_PRIO_SET */ 00132 00133 ACE_THR_FUNC_RETURN status = 0; 00134 00135 ACE_SEH_TRY 00136 { 00137 ACE_SEH_TRY 00138 { 00139 ACE_Thread_Hook *hook = 00140 ACE_OS_Object_Manager::thread_hook (); 00141 00142 if (hook) 00143 // Invoke the start hook to give the user a chance to 00144 // perform some initialization processing before the 00145 // <func> is invoked. 00146 status = hook->start (func, arg); 00147 else 00148 // Call thread entry point. 00149 status = (*func) (arg); 00150 } 00151 00152 #if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) 00153 ACE_SEH_EXCEPT (ACE_OS_Object_Manager::seh_except_selector ()( 00154 (void *) GetExceptionInformation ())) 00155 { 00156 ACE_OS_Object_Manager::seh_except_handler ()(0); 00157 } 00158 #endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ 00159 } 00160 00161 ACE_SEH_FINALLY 00162 { 00163 // If we changed this to 1, change the respective if in 00164 // Task::svc_run to 0. 00165 #if 0 00166 // Call the <Task->close> hook. 00167 if (func == reinterpret_cast<ACE_THR_FUNC_INTERNAL> ( 00168 ACE_Task_Base::svc_run)) 00169 { 00170 ACE_Task_Base *task_ptr = (ACE_Task_Base *) arg; 00171 ACE_Thread_Manager *thr_mgr_ptr = task_ptr->thr_mgr (); 00172 00173 // This calls the Task->close () hook. 00174 task_ptr->cleanup (task_ptr, 0); 00175 00176 // This prevents a second invocation of the cleanup code 00177 // (called later by <ACE_Thread_Manager::exit>. 00178 thr_mgr_ptr->at_exit (task_ptr, 0, 0); 00179 } 00180 #endif /* 0 */ 00181 00182 #if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) 00183 # if defined (ACE_WIN32) && defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0) 00184 int using_afx = -1; 00185 if (thr_desc) 00186 using_afx = ACE_BIT_ENABLED (thr_desc->flags (), THR_USE_AFX); 00187 # endif /* ACE_WIN32 && ACE_HAS_MFC && (ACE_HAS_MFC != 0) */ 00188 // Call TSS destructors. 00189 ACE_OS::cleanup_tss (0 /* not main thread */); 00190 00191 # if defined (ACE_WIN32) 00192 // Exit the thread. Allow CWinThread-destructor to be invoked 00193 // from AfxEndThread. _endthreadex will be called from 00194 // AfxEndThread so don't exit the thread now if we are running 00195 // an MFC thread. 00196 # if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0) 00197 if (using_afx != -1) 00198 { 00199 if (using_afx) 00200 ::AfxEndThread ((DWORD) status); 00201 else 00202 ACE_ENDTHREADEX (status); 00203 } 00204 else 00205 { 00206 // Not spawned by ACE_Thread_Manager, use the old buggy 00207 // version. You should seriously consider using 00208 // ACE_Thread_Manager to spawn threads. The following code 00209 // is know to cause some problem. 00210 CWinThread *pThread = ::AfxGetThread (); 00211 00212 if (!pThread || pThread->m_nThreadID != ACE_OS::thr_self ()) 00213 ACE_ENDTHREADEX (status); 00214 else 00215 ::AfxEndThread ((DWORD)status); 00216 } 00217 # else 00218 00219 ACE_ENDTHREADEX (status); 00220 # endif /* ACE_HAS_MFC && ACE_HAS_MFS != 0*/ 00221 # endif /* ACE_WIN32 */ 00222 #endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION */ 00223 } 00224 00225 return status; 00226 }
ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE ACE_Thread_Manager * ACE_Thread_Adapter::thr_mgr | ( | void | ) |
Accessor for the optional ACE_Thread_Manager.
Definition at line 8 of file Thread_Adapter.inl.
References thr_mgr_.
00009 { 00010 return this->thr_mgr_; 00011 }
ACE_Thread_Manager* ACE_Thread_Adapter::thr_mgr_ [private] |