xref: /haiku/src/apps/cortex/support/BasicThread.h (revision 19ae20e67e91fc09cc9fc5c0e60e21e24e7a53eb)
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
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 
78 	bool running() const { return m_running; }
79 	bool stopping() const { return m_stopping; }
80 
81 	thread_id thread() const { return m_thread; }
82 	const char* name() const { return m_name.String(); }
83 
84 public:					// operations
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 %ld: B_INTERRUPTED\n", thread));
119 			}
120 		}
121 
122 		return B_OK;
123 	}
124 
125 protected:					// internal methods
126 
127 	// Blunt force trauma.
128 	// added 12jul99 e.moon
129 	status_t kill() {
130 		if(m_thread <= 0)
131 			return B_ERROR;
132 
133 		kill_thread(m_thread);
134 
135 		m_thread = -1;
136 		m_running = false;
137 		m_stopping = false;
138 		return B_OK;
139 	}
140 
141 	// Call this method at the end of your run() implementation.
142 	// added 12jul99 e.moon
143 	void done() {
144 		m_running = false;
145 		m_stopping = false;
146 		m_thread = -1;
147 	}
148 
149 private:						// static impl. methods
150 	static status_t Run(void* user) {
151 
152 		BasicThread* instance = static_cast<BasicThread*>(user);
153 		instance->run();
154 		return B_OK;
155 	}
156 
157 private:						// impl members
158 	thread_id		m_thread;
159 	int32				m_priority;
160 	BString			m_name;
161 
162 	bool					m_running;
163 	bool					m_stopping;
164 };
165 
166 __END_CORTEX_NAMESPACE
167 #endif /* __BasicThread_H__ */
168