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