1 #include "ace/OS_Thread_Adapter.h"
3 #include "ace/Thread_Hook.h"
4 #include "ace/Object_Manager_Base.h"
5 #include "ace/Global_Macros.h"
6 #include "ace/OS_NS_Thread.h"
8 #if defined (ACE_HAS_ALLOC_HOOKS)
9 # include "ace/Malloc_Base.h"
10 #endif /* ACE_HAS_ALLOC_HOOKS */
12 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
14 ACE_OS_Thread_Adapter::ACE_OS_Thread_Adapter (
15 ACE_THR_FUNC user_func
17 , ACE_THR_C_FUNC entry_point
18 #if defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
19 , ACE_SEH_EXCEPT_HANDLER selector
20 , ACE_SEH_EXCEPT_HANDLER handler
21 #endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
24 : ACE_Base_Thread_Adapter (user_func
, arg
, entry_point
26 #if defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
29 #endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
35 ACE_OS_Thread_Adapter::~ACE_OS_Thread_Adapter ()
39 ACE_ALLOC_HOOK_DEFINE(ACE_OS_Thread_Adapter
)
42 ACE_OS_Thread_Adapter::invoke ()
44 // Inherit the logging features if the parent thread has an
45 // ACE_Log_Msg instance in thread-specific storage.
46 this->inherit_log_msg ();
48 // Extract the arguments.
49 ACE_THR_FUNC_INTERNAL func
=
50 reinterpret_cast<ACE_THR_FUNC_INTERNAL
> (this->user_func_
);
51 void *arg
= this->arg_
;
53 // Pick up the cancel-related flags before deleting this.
54 long cancel_flags
= this->flags_
;
56 // Delete ourselves since we don't need <this> anymore. Make sure
57 // not to access <this> anywhere below this point.
60 if (cancel_flags
!= 0)
62 // If both flags are set, ignore this.
64 int val
= cancel_flags
& (THR_CANCEL_ENABLE
| THR_CANCEL_DISABLE
);
65 if (val
== THR_CANCEL_ENABLE
|| val
== THR_CANCEL_DISABLE
)
66 ACE_OS::thr_setcancelstate (val
, &old
);
67 val
= cancel_flags
& (THR_CANCEL_DEFERRED
| THR_CANCEL_ASYNCHRONOUS
);
68 if (val
== THR_CANCEL_DEFERRED
|| val
== THR_CANCEL_ASYNCHRONOUS
)
69 ACE_OS::thr_setcanceltype (val
, &old
);
72 ACE_THR_FUNC_RETURN status
= 0;
78 ACE_Thread_Hook
*hook
=
79 ACE_OS_Object_Manager::thread_hook ();
82 // Invoke the start hook to give the user a chance to
83 // perform some initialization processing before the
85 status
= hook
->start (reinterpret_cast<ACE_THR_FUNC
> (func
),
89 // Call thread entry point.
90 status
= (*func
) (arg
);
94 #if defined (ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS)
95 ACE_SEH_EXCEPT (ACE_OS_Object_Manager::seh_except_selector ()(
96 (void *) GetExceptionInformation ()))
98 ACE_OS_Object_Manager::seh_except_handler ()(0);
100 #endif /* ACE_HAS_WIN32_STRUCTURED_EXCEPTIONS */
105 // If we changed this to 1, change the respective if in
106 // Task::svc_run to 0.
108 // Call the <Task->close> hook.
109 if (func
== reinterpret_cast<ACE_THR_FUNC_INTERNAL
> (ACE_Task_Base::svc_run
))
111 ACE_Task_Base
*task_ptr
= (ACE_Task_Base
*) arg
;
112 ACE_Thread_Manager
*thr_mgr_ptr
= task_ptr
->thr_mgr ();
114 // This calls the Task->close () hook.
115 task_ptr
->cleanup (task_ptr
, 0);
117 // This prevents a second invocation of the cleanup code
118 // (called later by <ACE_Thread_Manager::exit>.
119 thr_mgr_ptr
->at_exit (task_ptr
, 0, 0);
123 #if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION)
124 // Call TSS destructors.
125 ACE_OS::cleanup_tss (0 /* not main thread */);
127 # if defined (ACE_WIN32)
128 // Exit the thread. Allow CWinThread-destructor to be invoked
129 // from AfxEndThread. _endthreadex will be called from
130 // AfxEndThread so don't exit the thread now if we are running
132 # if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
133 // Not spawned by ACE_Thread_Manager, use the old buggy
134 // version. You should seriously consider using
135 // ACE_Thread_Manager to spawn threads. The following code
136 // is know to cause some problem.
137 CWinThread
*pThread
= ::AfxGetThread ();
139 if (!pThread
|| pThread
->m_nThreadID
!= ACE_OS::thr_self ())
140 ACE_ENDTHREADEX (status
);
142 ::AfxEndThread (status
);
144 ACE_ENDTHREADEX (status
);
145 # endif /* ACE_HAS_MFC && ACE_HAS_MFS != 0*/
146 # endif /* ACE_WIN32 */
147 #endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION */
153 ACE_END_VERSIONED_NAMESPACE_DECL