1 /*******************************************************************************
2 * File Name : HLH_Thread.cpp
5 * Created Time : 2009-10-8 11:18:18
7 ******************************************************************************/
10 /*******************************************************************************
11 * Desc : Includes Files
12 ******************************************************************************/
17 #include "utils/HLH_Thread.h"
21 /*******************************************************************************
22 * Desc : Macro Definations
23 ******************************************************************************/
26 /*******************************************************************************
27 * Desc : Type Definations
28 ******************************************************************************/
31 /*******************************************************************************
32 * Desc : Global Variables
33 ******************************************************************************/
36 /*******************************************************************************
37 * Desc : File Variables
38 ******************************************************************************/
44 /******************************************************************************
45 * Desc : Member Functions
46 ******************************************************************************/
51 /******************************************************************************
52 * Func : HLH_Thread::HLH_Thread
53 * Desc : Constructor of HLH_Thread
56 ******************************************************************************/
57 HLH_Thread::HLH_Thread ()
59 m_zhmRunMutex
.Init ();
60 m_zhmContinueMutex
.Init ();
61 m_zhmContinueMutex2
.Init ();
69 /******************************************************************************
70 * Func : HLH_Thread::~HLH_Thread
71 * Desc : Deconstructor of HLH_Thread
74 ******************************************************************************/
75 HLH_Thread::~HLH_Thread ()
81 /******************************************************************************
82 * Func : HLH_Thread::Start
83 * Desc : Start a thread calling \c ztfThreadFunc (pvThreadParam)
84 * Args : ztfThreadFunc Function called in this thread
85 * Outs : If success return 0, otherwise return error code.
86 ******************************************************************************/
87 int HLH_Thread::Start (ThreadFunc ztfThreadFunc
, void *pvThreadParam
)
91 // Force TheThread () to wait before call m_ztfThreadFunc ():
92 // TheThread () will set m_bRunning
93 // and wait Start () to confirm before it call m_ztfThreadFunc ()
94 m_zhmContinueMutex
.Lock ();
96 // Check if already running
97 m_zhmRunMutex
.Lock ();
99 m_zhmRunMutex
.Unlock ();
100 return HLH_THREAD_ERR_ALREADY_RUNNING
;
102 m_zhmRunMutex
.Unlock ();
104 // Set Thread Function
105 m_ztfThreadFunc
= ztfThreadFunc
;
106 m_pvThreadParam
= pvThreadParam
;
109 pthread_attr_init (&attr
);
110 pthread_attr_setdetachstate (&attr
,PTHREAD_CREATE_DETACHED
);
112 nRetval
= pthread_create (&m_zpThreadId
, &attr
, TheThread
, this);
113 pthread_attr_destroy (&attr
);
115 m_zhmContinueMutex
.Unlock ();
116 return HLH_THREAD_ERR_CANT_START_THREAD
;
119 /* Wait until 'm_bRunning' is set */
121 m_zhmRunMutex
.Lock ();
124 m_zhmRunMutex
.Unlock ();
126 struct timespec tsReq
;
127 struct timespec tsRem
;
130 tsReq
.tv_nsec
= 1000000;
131 nanosleep (&tsReq
, &tsRem
);
133 m_zhmRunMutex
.Lock();
135 m_zhmRunMutex
.Unlock();
137 // Unlock to let TheThread () continue and call m_ztfThreadFunc ()
138 m_zhmContinueMutex
.Unlock();
140 // Make sure that m_ztfThreadFunc () has call ThreadStarted ()
141 m_zhmContinueMutex2
.Lock();
142 m_zhmContinueMutex2
.Unlock();
148 /******************************************************************************
149 * Func : HLH_Thread::Stop
150 * Desc : Stop this thread
152 * Outs : If success return 0, otherwise return error code
153 ******************************************************************************/
154 int HLH_Thread::Stop ()
156 struct timespec tsReq
;
157 struct timespec tsRem
;
160 m_zhmRunMutex
.Lock ();
162 // If the thread isn't running, abort
165 m_zhmRunMutex
.Unlock();
166 return HLH_THREAD_ERR_NOT_RUNNING
;
170 m_zhmRunMutex
.Unlock();
171 return HLH_THREAD_ERR_ALREADY_STOPPING
;
174 // Send stop request to m_ztfThreadFunc ()
177 m_zhmRunMutex
.Unlock ();
179 // Wait until 'm_bRunning' is unset
181 m_zhmRunMutex
.Lock ();
184 m_zhmRunMutex
.Unlock ();
187 tsReq
.tv_nsec
= 1000000;
190 nanosleep (&tsReq
, &tsRem
);
192 m_zhmRunMutex
.Lock ();
194 m_zhmRunMutex
.Unlock ();
199 /******************************************************************************
200 * Func : HLH_Thread::Kill
201 * Desc : Kill this thread
203 * Outs : If success return 0, otherwise return error code.
204 ******************************************************************************/
205 int HLH_Thread::Kill ()
207 m_zhmRunMutex
.Lock ();
211 m_zhmRunMutex
.Unlock();
212 return HLH_THREAD_ERR_NOT_RUNNING
;
215 pthread_cancel (m_zpThreadId
);
221 m_zhmRunMutex
.Unlock();
226 /******************************************************************************
227 * Func : HLH_Thread::IsRunning
228 * Desc : Whether this thread is running
230 * Outs : If running return true, otherwise return false.
231 ******************************************************************************/
232 bool HLH_Thread::IsRunning ()
236 m_zhmRunMutex
.Lock();
237 bRunning
= m_bRunning
;
238 m_zhmRunMutex
.Unlock();
244 /******************************************************************************
245 * Func : HLH_Thread::IsStopping
246 * Desc : Whether this thread is requested to stop
248 * Outs : If requested to stop return true, otherwise return false
249 ******************************************************************************/
250 bool HLH_Thread::IsStopping ()
254 m_zhmRunMutex
.Lock();
255 bStopping
= m_bStopping
;
256 m_zhmRunMutex
.Unlock();
262 /******************************************************************************
263 * Func : HLH_Thread::GetReturnValue
264 * Desc : Get return value of this thread
266 * Outs : return return value of this thread in last run
267 ******************************************************************************/
268 void * HLH_Thread::GetReturnValue ()
272 m_zhmRunMutex
.Lock ();
274 m_zhmRunMutex
.Unlock ();
279 /******************************************************************************
280 * Func : HLH_Thread::TheThread
281 * Desc : Thread callback function of this thread
282 * Args : pvThis pointer to this instance
283 * Outs : Always return NULL.
284 ******************************************************************************/
285 void * HLH_Thread::TheThread (void *pvThis
)
287 HLH_Thread
*pzhThread
;
290 ASSERT (pvThis
!= NULL
);
291 pzhThread
= (HLH_Thread
*)pvThis
;
293 pzhThread
->m_zhmContinueMutex2
.Lock ();
295 // Identify that this thread is running
296 pzhThread
->m_zhmRunMutex
.Lock ();
297 pzhThread
->m_bRunning
= true;
298 pzhThread
->m_bStopping
= false;
299 pzhThread
->m_zhmRunMutex
.Unlock ();
301 // Wait until Start () confirm that m_bRunning is set
302 pzhThread
->m_zhmContinueMutex
.Lock ();
303 pzhThread
->m_zhmContinueMutex
.Unlock ();
305 // pzhThread->m_zhmContinueMutex2 will be unlock here
306 pvRet
= pzhThread
->m_ztfThreadFunc ( *pzhThread
, pzhThread
->m_pvThreadParam
);
308 // Identify that this thread is stopped
309 pzhThread
->m_zhmRunMutex
.Lock ();
310 pzhThread
->m_bRunning
= false;
311 pzhThread
->m_bStopping
= false;
312 pzhThread
->m_pvRetval
= pvRet
;
313 pzhThread
->m_zhmRunMutex
.Unlock ();
318 /******************************************************************************
319 * Func : HLH_Thread::ThreadStarted
320 * Desc : Called by m_ztfThreadFunc () to notify \c Start ()
321 * that \c m_ztfThreadFunc () started
324 ******************************************************************************/
325 void HLH_Thread::ThreadStarted ()
327 m_zhmContinueMutex2
.Unlock ();