xref: /haiku/src/apps/cortex/support/BasicThread.h (revision 3cb015b1ee509d69c643506e8ff573808c86dcfc)
1 // BasicThread.h
2 // based on ThreadPrimitive from the Be Newsletter
3 //
4 // HISTORY
5 //   e.moon		12jul99: now in cortex namespace
6 //   - The stop mechanism has changed a bit; it's now up to the
7 //     run() implementation to indicate that it has completed by
8 //     calling done().
9 //
10 //   e.moon		11may99: brought into the beDub support kit
11 
12 #ifndef __BasicThread_H__
13 #define __BasicThread_H__
14 
15 #include <Debug.h>
16 #include <KernelKit.h>
17 #include <String.h>
18 
19 
20 #include "cortex_defs.h"
21 __BEGIN_CORTEX_NAMESPACE
22 
23 class BasicThread {
24 
25 protected:				// hooks
26 	virtual void run()=0;
27 
28 public:					// ctor/dtor
29 	virtual ~BasicThread() {
30 
31 		if(m_thread > 0) {
32 			kill();
33 		}
34 	}
35 
36 	BasicThread(
37 		int32 priority=B_LOW_PRIORITY,
38 		const char* name=0,
39 		bool killOnDelete=true) :
40 
41 		m_thread(-1),
42 		m_priority(priority),
43 		m_name(name ? name : "BasicThread [?]"),
44 		m_running(false),
45 		m_stopping(false) {}
46 
47 	bool running() const { return m_running; }
48 	bool stopping() const { return m_stopping; }
49 
50 	thread_id thread() const { return m_thread; }
51 	const char* name() const { return m_name.String(); }
52 
53 public:					// operations
54 	status_t start() {
55 
56 		if(running())
57 			return B_ERROR;
58 
59 		m_thread = spawn_thread(
60 			&BasicThread::Run,
61 			m_name.String(),
62 			m_priority,
63 			this);
64 
65 		status_t err = resume_thread(m_thread);
66 		if(err == B_OK)
67 			m_running = true;
68 		return err;
69 	}
70 
71 	// reworked 12jul99 e.moon
72 	status_t stop(bool wait=true) {
73 
74 		if(!running())
75 			return B_ERROR;
76 
77 		thread_id thread = m_thread; // +++++ is this safe?
78 		if(thread <= 0)
79 			return B_OK;
80 
81 		// signal stop
82 		m_stopping = true;
83 
84 		if(wait) {
85 			status_t ret;
86 			while(wait_for_thread(thread, &ret) == B_INTERRUPTED) {
87 				PRINT(("stopping thread %ld: B_INTERRUPTED\n", thread));
88 			}
89 		}
90 
91 		return B_OK;
92 	}
93 
94 protected:					// internal methods
95 
96 	// Blunt force trauma.
97 	// added 12jul99 e.moon
98 	status_t kill() {
99 		if(m_thread <= 0)
100 			return B_ERROR;
101 
102 		kill_thread(m_thread);
103 
104 		m_thread = -1;
105 		m_running = false;
106 		m_stopping = false;
107 		return B_OK;
108 	}
109 
110 	// Call this method at the end of your run() implementation.
111 	// added 12jul99 e.moon
112 	void done() {
113 		m_running = false;
114 		m_stopping = false;
115 		m_thread = -1;
116 	}
117 
118 private:						// static impl. methods
119 	static status_t Run(void* user) {
120 
121 		BasicThread* instance = static_cast<BasicThread*>(user);
122 		instance->run();
123 		return B_OK;
124 	}
125 
126 private:						// impl members
127 	thread_id		m_thread;
128 	int32				m_priority;
129 	BString			m_name;
130 
131 	bool					m_running;
132 	bool					m_stopping;
133 };
134 
135 __END_CORTEX_NAMESPACE
136 #endif /* __BasicThread_H__ */
137