* Copyright (c) 1999-2000, Eric Moon.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions, and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __BasicThread_H__
#define __BasicThread_H__
#include <Debug.h>
#include <KernelKit.h>
#include <String.h>
#include "cortex_defs.h"
__BEGIN_CORTEX_NAMESPACE
class BasicThread {
protected:
virtual void run()=0;
public:
virtual ~BasicThread() {
if(m_thread > 0) {
kill();
}
}
BasicThread(
int32 priority=B_LOW_PRIORITY,
const char* name=0,
bool killOnDelete=true) :
m_thread(-1),
m_priority(priority),
m_name(name ? name : "BasicThread [?]"),
m_running(false),
m_stopping(false) {}
bool running() const { return m_running; }
bool stopping() const { return m_stopping; }
thread_id thread() const { return m_thread; }
const char* name() const { return m_name.String(); }
public:
status_t start() {
if(running())
return B_ERROR;
m_thread = spawn_thread(
&BasicThread::Run,
m_name.String(),
m_priority,
this);
status_t err = resume_thread(m_thread);
if(err == B_OK)
m_running = true;
return err;
}
status_t stop(bool wait=true) {
if(!running())
return B_ERROR;
thread_id thread = m_thread;
if(thread <= 0)
return B_OK;
m_stopping = true;
if(wait) {
status_t ret;
while(wait_for_thread(thread, &ret) == B_INTERRUPTED) {
PRINT(("stopping thread %" B_PRId32 ": B_INTERRUPTED\n",
thread));
}
}
return B_OK;
}
protected:
status_t kill() {
if(m_thread <= 0)
return B_ERROR;
kill_thread(m_thread);
m_thread = -1;
m_running = false;
m_stopping = false;
return B_OK;
}
void done() {
m_running = false;
m_stopping = false;
m_thread = -1;
}
private:
static status_t Run(void* user) {
BasicThread* instance = static_cast<BasicThread*>(user);
instance->run();
return B_OK;
}
private:
thread_id m_thread;
int32 m_priority;
BString m_name;
bool m_running;
bool m_stopping;
};
__END_CORTEX_NAMESPACE
#endif