00001 #ifndef UTILITIES_GENERAL_MUTEXUTILS_H 00002 #define UTILITIES_GENERAL_MUTEXUTILS_H 00003 // 00004 // thread Utilities... 00005 // 00006 #include <boost/thread/recursive_mutex.hpp> 00007 #include <boost/thread/mutex.hpp> 00008 #include <boost/thread/xtime.hpp> 00009 #include <boost/thread/condition.hpp> 00010 #include <boost/thread/tss.hpp> 00011 00012 #include <iosfwd> 00013 00014 class MutexI { 00015 public: 00016 virtual ~MutexI(){} 00017 virtual void lock()=0; 00018 virtual void unlock()=0; 00019 00020 class scoped_lock { 00021 MutexI & m; 00022 public: 00023 scoped_lock(MutexI& im) :m(im) { m.lock();} 00024 ~scoped_lock() { m.unlock();} 00025 }; 00026 00027 }; 00028 00029 struct DummyMutex : public MutexI { 00030 void lock(){} 00031 void unlock(){} 00032 }; 00033 00034 template<class M=boost::recursive_mutex> 00035 class AnyMutex : public MutexI { 00036 M & m; 00037 public: 00038 typedef M Mutex; 00039 typedef MutexI::scoped_lock scoped_lock; 00040 AnyMutex(M & im) : m(im){} 00041 void lock() { m.lock();} 00042 void unlock() { m.unlock();} 00043 }; 00044 00045 00046 std::ostream & TSafeOstream(); 00047 00048 00049 template<class M> 00050 class lockSentry { 00051 public: 00052 typedef M Mutex; 00053 00054 explicit lockSentry(M& im) :m(im) {} 00055 ~lockSentry() {} 00056 00057 operator typename M::scoped_lock & () { return m;} 00058 typename M::scoped_lock & operator()() { return m;} 00059 00060 private: 00061 typename M::scoped_lock m; 00062 00063 }; 00064 00065 typedef lockSentry<boost::recursive_mutex> LockMutex; 00066 00067 typedef lockSentry<boost::mutex> SimpleLockMutex; 00068 00069 namespace Capri { 00070 00071 // the global mutex... 00072 extern LockMutex::Mutex glMutex; 00073 00074 } 00075 00076 00077 template<class M=boost::recursive_mutex> 00078 struct ThreadTraits { 00079 00080 typedef M Mutex; 00081 00083 template<class T> static Mutex & myMutex(const T*) { 00084 static Mutex locm; 00085 return locm; 00086 } 00087 00088 00089 }; 00090 00091 00092 template<class T, class M=boost::recursive_mutex> 00093 class classLock : private lockSentry<M> { 00094 public: 00095 explicit classLock(const T* me) : lockSentry<M>(ThreadTraits<M>::myMutex(me)){} 00096 ~classLock(){} 00097 }; 00098 00099 00100 struct boostFuture { 00101 boost::xtime xt; 00102 00103 boostFuture(int i) { 00104 boost::xtime_get(&xt, boost::TIME_UTC); 00105 xt.sec += i; 00106 } 00107 00108 operator const boost::xtime & () const { return xt;} 00109 00110 }; 00111 00112 inline pthread_t thread_self_tid() { return pthread_self();} 00113 00114 00115 00116 template<typename T> 00117 class ThreadMessage { 00118 public: 00119 typedef T Case; 00120 00121 const Case& operator()() const { 00122 SimpleLockMutex gl(lock); 00123 doit.wait(gl()); 00124 return it; 00125 } 00126 00127 void go(const Case& i) { 00128 SimpleLockMutex gl(lock); 00129 it=i; 00130 doit.notify_all(); 00131 } 00132 00133 const Case& get() const { return it;} 00134 00135 private: 00136 00137 mutable SimpleLockMutex::Mutex lock; 00138 mutable boost::condition doit; 00139 Case it; 00140 }; 00141 00142 namespace { 00143 template<typename T> 00144 struct defF { 00145 T * operator()() { 00146 return new T(); 00147 } 00148 }; 00149 00150 } 00151 00152 template<typename T, typename F=defF<T> > 00153 class ThreadSingleton { 00154 public: 00155 00156 static T & instance(F&f=factory()) { 00157 static boost::thread_specific_ptr<T> me; 00158 if (!me.get()) { 00159 T * t = buildMe(f); 00160 me.reset(t); 00161 } 00162 return *me; 00163 } 00164 00165 private: 00166 static F & factory() { 00167 static F f; 00168 return f; 00169 } 00170 00171 static T * buildMe(F&f) { 00172 return f(); 00173 } 00174 00175 }; 00176 00177 #endif // UTILITIES_THREADS_MUTEXUTILS_H