casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
AsynchronousTools.h
Go to the documentation of this file.
00001 /*
00002  * AsynchronousTools.h
00003  *
00004  *  Created on: Nov 1, 2010
00005  *      Author: jjacobs
00006  */
00007 
00008 #ifndef ASYNCHRONOUSTOOLS_H_
00009 #define ASYNCHRONOUSTOOLS_H_
00010 
00011 #include <casa/aips.h>
00012 #include <casa/aipstype.h>
00013 #include <casa/BasicSL/String.h>
00014 #include <boost/utility.hpp>
00015 #include <boost/noncopyable.hpp>
00016 #include <boost/thread/condition.hpp>
00017 #include "UtilJ.h"
00018 
00019 #include <map>
00020 #include <queue>
00021 
00022 using std::map;
00023 using std::queue;
00024 
00025 //using namespace casa;
00026 
00027 namespace casa {
00028 
00029 namespace async {
00030 
00031 class MutexImpl;
00032 
00033 class Mutex {
00034 
00035     friend class Condition;
00036     friend class UniqueLock;
00037 
00038 public:
00039 
00040     Mutex ();
00041     virtual ~Mutex ();
00042 
00044 
00045     void lock ();
00046     //Bool lock (Int milliseconds);
00047     void unlock ();
00048     Bool trylock ();
00049     
00050     // jagonzal: Useful when mandatory is locking
00051     void acquirelock();
00052 
00053 protected:
00054 
00055     boost::mutex & getMutex ();
00056 
00057 private:
00058 
00059     Bool        isLocked_p;
00060     MutexImpl * impl_p;
00061 
00062     Mutex (const Mutex & other); // illegal operation: do not define
00063     Mutex operator= (const Mutex & other); // illegal operation: do not define
00064 
00065 };
00066 
00067 class LockGuard {
00068 
00069     friend class LockGuardInverse;
00070 
00071 public:
00072 
00073     LockGuard (Mutex & mutex);
00074     LockGuard (Mutex * mutex);
00075 
00076     virtual ~LockGuard ();
00077 
00078 private:
00079 
00080     Mutex * mutex_p;
00081 
00082 };
00083 
00084 class LockGuardInverse {
00085 
00086 public:
00087 
00088     LockGuardInverse (Mutex & mutex);
00089     LockGuardInverse (Mutex * mutex);
00090     LockGuardInverse (LockGuard & lg);
00091 
00092     virtual ~LockGuardInverse ();
00093 
00094 private:
00095 
00096     Mutex * mutex_p;
00097 
00098 };
00099 
00100 
00101 class MutexLocker {
00102 
00103 public:
00104 
00105     MutexLocker (Mutex & mutex);
00106     MutexLocker (Mutex * mutex);
00107 
00108     virtual ~MutexLocker ();
00109 
00110 private:
00111 
00112     Mutex * mutex_p;
00113 
00114     MutexLocker (const MutexLocker & other); // do not define
00115     MutexLocker & operator= (const MutexLocker & other); // do not define
00116 
00117 };
00118 
00119 class ConditionImpl;
00120 class UniqueLock;
00121 
00122 class Condition {
00123 
00124 public:
00125 
00126     Condition ();
00127     virtual ~Condition ();
00128 
00129     void broadcast () __attribute__ ((deprecated)) /*"Use notify_all */;
00130     void signal () __attribute__ ((deprecated)) /* Use notify_one */;
00131 
00132     void notify_all ();
00133     void notify_one ();
00134     void wait (UniqueLock & uniqueLock);
00135     // Bool wait (Mutex & mutex, int milliseconds);
00136 
00137 private:
00138 
00139     ConditionImpl * impl_p;
00140 };
00141 
00142 class SemaphoreImpl;
00143 
00144 class Semaphore {
00145 
00146 public:
00147 
00148     Semaphore (int initialValue = 0);
00149     ~Semaphore ();
00150 
00151     Int getValue ();
00152     void post ();
00153     Bool trywait ();
00154     void wait ();
00155     Bool wait (int milliseconds);
00156 
00157 private:
00158 
00159     SemaphoreImpl * impl_p;
00160     String name_p;
00161 
00162     Semaphore (const Semaphore & other); // illegal operation: do not define
00163     Semaphore operator= (const Semaphore & other); // illegal operation: do not define
00164 
00165 };
00166 
00167 class Thread {
00168 
00169 public:
00170 
00171     typedef void * (* ThreadFunction) (void *);
00172 
00173     Thread ();
00174     virtual ~Thread ();
00175 
00176     pthread_t getId () const;
00177     pid_t gettid () const; // linux only
00178     bool isTerminationRequested () const;
00179     void * join ();
00180     void startThread ();
00181     virtual void terminate ();
00182 
00183 protected:
00184 
00185     bool isStarted () const;
00186     virtual void * run () = 0;
00187 
00188     static void * threadFunction (void *);
00189 
00190 private:
00191 
00192     pthread_t * id_p;
00193     bool started_p;
00194     volatile bool terminationRequested_p;
00195 
00196 };
00197 
00198 class UniqueLock {
00199 
00200     friend class Condition;
00201 
00202 public:
00203 
00204     UniqueLock (Mutex & mutex);
00205 
00206     void lock ();
00207     void unlock ();
00208 
00209 private:
00210 
00211     boost::unique_lock<boost::mutex> uniqueLock_p;
00212 };
00213 
00214 class Logger : private boost::noncopyable {
00215 
00216 public:
00217 
00218     void log (const char * format, ...);
00219     void registerName (const String & threadName);
00220     void start (const char * logFilename);
00221 
00222     static Logger * get ();
00223 
00224 protected:
00225 
00226     class LoggerThread : public Thread {
00227     public:
00228 
00229         LoggerThread ();
00230         ~LoggerThread ();
00231 
00232         void log (const string & text);
00233         void setLogFilename (const String & filename);
00234         void terminate ();
00235 
00236     protected:
00237 
00238         void * run ();
00239 
00240     private:
00241 
00242         Bool      deleteStream_p;
00243         String    logFilename_p;
00244         Condition loggerChanged_p;
00245         ostream * logStream_p;
00246         Mutex mutex_p;
00247         queue<string> outputQueue_p;
00248     };
00249 
00250 
00251 //    void log (char * format, ...);
00252 //    void setLogFilename (char * logFilename);
00253 //    void terminate ();
00254 
00255 private:
00256 
00257     typedef map <pthread_t, String>  ThreadNames;
00258 
00259     LoggerThread * loggerThread_p;
00260     bool loggingStarted_p;
00261     Mutex * nameMutex_p;
00262     ThreadNames threadNames_p;
00263 
00264     static Logger * singleton_p;
00265 
00266     Logger (); // singleton
00267     ~Logger ();
00268 
00269     static void initialize ();
00270 };
00271 
00272 
00273 }
00274 
00275 }
00276 
00277 
00278 #endif /* ASYNCHRONOUSTOOLS_H_ */