00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef WWORKERTHREAD_H
00026 #define WWORKERTHREAD_H
00027
00028 #include <string>
00029 #include <exception>
00030
00031 #include <boost/shared_ptr.hpp>
00032 #include <boost/signal.hpp>
00033
00034 #include "WAssert.h"
00035 #include "WException.h"
00036 #include "WThreadedRunner.h"
00037
00038
00039
00040
00041 template< class Function_T >
00042 class WWorkerThread : public WThreadedRunner
00043 {
00044
00045
00046 typedef boost::signal< void () > StopSignal;
00047
00048
00049 typedef boost::signal< void ( WException const& ) > ExceptionSignal;
00050
00051 public:
00052
00053
00054 typedef boost::function< void () > StopFunction;
00055
00056
00057 typedef boost::function< void ( WException const& ) > ExceptionFunction;
00058
00059
00060
00061
00062
00063
00064
00065
00066 WWorkerThread( boost::shared_ptr< Function_T > func, std::size_t id, std::size_t numThreads );
00067
00068
00069
00070
00071 virtual ~WWorkerThread();
00072
00073
00074
00075
00076
00077
00078 void subscribeExceptionSignal( ExceptionFunction func );
00079
00080
00081
00082
00083
00084
00085 void subscribeStopSignal( StopFunction func );
00086
00087 protected:
00088
00089
00090
00091 virtual void threadMain();
00092
00093 private:
00094
00095
00096
00097 WWorkerThread( WWorkerThread const& );
00098
00099
00100
00101
00102
00103
00104 WWorkerThread& operator = ( WWorkerThread const& );
00105
00106
00107 boost::shared_ptr< Function_T > m_func;
00108
00109
00110 std::size_t m_id;
00111
00112
00113 std::size_t m_numThreads;
00114
00115
00116 ExceptionSignal m_exceptionSignal;
00117
00118
00119 StopSignal m_stopSignal;
00120 };
00121
00122 template< class Function_T >
00123 WWorkerThread< Function_T >::WWorkerThread( boost::shared_ptr< Function_T > func, std::size_t id, std::size_t numThreads )
00124 : m_func( func ),
00125 m_id( id ),
00126 m_numThreads( numThreads ),
00127 m_exceptionSignal(),
00128 m_stopSignal()
00129 {
00130 if( id >= numThreads )
00131 {
00132 throw WException( std::string( "The id of this thread is not valid." ) );
00133 }
00134 if( !m_func )
00135 {
00136 throw WException( std::string( "No thread function provided!" ) );
00137 }
00138 }
00139
00140 template< class Function_T >
00141 WWorkerThread< Function_T >::~WWorkerThread()
00142 {
00143 m_exceptionSignal.disconnect_all_slots();
00144 m_stopSignal.disconnect_all_slots();
00145 }
00146
00147 template< class Function_T >
00148 void WWorkerThread< Function_T >::subscribeExceptionSignal( ExceptionFunction func )
00149 {
00150 if( func )
00151 {
00152 m_exceptionSignal.connect( func );
00153 }
00154 }
00155
00156 template< class Function_T >
00157 void WWorkerThread< Function_T >::subscribeStopSignal( StopFunction func )
00158 {
00159 if( func )
00160 {
00161 m_stopSignal.connect( func );
00162 }
00163 }
00164
00165 template< class Function_T >
00166 void WWorkerThread< Function_T >::threadMain()
00167 {
00168 if( m_func )
00169 {
00170 try
00171 {
00172 m_func->operator() ( m_id, m_numThreads, m_shutdownFlag );
00173 }
00174 catch( WException const& e )
00175 {
00176 m_exceptionSignal( e );
00177 return;
00178 }
00179 catch( std::exception const& e )
00180 {
00181 WException w( std::string( e.what() ) );
00182 m_exceptionSignal( w );
00183 return;
00184 }
00185 catch( ... )
00186 {
00187 WException w( std::string( "An exception was thrown." ) );
00188 m_exceptionSignal( w );
00189 return;
00190 }
00191 }
00192 m_stopSignal();
00193 }
00194
00195 #endif // WWORKERTHREAD_H