CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/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 #if BOOST_VERSION >= 105000
00105     boost::xtime_get(&xt, boost::TIME_UTC_);
00106 #else
00107     boost::xtime_get(&xt, boost::TIME_UTC);
00108 #endif
00109     xt.sec += i;
00110   }
00111   
00112   operator const boost::xtime & () const { return xt;}
00113   
00114 };
00115 
00116 inline pthread_t thread_self_tid() { return pthread_self();}
00117 
00118 
00119 
00120 template<typename T>
00121 class ThreadMessage {
00122 public:
00123   typedef T Case;
00124 
00125   const Case& operator()() const {
00126     SimpleLockMutex gl(lock);
00127     doit.wait(gl());
00128     return it;
00129   }
00130   
00131   void go(const Case& i) {
00132     SimpleLockMutex gl(lock);
00133     it=i;
00134     doit.notify_all(); 
00135   }
00136   
00137   const Case& get() const { return it;} 
00138 
00139 private:
00140 
00141   mutable SimpleLockMutex::Mutex lock;
00142   mutable boost::condition doit;
00143   Case it;
00144 };
00145 
00146 namespace {
00147   template<typename T> 
00148   struct defF {
00149     T * operator()() {
00150       return new T();
00151     }
00152   };
00153 
00154 }
00155 
00156 template<typename T, typename F=defF<T> >
00157 class ThreadSingleton {
00158 public:
00159 
00160   static T & instance(F&f=factory()) {
00161     static boost::thread_specific_ptr<T> me;
00162     if (!me.get()) {
00163       T * t = buildMe(f);
00164       me.reset(t);
00165     }
00166     return *me;
00167   }
00168 
00169 private:
00170   static F & factory() {
00171     static F f;
00172     return f;
00173   }
00174 
00175   static T * buildMe(F&f) {
00176     return f();
00177   }
00178 
00179 };
00180 
00181 #endif // UTILITIES_THREADS_MUTEXUTILS_H