2018-05-17 14:01:02 +00:00
# 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 ;
}
}
}