/* * AsynchronousTools.h * * Created on: Nov 1, 2010 * Author: jjacobs */ #ifndef ASYNCHRONOUSTOOLS_H_ #define ASYNCHRONOUSTOOLS_H_ #include <casacore/casa/aips.h> #include <casacore/casa/aipstype.h> #include <casacore/casa/BasicSL/String.h> #include <mutex> #include <stdcasa/UtilJ.h> #include <map> #include <queue> using std::map; using std::mutex; using std::queue; namespace casa { namespace async { class MutexImpl; class Mutex { friend class Condition; friend class UniqueLock; public: Mutex (); virtual ~Mutex (); ///casacore::Bool isLockedByThisThread () const; // for debug purposes only !!! void lock (); //casacore::Bool lock (casacore::Int milliseconds); void unlock (); bool trylock (); // jagonzal: Useful when mandatory is locking void acquirelock(); protected: std::mutex & getMutex (); private: bool isLocked_p; MutexImpl * impl_p; Mutex (const Mutex & other); // illegal operation: do not define Mutex operator= (const Mutex & other); // illegal operation: do not define }; class LockGuard { friend class LockGuardInverse; public: LockGuard (Mutex & mutex); LockGuard (Mutex * mutex); virtual ~LockGuard (); private: Mutex * mutex_p; }; class LockGuardInverse { public: LockGuardInverse (Mutex & mutex); LockGuardInverse (Mutex * mutex); LockGuardInverse (LockGuard & lg); virtual ~LockGuardInverse (); private: Mutex * mutex_p; }; class MutexLocker { public: MutexLocker (Mutex & mutex); MutexLocker (Mutex * mutex); virtual ~MutexLocker (); private: Mutex * mutex_p; MutexLocker (const MutexLocker & other); // do not define MutexLocker & operator= (const MutexLocker & other); // do not define }; class ConditionImpl; class UniqueLock; class Condition { public: Condition (); virtual ~Condition (); void broadcast () __attribute__ ((deprecated)) /*"Use notify_all */; void signal () __attribute__ ((deprecated)) /* Use notify_one */; void notify_all (); void notify_one (); void wait (UniqueLock & uniqueLock); // casacore::Bool wait (Mutex & mutex, int milliseconds); private: ConditionImpl * impl_p; }; class SemaphoreImpl; class Semaphore { public: Semaphore (int initialValue = 0); ~Semaphore (); casacore::Int getValue (); void post (); casacore::Bool trywait (); void wait (); casacore::Bool wait (int milliseconds); private: SemaphoreImpl * impl_p; casacore::String name_p; Semaphore (const Semaphore & other); // illegal operation: do not define Semaphore operator= (const Semaphore & other); // illegal operation: do not define }; class Thread { public: typedef void * (* ThreadFunction) (void *); Thread (); virtual ~Thread (); pthread_t getId () const; pid_t gettid () const; // linux only bool isTerminationRequested () const; void * join (); void startThread (); virtual void terminate (); protected: bool isStarted () const; virtual void * run () = 0; static void * threadFunction (void *); private: pthread_t * id_p; bool started_p; volatile bool terminationRequested_p; }; class UniqueLock { friend class Condition; public: UniqueLock (Mutex & mutex); void lock (); void unlock (); private: std::unique_lock<std::mutex> uniqueLock_p; }; class Logger { public: // make noncopyable... Logger( const Logger& ) = delete; Logger& operator=( const Logger& ) = delete; void log (const char * format, ...); void registerName (const casacore::String & threadName); void start (const char * logFilename); static Logger * get (); protected: class LoggerThread : public Thread { public: LoggerThread (); ~LoggerThread (); void log (const string & text); void setLogFilename (const casacore::String & filename); void terminate (); protected: void * run (); private: bool deleteStream_p; casacore::String logFilename_p; Condition loggerChanged_p; std::ostream * logStream_p; Mutex mutex_p; queue<std::string> outputQueue_p; }; // void log (char * format, ...); // void setLogFilename (char * logFilename); // void terminate (); private: typedef map <pthread_t, casacore::String> ThreadNames; LoggerThread * loggerThread_p; bool loggingStarted_p; Mutex * nameMutex_p; ThreadNames threadNames_p; static Logger * singleton_p; Logger (); // singleton ~Logger (); static void initialize (); }; } } #endif /* ASYNCHRONOUSTOOLS_H_ */