OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WTHREADEDRUNNER_H 00026 #define WTHREADEDRUNNER_H 00027 00028 #include <stdint.h> 00029 00030 #include <string> 00031 00032 #include <boost/function.hpp> 00033 #include <boost/signals2.hpp> 00034 00035 #include <boost/thread.hpp> 00036 #include <boost/thread/thread.hpp> 00037 00038 #include "WFlag.h" 00039 #include "WThreadedRunnerSignals.h" 00040 00041 /** 00042 * Base class for all classes needing to be executed in a separate thread. 00043 */ 00044 class WThreadedRunner // NOLINT 00045 { 00046 public: 00047 /** 00048 * Type used for simple thread functions. 00049 */ 00050 typedef boost::function< void ( void ) > THREADFUNCTION; 00051 00052 /** 00053 * Default constructor. 00054 */ 00055 WThreadedRunner(); 00056 00057 /** 00058 * Destructor. 00059 */ 00060 virtual ~WThreadedRunner(); 00061 00062 /** 00063 * Run thread. 00064 */ 00065 virtual void run(); 00066 00067 /** 00068 * Run thread. This does not start threadMain(() but runs a specified function instead. 00069 * 00070 * \param f the function to run instead of the threadMain method. 00071 */ 00072 void run( THREADFUNCTION f ); 00073 00074 /** 00075 * Wait for the thread to be finished. 00076 * 00077 * \param requestFinish true if the thread should be notified. 00078 */ 00079 void wait( bool requestFinish = false ); 00080 00081 /** 00082 * This method's purpose is to request a stop without waiting for it. 00083 */ 00084 virtual void requestStop(); 00085 00086 /** 00087 * Connects a specified notify function with a signal this thread instance is offering. 00088 * 00089 * \exception WSignalSubscriptionFailed thrown if the signal can't be connected. 00090 * 00091 * \param signal the signal to connect to. 00092 * \param notifier the notifier function to bind. 00093 * 00094 * \return connection descriptor. 00095 */ 00096 virtual boost::signals2::connection subscribeSignal( THREAD_SIGNAL signal, t_ThreadErrorSignalHandlerType notifier ); 00097 00098 /** 00099 * Checks whether this thread has been crashed. This will be true whenever the code in the thread throws an unhandled 00100 * exception. 00101 * 00102 * \return true if there has been an exception during threadMain(). 00103 */ 00104 const WBoolFlag& isCrashed() const; 00105 00106 /** 00107 * Get the message of the exception finally causing the crash. 00108 * 00109 * \return the message 00110 */ 00111 const std::string& getCrashMessage() const; 00112 00113 /** 00114 * Set the name of the thread. This can be handy for debugging as it gets set on Linux as the pthread name. You MUST set this before starting 00115 * the thread. 00116 * 00117 * \param name the name 00118 */ 00119 void setThreadName( std::string name ); 00120 00121 /** 00122 * Returns the current thread name 00123 * 00124 * \return the name, empty if no name was specified. 00125 */ 00126 std::string getThreadName() const; 00127 00128 /** 00129 * Static function to set the name of the calling thread. 00130 * 00131 * \param name the name. 00132 */ 00133 static void setThisThreadName( std::string name ); 00134 protected: 00135 /** 00136 * Function that has to be overwritten for execution. It gets executed in a separate thread after run() 00137 * has been called. 00138 */ 00139 virtual void threadMain(); 00140 00141 /** 00142 * Gets called when the thread should be stopped. The purpose of this method is to allow derived classes to handle this kind of event. 00143 */ 00144 virtual void notifyStop(); 00145 00146 /** 00147 * Thread instance. 00148 */ 00149 boost::thread m_thread; 00150 00151 /** 00152 * Give remaining execution timeslice to another thread. 00153 */ 00154 void yield() const; 00155 00156 /** 00157 * Sets thread asleep. 00158 * 00159 * \param t time to sleep in seconds. 00160 */ 00161 void sleep( const int32_t t ) const; 00162 00163 /** 00164 * Sets thread asleep. 00165 * 00166 * \param t time to sleep in microseconds. 00167 */ 00168 void msleep( const int32_t t ) const; 00169 00170 /** 00171 * Let the thread sleep until a stop request was given. 00172 */ 00173 void waitForStop(); 00174 00175 /** 00176 * Condition getting fired whenever the thread should quit. This is useful for waiting for stop requests. 00177 */ 00178 WBoolFlag m_shutdownFlag; 00179 00180 /** 00181 * This method is called if an exception was caught, which came from the custom thread code. This method is virtual and allows you to 00182 * overwrite the default behaviour. If you overwrite this method, you should call \ref handleDeadlyException or 00183 * WThreadedRunner::onThreadException if you are finished with your customized code. 00184 * 00185 * \param e the exception that was caught. 00186 */ 00187 virtual void onThreadException( const WException& e ); 00188 00189 /** 00190 * Handle the specified exception which was not caught in the thread, which basically means the thread has crashed. This triggers the error 00191 * notification and marks the thread as crashed. If you write your own exception/error mechanism (like \ref WModule), you should take care 00192 * that these method gets called. 00193 * 00194 * \note this method does not re-throw the exception 00195 * \note you should specify a custom sender string if you overwrite \ref onThreadException. 00196 * 00197 * \param e the exception 00198 * \param sender allows to customize the sender information in the log entry created by this method. 00199 */ 00200 void handleDeadlyException( const WException& e, std::string sender = "WThreadedRunner" ); 00201 00202 /** 00203 * True whenever an exception is thrown during threadMain. 00204 */ 00205 WBoolFlag m_isCrashed; 00206 00207 /** 00208 * The crash message. Only filled if m_isCrashed is true. 00209 */ 00210 std::string m_crashMessage; 00211 00212 private: 00213 /** 00214 * Disallow copy construction. 00215 * 00216 * \param rhs the other threaded runner. 00217 */ 00218 WThreadedRunner( const WThreadedRunner & rhs ); 00219 00220 /** 00221 * Disallow copy assignment. 00222 * 00223 * \param rhs the other threaded runner. 00224 * \return this. 00225 */ 00226 WThreadedRunner& operator=( const WThreadedRunner & rhs ); 00227 00228 /** 00229 * Signal fired whenever a thread throws an exception/error. 00230 */ 00231 t_ThreadErrorSignalType signal_thread_error; 00232 00233 /** 00234 * The is the thread entry point. It does exception handling and calls threadMain. 00235 */ 00236 void threadMainSave(); 00237 00238 /** 00239 * This threads name. 00240 */ 00241 std::string m_threadName; 00242 }; 00243 00244 #endif // WTHREADEDRUNNER_H