smtpthread/Thread.h

00001 // DOCUMENT:  Thread-Class
00002 // VERSION:   $Revision: 1.5 $
00003 // DATE:      $Date: 2007-10-26 23:09:19 $
00004 // AUTHOR:    M.Beranek
00005 // COPYRIGHT: M.Beranek
00006 
00007 #ifndef _THREAD_H
00008 #define _THREAD_H
00009 
00010 #include <pthread.h>
00011 
00012 namespace SmtpThread
00013 {
00014     /**
00015      * Thread-Class.
00016      *
00017      * This abstract class wraps a class around a threading function.
00018      *
00019      * Threading is startet through calling 'Start', which sets
00020      * the protected member-variable '_isRunning'. The state of
00021      * the thread can be checked with the member-function
00022      * 'isRunning'.
00023      *
00024      * You must overwrite the method 'Execute' to do
00025      * something usefull within the thread.
00026      *
00027      * 'Execute' should be constructed as an endless loop like:
00028      *
00029      * <code>
00030      * void InheritedClassname::Execute( void * arg )<br>
00031      * {<br>
00032      *   while( _isRunning )<br>
00033      *   {<br>
00034      *     // do something...<br>
00035      *   }<br>
00036      * }<br>
00037      * </code>
00038      *
00039      * When 'Start' is called, it starts the thread and executes
00040      * 'Setup' and 'Execute'.
00041      *
00042      * To stop threading, simply call 'Stop'.
00043      */
00044     class Thread
00045     {
00046     public:
00047         
00048         /**
00049          * Constructor.
00050          */
00051         Thread();
00052         
00053         /**
00054          * Destructor.
00055          *
00056          * NOTE: Under normal conditions I would use a purely virtual
00057          * destructor. But unfortunately most people (me too) often forget
00058          * to call the 'Stop' member-function in the destructor of the
00059          * derived classes.
00060          *
00061          * So calling delete on an object, which still has a running
00062          * thread, may not behave well, especially when the destructor
00063          * removes members of the object, while the thread is trying to
00064          * access them.
00065          *
00066          * So, I implemented a non-virtual destructor, which stops
00067          * threading, when the thread is still running. This will cause
00068          * most compilers to issue a warning, but it seems to be the
00069          * easiest way, to get your code working... ;)
00070          *
00071          */
00072         ~Thread();
00073         
00074         /**
00075          * Start threading.
00076          * @param void* arg typeless argument.
00077          * @return int exit-code of 'pthread_create'
00078          */
00079         int Start(void* arg);
00080         
00081         /**
00082          * Returns the thread-id.
00083          * @return pthread_t thread-id
00084          */
00085         pthread_t getThreadId();
00086         
00087         /**
00088          * Checks, whether or not the thread is running.
00089          * @return bool true / false = running / not running
00090          */
00091         bool isRunning();
00092         
00093         /**
00094          * Stop threading.
00095          */
00096         void Stop();
00097         
00098         
00099     protected:
00100         
00101         /**
00102          * Gets called immediatly after "EntryPoint".
00103          * Calls "Setup" and "Execute".
00104          * @param void* arg typeless argument.
00105          */
00106         int Run(void * arg);
00107         
00108         /**
00109          * This is the entrypoint for threading.
00110          * This function must be declared as "static", because the pthread-library
00111          * expects a normal C-type-function as an entrypoint.
00112          *
00113          * Parameters are passed as pointer to void and are the same as passed
00114          * to "Start".
00115          *
00116          * @param void* arg typeless argument.
00117          */
00118         static void * EntryPoint( void * );
00119         
00120         /**
00121          * Initializes some thread-variables and sets up a mutex.
00122          * The mutex can be accessed through the member-varaible
00123          * "_mutex".
00124          */
00125         virtual void Setup();
00126         
00127         /**
00128          * The main threading-functionality goes here.
00129          * You should create an endless loop like:
00130          *
00131          * <code>
00132          * while( _isRunning)
00133          * {
00134          *   // do something usefull...
00135          * }
00136          * </code>
00137          *
00138          * Parameters are passed as pointer to void and are the same as passed
00139          * to "Start".
00140          *
00141          * @param void* arg typeless argument.
00142          */
00143         virtual void Execute( void * );
00144         
00145         /**
00146          * Helper to initialize the parameters provided to "Start".
00147          */
00148         void * Arg() const
00149         {
00150             return _arg;
00151         }
00152         
00153         /**
00154          * Initiallizes the parameters passed to "Start".
00155          *
00156          * @param void* a typeless argument.
00157          */
00158         void Arg( void * a )
00159         {
00160             _arg = a;
00161         }
00162         
00163         /** Wether or not the thread is running. */
00164         bool _isRunning;
00165         
00166         /** Mutex. */
00167         pthread_mutex_t _mutex;
00168         
00169         /**
00170          * Locks the mutex "_mutex".
00171          *
00172          * NOTE: Use with care, cause it might get you a deadlock!
00173          *
00174          * @see Thread::releaseLock
00175          */
00176         void getLock();
00177         
00178         /**
00179          * Unlocks the mutex "_mutex".
00180          *
00181          * @see Thread::getLock
00182          */
00183         void releaseLock();
00184         
00185         
00186     private:
00187         
00188         /** Thread-ID. */
00189         pthread_t _ThreadId;
00190         
00191         /** Parameters passed to "Start", */
00192         void * _arg;
00193         
00194         
00195     };
00196     
00197 }
00198 
00199 #endif  /* _THREAD_H */
00200 

Generated on Thu Nov 1 09:51:22 2007 for libSmtpThread by  doxygen 1.5.1