OpenWalnut  1.5.0dev
WThreadedRunner.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #if( defined( __linux__ ) && !defined( __ANDROID__ ) )
26 #include <sys/prctl.h>
27 #endif
28 
29 #include <iostream>
30 #include <string>
31 
32 #include "exceptions/WSignalSubscriptionFailed.h"
33 #include "WCondition.h"
34 #include "WConditionOneShot.h"
35 #include "WException.h"
36 #include "WLogger.h"
37 #include "WThreadedRunner.h"
38 
40  m_shutdownFlag( new WConditionOneShot(), false ),
41  m_isCrashed( new WConditionOneShot(), false ),
42  m_crashMessage( "" ),
43  m_threadName( "" )
44 {
45  // initialize members
46 }
47 
49 {
50  // cleanup
51 }
52 
54 {
55  return m_isCrashed;
56 }
57 
59 {
61 }
62 
63 void WThreadedRunner::handleDeadlyException( const WException& e, std::string sender )
64 {
65  wlog::error( sender ) << "WException. Notifying. Message: " << e.what();
66 
67  // ensure proper exception propagation
69 
70  // notify waiting threads
71  m_isCrashed( true );
72  m_crashMessage = e.what();
73 }
74 
76 {
77  run( boost::bind( &WThreadedRunner::threadMainSave, this ) );
78 }
79 
81 {
82  m_thread = boost::thread( f );
83 }
84 
85 void WThreadedRunner::wait( bool requestFinish )
86 {
87  if( requestFinish )
88  {
89  requestStop();
90  }
91  m_thread.join();
92 }
93 
95 {
96  // first notify
97  notifyStop();
98 
99  // then signal it
100  m_shutdownFlag( true );
101 }
102 
104 {
106 }
107 
109 {
111 
112  try
113  {
114  threadMain();
115  }
116  catch( const WException& e )
117  {
118  onThreadException( e );
119  }
120  catch( const std::exception& e )
121  {
123  }
124 }
125 
127 {
128  WLogger::getLogger()->addLogMessage( "This should never be called. Implement a thread function here.", "WThreadedRunner", LL_WARNING );
129 }
130 
132 {
133 }
134 
136 {
137  m_thread.yield();
138 }
139 
140 void WThreadedRunner::sleep( const int32_t t ) const
141 {
142  boost::this_thread::sleep( boost::posix_time::seconds( t ) );
143 }
144 
145 void WThreadedRunner::msleep( const int32_t t ) const
146 {
147  boost::this_thread::sleep( boost::posix_time::microseconds( t ) );
148 }
149 
150 boost::signals2::connection WThreadedRunner::subscribeSignal( THREAD_SIGNAL signal, t_ThreadErrorSignalHandlerType notifier )
151 {
152  switch( signal )
153  {
154  case WTHREAD_ERROR:
155  return signal_thread_error.connect( notifier );
156  default:
157  throw WSignalSubscriptionFailed( "Could not subscribe to unknown signal." );
158  break;
159  }
160 }
161 
162 void WThreadedRunner::setThreadName( std::string name )
163 {
164  m_threadName = name;
165 }
166 
168 {
169  return m_threadName;
170 }
171 
172 const std::string& WThreadedRunner::getCrashMessage() const
173 {
174  return m_crashMessage;
175 }
176 
177 #if( defined( __linux__ ) && !defined( __ANDROID__ ) )
178 void WThreadedRunner::setThisThreadName( std::string name )
179 {
180  // set the name of the thread. This name is shown by the "top", for example.
181  prctl( PR_SET_NAME, ( "openwalnut (" + name + ")" ).c_str() );
182 }
183 #else
184 void WThreadedRunner::setThisThreadName( std::string /* name */ )
185 {
186  // Not supported
187 }
188 #endif
189 
Implements a WCondition, but can be fired only ONCE.
Basic exception handler.
Definition: WException.h:39
virtual const char * what() const
Returns the message string set on throw.
Definition: WException.cpp:90
virtual void wait() const
Wait for the flag to change its value.
Definition: WFlag.h:279
void addLogMessage(std::string message, std::string source="", LogLevel level=LL_DEBUG)
Appends a log message to the logging queue.
Definition: WLogger.cpp:84
static WLogger * getLogger()
Returns pointer to the currently running logger instance.
Definition: WLogger.cpp:64
General purpose exception and therefore base class for all kernel related exceptions.
void msleep(const int32_t t) const
Sets thread asleep.
virtual boost::signals2::connection subscribeSignal(THREAD_SIGNAL signal, t_ThreadErrorSignalHandlerType notifier)
Connects a specified notify function with a signal this thread instance is offering.
virtual void run()
Run thread.
void threadMainSave()
The is the thread entry point.
void yield() const
Give remaining execution timeslice to another thread.
boost::function< void(void) > THREADFUNCTION
Type used for simple thread functions.
const std::string & getCrashMessage() const
Get the message of the exception finally causing the crash.
std::string m_threadName
This threads name.
virtual void threadMain()
Function that has to be overwritten for execution.
std::string getThreadName() const
Returns the current thread name.
void setThreadName(std::string name)
Set the name of the thread.
std::string m_crashMessage
The crash message.
static void setThisThreadName(std::string name)
Static function to set the name of the calling thread.
void sleep(const int32_t t) const
Sets thread asleep.
void handleDeadlyException(const WException &e, std::string sender="WThreadedRunner")
Handle the specified exception which was not caught in the thread, which basically means the thread h...
WThreadedRunner()
Default constructor.
void waitForStop()
Let the thread sleep until a stop request was given.
virtual void requestStop()
This method's purpose is to request a stop without waiting for it.
virtual ~WThreadedRunner()
Destructor.
void wait(bool requestFinish=false)
Wait for the thread to be finished.
virtual void notifyStop()
Gets called when the thread should be stopped.
boost::thread m_thread
Thread instance.
WBoolFlag m_isCrashed
True whenever an exception is thrown during threadMain.
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
t_ThreadErrorSignalType signal_thread_error
Signal fired whenever a thread throws an exception/error.
const WBoolFlag & isCrashed() const
Checks whether this thread has been crashed.
virtual void onThreadException(const WException &e)
This method is called if an exception was caught, which came from the custom thread code.
WStreamedLogger error(const std::string &source)
Logging an error message.
Definition: WLogger.h:298