casa
$Rev:20696$
|
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_ */