1 // license: public domain
2 // authors: jonas.sundstrom@kirilla.com
5 #include "GenericThread.h"
10 GenericThread::GenericThread(const char* threadName
, int32 priority
,
13 fThreadDataStore(message
),
14 fThreadId(spawn_thread(private_thread_function
, threadName
, priority
,
16 fExecuteUnit(create_sem(1, "ExecuteUnit sem")),
17 fQuitRequested(false),
18 fThreadIsPaused(false)
20 if (fThreadDataStore
== NULL
)
21 fThreadDataStore
= new BMessage();
25 GenericThread::~GenericThread()
27 kill_thread(fThreadId
);
29 delete_sem(fExecuteUnit
);
34 GenericThread::ThreadFunction(void)
36 status_t status
= B_OK
;
38 status
= ThreadStartup();
39 // Subclass and override this function
41 ThreadStartupFailed(status
);
43 // is this the right thing to do?
47 if (HasQuitBeenRequested()) {
48 status
= ThreadShutdown();
49 // Subclass and override this function
51 ThreadShutdownFailed(status
);
63 status
= ExecuteUnit();
64 // Subclass and override
66 // Subclass and override
68 ExecuteUnitFailed(status
);
78 GenericThread::ThreadStartup(void)
80 // This function is virtual.
81 // Subclass and override this function.
88 GenericThread::ExecuteUnit(void)
90 // This function is virtual.
92 // You would normally subclass and override this function
93 // as it will provide you with Pause and Quit functionality
94 // thanks to the unit management done by GenericThread::ThreadFunction()
101 GenericThread::ThreadShutdown(void)
103 // This function is virtual.
104 // Subclass and override this function.
111 GenericThread::ThreadStartupFailed(status_t status
)
113 // This function is virtual.
114 // Subclass and override this function.
121 GenericThread::ExecuteUnitFailed(status_t status
)
123 // This function is virtual.
124 // Subclass and override this function.
131 GenericThread::ThreadShutdownFailed(status_t status
)
133 // This function is virtual.
134 // Subclass and override this function.
136 // (is this good default behaviour?)
141 GenericThread::Start(void)
143 status_t status
= B_OK
;
146 status
= release_sem(fExecuteUnit
);
150 fThreadIsPaused
= false;
153 status
= resume_thread(fThreadId
);
160 GenericThread::private_thread_function(void* pointer
)
162 return ((GenericThread
*)pointer
)->ThreadFunction();
167 GenericThread::GetDataStore(void)
169 return fThreadDataStore
;
174 GenericThread::SetDataStore(BMessage
* message
)
176 fThreadDataStore
= message
;
181 GenericThread::Pause(bool shouldBlock
, bigtime_t timeout
)
183 status_t status
= B_OK
;
186 // thread will wait on semaphore
187 status
= acquire_sem(fExecuteUnit
);
189 // thread will timeout
190 status
= acquire_sem_etc(fExecuteUnit
, 1, B_RELATIVE_TIMEOUT
, timeout
);
193 if (status
== B_OK
) {
194 fThreadIsPaused
= true;
203 GenericThread::Quit(void)
205 fQuitRequested
= true;
210 GenericThread::HasQuitBeenRequested(void)
212 return fQuitRequested
;
217 GenericThread::IsPaused(void)
219 return fThreadIsPaused
;
224 GenericThread::Suspend(void)
226 return suspend_thread(fThreadId
);
231 GenericThread::Resume(void)
233 release_sem(fExecuteUnit
);
234 // to counteract Pause()
235 fThreadIsPaused
= false;
237 return (resume_thread(fThreadId
));
238 // to counteract Suspend()
243 GenericThread::Kill(void)
245 return (kill_thread(fThreadId
));
250 GenericThread::ExitWithReturnValue(status_t returnValue
)
252 exit_thread(returnValue
);
257 GenericThread::SetExitCallback(void (*callback
)(void*), void* data
)
259 return (on_exit_thread(callback
, data
));
264 GenericThread::WaitForThread(status_t
* exitValue
)
266 return (wait_for_thread(fThreadId
, exitValue
));
271 GenericThread::Rename(char* name
)
273 return (rename_thread(fThreadId
, name
));
278 GenericThread::SendData(int32 code
, void* buffer
, size_t size
)
280 return (send_data(fThreadId
, code
, buffer
, size
));
285 GenericThread::ReceiveData(thread_id
* sender
, void* buffer
, size_t size
)
287 return (receive_data(sender
, buffer
, size
));
292 GenericThread::HasData(void)
294 return (has_data(fThreadId
));
299 GenericThread::SetPriority(int32 priority
)
301 return (set_thread_priority(fThreadId
, priority
));
306 GenericThread::Snooze(bigtime_t delay
)
315 GenericThread::SnoozeUntil(bigtime_t delay
, int timeBase
)
318 snooze_until(delay
, timeBase
);
324 GenericThread::GetInfo(thread_info
* info
)
326 return get_thread_info(fThreadId
, info
);
331 GenericThread::GetThread(void)
340 GenericThread::GetTeam(void)
349 GenericThread::GetName(void)
353 return strdup(info
.name
);
358 GenericThread::GetState(void)
367 GenericThread::GetSemaphore(void)
376 GenericThread::GetPriority(void)
380 return info
.priority
;
385 GenericThread::GetUserTime(void)
389 return info
.user_time
;
394 GenericThread::GetKernelTime(void)
398 return info
.kernel_time
;
403 GenericThread::GetStackBase(void)
407 return info
.stack_base
;
412 GenericThread::GetStackEnd(void)
416 return info
.stack_end
;
421 GenericThread::BeginUnit(void)
423 acquire_sem(fExecuteUnit
);
424 // thread can not be paused until it releases semaphore
429 GenericThread::EndUnit(void)
431 release_sem(fExecuteUnit
);
432 // thread can now be paused