vfs: check userland buffers before reading them.
[haiku.git] / src / apps / expander / GenericThread.cpp
blob7092177b60881ed756b2f950dbc22e57078b8e35
1 // license: public domain
2 // authors: jonas.sundstrom@kirilla.com
5 #include "GenericThread.h"
7 #include <string.h>
10 GenericThread::GenericThread(const char* threadName, int32 priority,
11 BMessage* message)
13 fThreadDataStore(message),
14 fThreadId(spawn_thread(private_thread_function, threadName, priority,
15 this)),
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);
33 status_t
34 GenericThread::ThreadFunction(void)
36 status_t status = B_OK;
38 status = ThreadStartup();
39 // Subclass and override this function
40 if (status != B_OK) {
41 ThreadStartupFailed(status);
42 return (status);
43 // is this the right thing to do?
46 while (1) {
47 if (HasQuitBeenRequested()) {
48 status = ThreadShutdown();
49 // Subclass and override this function
50 if (status != B_OK){
51 ThreadShutdownFailed(status);
52 return (status);
53 // what do we do?
56 delete this;
57 // destructor
58 return B_OK;
61 BeginUnit();
63 status = ExecuteUnit();
64 // Subclass and override
66 // Subclass and override
67 if (status != B_OK)
68 ExecuteUnitFailed(status);
70 EndUnit();
73 return (B_OK);
77 status_t
78 GenericThread::ThreadStartup(void)
80 // This function is virtual.
81 // Subclass and override this function.
83 return B_OK;
87 status_t
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()
96 return B_OK;
100 status_t
101 GenericThread::ThreadShutdown(void)
103 // This function is virtual.
104 // Subclass and override this function.
106 return B_OK;
110 void
111 GenericThread::ThreadStartupFailed(status_t status)
113 // This function is virtual.
114 // Subclass and override this function.
116 Quit();
120 void
121 GenericThread::ExecuteUnitFailed(status_t status)
123 // This function is virtual.
124 // Subclass and override this function.
126 Quit();
130 void
131 GenericThread::ThreadShutdownFailed(status_t status)
133 // This function is virtual.
134 // Subclass and override this function.
136 // (is this good default behaviour?)
140 status_t
141 GenericThread::Start(void)
143 status_t status = B_OK;
145 if (IsPaused()) {
146 status = release_sem(fExecuteUnit);
147 if (status != B_OK)
148 return status;
150 fThreadIsPaused = false;
153 status = resume_thread(fThreadId);
155 return status;
159 int32
160 GenericThread::private_thread_function(void* pointer)
162 return ((GenericThread*)pointer)->ThreadFunction();
166 BMessage*
167 GenericThread::GetDataStore(void)
169 return fThreadDataStore;
173 void
174 GenericThread::SetDataStore(BMessage* message)
176 fThreadDataStore = message;
180 status_t
181 GenericThread::Pause(bool shouldBlock, bigtime_t timeout)
183 status_t status = B_OK;
185 if (shouldBlock) {
186 // thread will wait on semaphore
187 status = acquire_sem(fExecuteUnit);
188 } else {
189 // thread will timeout
190 status = acquire_sem_etc(fExecuteUnit, 1, B_RELATIVE_TIMEOUT, timeout);
193 if (status == B_OK) {
194 fThreadIsPaused = true;
195 return B_OK;
198 return status;
202 void
203 GenericThread::Quit(void)
205 fQuitRequested = true;
209 bool
210 GenericThread::HasQuitBeenRequested(void)
212 return fQuitRequested;
216 bool
217 GenericThread::IsPaused(void)
219 return fThreadIsPaused;
223 status_t
224 GenericThread::Suspend(void)
226 return suspend_thread(fThreadId);
230 status_t
231 GenericThread::Resume(void)
233 release_sem(fExecuteUnit);
234 // to counteract Pause()
235 fThreadIsPaused = false;
237 return (resume_thread(fThreadId));
238 // to counteract Suspend()
242 status_t
243 GenericThread::Kill(void)
245 return (kill_thread(fThreadId));
249 void
250 GenericThread::ExitWithReturnValue(status_t returnValue)
252 exit_thread(returnValue);
256 status_t
257 GenericThread::SetExitCallback(void (*callback)(void*), void* data)
259 return (on_exit_thread(callback, data));
263 status_t
264 GenericThread::WaitForThread(status_t* exitValue)
266 return (wait_for_thread(fThreadId, exitValue));
270 status_t
271 GenericThread::Rename(char* name)
273 return (rename_thread(fThreadId, name));
277 status_t
278 GenericThread::SendData(int32 code, void* buffer, size_t size)
280 return (send_data(fThreadId, code, buffer, size));
284 int32
285 GenericThread::ReceiveData(thread_id* sender, void* buffer, size_t size)
287 return (receive_data(sender, buffer, size));
291 bool
292 GenericThread::HasData(void)
294 return (has_data(fThreadId));
298 status_t
299 GenericThread::SetPriority(int32 priority)
301 return (set_thread_priority(fThreadId, priority));
305 void
306 GenericThread::Snooze(bigtime_t delay)
308 Suspend();
309 snooze(delay);
310 Resume();
314 void
315 GenericThread::SnoozeUntil(bigtime_t delay, int timeBase)
317 Suspend();
318 snooze_until(delay, timeBase);
319 Resume();
323 status_t
324 GenericThread::GetInfo(thread_info* info)
326 return get_thread_info(fThreadId, info);
330 thread_id
331 GenericThread::GetThread(void)
333 thread_info info;
334 GetInfo(&info);
335 return info.thread;
339 team_id
340 GenericThread::GetTeam(void)
342 thread_info info;
343 GetInfo(&info);
344 return info.team;
348 char*
349 GenericThread::GetName(void)
351 thread_info info;
352 GetInfo(&info);
353 return strdup(info.name);
357 thread_state
358 GenericThread::GetState(void)
360 thread_info info;
361 GetInfo(&info);
362 return info.state;
366 sem_id
367 GenericThread::GetSemaphore(void)
369 thread_info info;
370 GetInfo(&info);
371 return info.sem;
375 int32
376 GenericThread::GetPriority(void)
378 thread_info info;
379 GetInfo(&info);
380 return info.priority;
384 bigtime_t
385 GenericThread::GetUserTime(void)
387 thread_info info;
388 GetInfo(&info);
389 return info.user_time;
393 bigtime_t
394 GenericThread::GetKernelTime(void)
396 thread_info info;
397 GetInfo(&info);
398 return info.kernel_time;
402 void*
403 GenericThread::GetStackBase(void)
405 thread_info info;
406 GetInfo(&info);
407 return info.stack_base;
411 void*
412 GenericThread::GetStackEnd(void)
414 thread_info info;
415 GetInfo(&info);
416 return info.stack_end;
420 void
421 GenericThread::BeginUnit(void)
423 acquire_sem(fExecuteUnit);
424 // thread can not be paused until it releases semaphore
428 void
429 GenericThread::EndUnit(void)
431 release_sem(fExecuteUnit);
432 // thread can now be paused