xref: /haiku/src/apps/cortex/support/BasicThread.h (revision 1a7bcf6962e1c99906cce0fe602e08c3fcda46f6)
1 /*
2  * Copyright (c) 1999-2000, Eric Moon.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions, and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions, and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 
32 // BasicThread.h
33 // based on ThreadPrimitive from the Be Newsletter
34 //
35 // HISTORY
36 //   e.moon		12jul99: now in cortex namespace
37 //   - The stop mechanism has changed a bit; it's now up to the
38 //     run() implementation to indicate that it has completed by
39 //     calling done().
40 //
41 //   e.moon		11may99: brought into the beDub support kit
42 
43 #ifndef __BasicThread_H__
44 #define __BasicThread_H__
45 
46 #include <Debug.h>
47 #include <KernelKit.h>
48 #include <String.h>
49 
50 
51 #include "cortex_defs.h"
52 __BEGIN_CORTEX_NAMESPACE
53 
54 class BasicThread {
55 
56 protected:				// hooks
57 	virtual void run()=0;
58 
59 public:					// ctor/dtor
~BasicThread()60 	virtual ~BasicThread() {
61 
62 		if(m_thread > 0) {
63 			kill();
64 		}
65 	}
66 
67 	BasicThread(
68 		int32 priority=B_LOW_PRIORITY,
69 		const char* name=0,
70 		bool killOnDelete=true) :
71 
72 		m_thread(-1),
73 		m_priority(priority),
74 		m_name(name ? name : "BasicThread [?]"),
75 		m_running(false),
76 		m_stopping(false) {}
77 
running()78 	bool running() const { return m_running; }
stopping()79 	bool stopping() const { return m_stopping; }
80 
thread()81 	thread_id thread() const { return m_thread; }
name()82 	const char* name() const { return m_name.String(); }
83 
84 public:					// operations
start()85 	status_t start() {
86 
87 		if(running())
88 			return B_ERROR;
89 
90 		m_thread = spawn_thread(
91 			&BasicThread::Run,
92 			m_name.String(),
93 			m_priority,
94 			this);
95 
96 		status_t err = resume_thread(m_thread);
97 		if(err == B_OK)
98 			m_running = true;
99 		return err;
100 	}
101 
102 	// reworked 12jul99 e.moon
103 	status_t stop(bool wait=true) {
104 
105 		if(!running())
106 			return B_ERROR;
107 
108 		thread_id thread = m_thread; // +++++ is this safe?
109 		if(thread <= 0)
110 			return B_OK;
111 
112 		// signal stop
113 		m_stopping = true;
114 
115 		if(wait) {
116 			status_t ret;
117 			while(wait_for_thread(thread, &ret) == B_INTERRUPTED) {
118 				PRINT(("stopping thread %" B_PRId32 ": B_INTERRUPTED\n",
119 					thread));
120 			}
121 		}
122 
123 		return B_OK;
124 	}
125 
126 protected:					// internal methods
127 
128 	// Blunt force trauma.
129 	// added 12jul99 e.moon
kill()130 	status_t kill() {
131 		if(m_thread <= 0)
132 			return B_ERROR;
133 
134 		kill_thread(m_thread);
135 
136 		m_thread = -1;
137 		m_running = false;
138 		m_stopping = false;
139 		return B_OK;
140 	}
141 
142 	// Call this method at the end of your run() implementation.
143 	// added 12jul99 e.moon
done()144 	void done() {
145 		m_running = false;
146 		m_stopping = false;
147 		m_thread = -1;
148 	}
149 
150 private:						// static impl. methods
Run(void * user)151 	static status_t Run(void* user) {
152 
153 		BasicThread* instance = static_cast<BasicThread*>(user);
154 		instance->run();
155 		return B_OK;
156 	}
157 
158 private:						// impl members
159 	thread_id		m_thread;
160 	int32				m_priority;
161 	BString			m_name;
162 
163 	bool					m_running;
164 	bool					m_stopping;
165 };
166 
167 __END_CORTEX_NAMESPACE
168 #endif /* __BasicThread_H__ */
169