Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

thread.hpp

00001 /************************************************************************************
00002  *    This file is part of the MynahSA streaming and archiving toolkit              *
00003  *    Copyright (C) 2006 Mynah-Software Ltd. All Rights Reserved.                   *
00004  *                                                                                  *
00005  *    This program is free software; you can redistribute it and/or modify          *
00006  *    it under the terms of the GNU General Public License, version 2               *
00007  *    as published by the Free Software Foundation.                                 *
00008  *                                                                                  *
00009  *    This program is distributed in the hope that it will be useful,               *
00010  *    but WITHOUT ANY WARRANTY; without even the implied warranty of                *
00011  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                 *
00012  *    GNU General Public License for more details.                                  *
00013  *                                                                                  *
00014  *    You should have received a copy of the GNU General Public License along       *
00015  *    with this program; if not, write to the Free Software Foundation, Inc.,       *
00016  *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.                   *
00017  *                                                                                  *
00018  ************************************************************************************/
00019 
00020 #ifndef __thread_hpp
00021 #define __thread_hpp
00022 
00023 #ifdef MYNAHSA_USE_BOOST
00024 #include <boost/thread.hpp>
00025 #include <boost/thread/mutex.hpp>
00026 namespace MynahSA { 
00027   typedef boost::mutex Mutex;
00028   typedef boost::mutex::scoped_lock Lock;
00029 };
00030 
00031 #else
00032 
00033 #ifndef WIN32
00034 #include <pthread.h>
00035 #else
00036 #include <windows.h>
00037 #endif
00038 
00039 
00040 #include <iostream>
00041 
00042 
00043 namespace MynahSA { 
00054   class Mutex { 
00055     friend class Lock;
00056   public:
00058     Mutex();
00060     ~Mutex();
00061   
00063     inline static void lock(Mutex& m) { 
00064 #ifdef WIN32
00065       WaitForSingleObject(m._mutex, INFINITE); // obtain lock
00066 #else
00067       pthread_mutex_lock(&m._mutex); 
00068 #endif
00069     }
00070     
00072     inline static void unlock(Mutex& m) { 
00073 #ifdef WIN32
00074       ReleaseMutex(m._mutex);
00075 #else
00076       pthread_mutex_unlock(&m._mutex); 
00077 #endif
00078     }
00079   
00080   private:
00082     Mutex(const Mutex&) { }
00083 #ifdef WIN32
00084 
00085     HANDLE _mutex;
00086 #else
00087     // posix mutex (only available on posix machines)
00088     pthread_mutex_t _mutex;
00089 #endif
00090   };
00091 
00108   class Lock { 
00109   public:
00111     Lock(Mutex& m);
00113     ~Lock();
00114   private:
00116     Lock(const Lock& l ) : _mutex(l._mutex) { }
00118     Mutex& _mutex;
00119   };
00120   
00121 
00144   template<class T>
00145   class Thread { 
00146   public:
00148     Thread(const T& startclass) {
00149       T* copy = new T(startclass);  // create a startclass copy on the heap
00150       
00151 #ifndef WIN32
00152       pthread_create(&_thread,
00153                      0,
00154                      Thread<T>::startAddr,
00155                      copy);
00156 #else 
00157       _hThread = CreateThread(0,                    // LPSECURITY_ATTRIBUTES
00158                               0,                    // dwStackSize - 0 means same as parent
00159                               (LPTHREAD_START_ROUTINE) Thread<T>::startAddr, // start address
00160                               copy,        // data (this ptr)
00161                                                 0,
00162                                                 &_thread);    
00163 #endif
00164     }
00168     ~Thread() { 
00169 #ifndef WIN32
00170       pthread_detach(_thread);
00171 #endif
00172     }    
00176     void* join() { 
00177 #ifdef WIN32
00178       WaitForSingleObject( _hThread, INFINITE );
00179       return 0;
00180 #else
00181       void* vrtn;
00182       pthread_join(_thread,&vrtn);
00183       return vrtn;
00184 #endif
00185     }
00186       
00187   private:
00189     static void* startAddr(void* args) {
00190       T* tptr = reinterpret_cast<T*>(args);
00191       (*tptr)();
00192       delete tptr;
00193       return 0;
00194     }
00195   
00196 #ifdef WIN32
00197 
00198     HANDLE _hThread;
00200     DWORD _thread;
00201 #else  
00202 
00203     pthread_t _thread;
00204 #endif
00205 
00206   };
00207 };
00208 #endif
00209 
00210 #endif