#include #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; } } }