CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/Utilities/General/interface/MutexUtils.h

Go to the documentation of this file.
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