Converts a C++ function into a function that can be called from a thread creation routine (e.g., pthread_create() or _beginthreadex()) that expects an extern "C" entry point. This class also makes it possible to transparently provide hooks to register a thread with an ACE_Thread_Manager. More...
#include <OS_Thread_Adapter.h>
Public Member Functions | |
ACE_OS_Thread_Adapter (ACE_THR_FUNC user_func, void *arg, ACE_THR_C_FUNC entry_point=(ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME) | |
Constructor. | |
virtual ACE_THR_FUNC_RETURN | invoke (void) |
Protected Member Functions | |
~ACE_OS_Thread_Adapter (void) | |
Ensure that this object is allocated on the heap. |
Converts a C++ function into a function that can be called from a thread creation routine (e.g., pthread_create() or _beginthreadex()) that expects an extern "C" entry point. This class also makes it possible to transparently provide hooks to register a thread with an ACE_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 42 of file OS_Thread_Adapter.h.
ACE_OS_Thread_Adapter::ACE_OS_Thread_Adapter | ( | ACE_THR_FUNC | user_func, | |
void * | arg, | |||
ACE_THR_C_FUNC | entry_point = (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME | |||
) |
Constructor.
ACE_OS_Thread_Adapter::~ACE_OS_Thread_Adapter | ( | void | ) | [protected] |
Ensure that this object is allocated on the heap.
Definition at line 35 of file OS_Thread_Adapter.cpp.
{ }
ACE_THR_FUNC_RETURN ACE_OS_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 40 of file OS_Thread_Adapter.cpp.
{ // 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<ACE_THR_FUNC_INTERNAL> (this->user_func_); void *arg = this->arg_; // 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 */ 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 // <func> is invoked. status = hook->start (reinterpret_cast<ACE_THR_FUNC> (func), arg); else { // Call thread entry point. status = (*func) (arg); } } #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 == 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) // 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; }