#ifndef MONITOR_H #define MONITOR_H #include #include #include extern "C" unsigned int sleep(unsigned int seconds); namespace util { class Monitor { public: class Token; friend class Token; private: typedef std::map DepthMap; pthread_mutex_t mutex; pthread_cond_t cond; DepthMap lockdepth; #ifndef NDEBUG bool owned; pthread_t owner; #endif void lock(Token *tok); void unlock(Token *tok); bool wait(Token *tok, const struct timespec *abstime); void wait(Token *tok); void notify(Token *tok); void notifyAll(Token *tok); ~Monitor(); public: typedef std::auto_ptr token; token getToken(); Monitor(); static bool destroyMonitor(Monitor *&mon); }; class Monitor::Token { private: friend class Monitor; #ifndef NDEBUG const pthread_t mythread; //owned by only one thread #endif Monitor *mon; #ifndef NDEBUG inline bool rightThread() { return (pthread_self()==mythread); } #endif Token(Monitor *Mon); public: //see pthread_cond_wait() and pthread_cond_timedwait() bool wait(const struct timespec *abstime = 0); //see pthread_cond_signal() void notify(); //see pthread_cond_broadcast() void notifyAll(); ~Token(); }; class Synchronizable { public: typedef const std::auto_ptr consttok; protected: Monitor *monitor; Synchronizable() : monitor(new Monitor) { } virtual ~Synchronizable() { while (!(Monitor::destroyMonitor(monitor))) sleep(10); } }; #define MONITOR_WAIT() blocksync->wait() #define MONITOR_TIMEDWAIT(x) blocksync->wait(x) #define MONITOR_NOTIFY() blocksync->notify() #define MONITOR_NOTIFY_ALL() blocksync->notifyAll() #define MONITOR_SYNCHRONIZE_BLOCK(monitor) \ util::Synchronizable::consttok blocksync(monitor->getToken()) } #endif //MONITOR_H #if 0 vim:ft=cpp #endif