OpenWalnut  1.4.0
WThreadedRunner.h
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