165 lines
3.5 KiB
C++
165 lines
3.5 KiB
C++
#include <iostream>
|
|
#include "common_std_thread.h"
|
|
|
|
namespace cgv {
|
|
namespace os {
|
|
|
|
|
|
///create the thread
|
|
thread::thread()
|
|
{
|
|
pthread = 0;
|
|
stop_request = false;
|
|
running = false;
|
|
delete_after_termination = false;
|
|
}
|
|
|
|
///start the implemented run() method (asynchronly)
|
|
void thread::start(bool _delete_after_termination)
|
|
{
|
|
if(!running) {
|
|
delete_after_termination = _delete_after_termination;
|
|
stop_request=false;
|
|
std::thread*& t_ptr = (std::thread*&) pthread;
|
|
t_ptr = new std::thread(&cgv::os::thread::execute, this);
|
|
running=true;
|
|
}
|
|
}
|
|
|
|
/// sleep till the signal from the given condition_mutex is sent
|
|
void thread::wait_for_signal(condition_mutex& cm)
|
|
{
|
|
Condition& c = *((Condition*&) cm.pcond);
|
|
c.cv.wait(c.ul);
|
|
}
|
|
|
|
/// sleep till the signal from the given condition_mutex is sent or the timeout is reached, lock the mutex first and unlock after waiting
|
|
bool thread::wait_for_signal_or_timeout(condition_mutex& cm, unsigned millisec)
|
|
{
|
|
Condition& c = *((Condition*&) cm.pcond);
|
|
std::chrono::milliseconds dura(millisec);
|
|
return c.cv.wait_for(c.ul, dura) == std::cv_status::no_timeout;
|
|
}
|
|
|
|
/// prefered approach to wait for signal and implemented as { cm.lock(); wait_for_signal(cm); cm.unlock(); }
|
|
void thread::wait_for_signal_with_lock(condition_mutex& cm)
|
|
{
|
|
cm.lock();
|
|
wait_for_signal(cm);
|
|
cm.unlock();
|
|
}
|
|
|
|
/// prefered approach to wait for signal or the timeout is reached and implemented as { cm.lock(); wait_for_signal_or_timeout(cm,millisec); cm.unlock(); }
|
|
bool thread::wait_for_signal_or_timeout_with_lock(condition_mutex& cm, unsigned millisec)
|
|
{
|
|
cm.lock();
|
|
bool res = wait_for_signal_or_timeout(cm, millisec);
|
|
cm.unlock();
|
|
return res;
|
|
}
|
|
|
|
void* thread::execute_s(void* args)
|
|
{
|
|
thread* t = (thread*)args;
|
|
t->execute();
|
|
if (t->delete_after_termination)
|
|
delete t;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void thread::execute()
|
|
{
|
|
run();
|
|
running = false;
|
|
}
|
|
|
|
/// wait the given number of milliseconds
|
|
void thread::wait(unsigned millisec)
|
|
{
|
|
std::chrono::milliseconds dura(millisec);
|
|
std::this_thread::sleep_for(dura);
|
|
}
|
|
|
|
void thread::stop()
|
|
{
|
|
if(running) {
|
|
stop_request=true;
|
|
std::thread& t = *((std::thread*&) pthread);
|
|
t.join();
|
|
stop_request=false;
|
|
}
|
|
}
|
|
|
|
///kill a running thread
|
|
void thread::kill()
|
|
{
|
|
if (running) {
|
|
std::thread*& t_ptr = (std::thread*&) pthread;
|
|
delete t_ptr;
|
|
t_ptr = 0;
|
|
stop_request=false;
|
|
running=false;
|
|
}
|
|
}
|
|
|
|
///join the current thread
|
|
void thread::wait_for_completion()
|
|
{
|
|
if (running) {
|
|
std::thread& t = *((std::thread*&) pthread);
|
|
t.join();
|
|
}
|
|
}
|
|
|
|
///standard destructor (a running thread will be killed)
|
|
thread::~thread()
|
|
{
|
|
if(running)
|
|
kill();
|
|
if (pthread) {
|
|
std::thread*& t_ptr = (std::thread*&) pthread;
|
|
delete t_ptr;
|
|
}
|
|
}
|
|
|
|
/// return the id of the currently executed thread
|
|
thread_id_type thread::get_current_thread_id()
|
|
{
|
|
std::thread::id id = std::this_thread::get_id();
|
|
return (long long&) id;
|
|
}
|
|
|
|
/// return id of this thread
|
|
thread_id_type thread::get_id() const
|
|
{
|
|
std::thread& t = *((std::thread*&) pthread);
|
|
std::thread::id id = t.get_id();
|
|
return (long long&) id;
|
|
}
|
|
|
|
class function_thread : public thread
|
|
{
|
|
protected:
|
|
void (*func)(thread_id_type);
|
|
public:
|
|
function_thread(void (*_func)(thread_id_type))
|
|
{
|
|
func = _func;
|
|
}
|
|
void run()
|
|
{
|
|
func(get_id());
|
|
}
|
|
};
|
|
|
|
/// start a function in a newly constructed thread, which is deleted automatically on termination
|
|
thread* start_in_thread(void (*func)(thread_id_type), bool _delete_after_termination)
|
|
{
|
|
thread* ft = new function_thread(func);
|
|
ft->start(_delete_after_termination);
|
|
return ft;
|
|
}
|
|
|
|
}
|
|
}
|