00001 ////////////////////////////////////////////////////////////////////////// 00002 // This material is provided "as is", with absolutely no warranty 00003 // expressed or implied. Any use is at your own risk. 00004 // 00005 // Permission to use or copy this software for any purpose is hereby 00006 // granted without fee, provided the above notices are retained on all 00007 // copies. Permission to modify the code and to distribute modified code 00008 // is granted, provided the above notices are retained, and a notice that 00009 // the code was modified is included with the above copyright notice. 00010 ////////////////////////////////////////////////////////////////////////// 00011 /** @file 00012 @brief Synchronization tools. 00013 00014 This header file contains declaration of the intra-process 00015 and inter-process synchronization tools. 00016 00017 @author Sergey Polichnoy 00018 */ 00019 #ifndef __OMNI_SYNC_HPP_ 00020 #define __OMNI_SYNC_HPP_ 00021 00022 #include <omni/defs.hpp> 00023 00024 namespace omni 00025 { 00026 namespace sync 00027 { 00028 00029 ////////////////////////////////////////////////////////////////////////// 00030 /// @brief %Lockable interface. 00031 /** 00032 This class is used as interface for the some synchronization objects. 00033 The public interface contains two methods: 00034 - enter() - lock synchronization object, 00035 - leave() - unlock synchronization object. 00036 00037 It is recommended to use Locker guard class 00038 instead direct enter()/leave() method calling. 00039 00040 @see Locker 00041 */ 00042 class Lockable { 00043 protected: 00044 Lockable() {} ///< @brief Trivial constructor. 00045 ~Lockable() {} ///< @brief Trivial destructor. 00046 00047 public: 00048 virtual void enter() = 0; 00049 virtual void leave() = 0; 00050 }; 00051 00052 00053 ////////////////////////////////////////////////////////////////////////// 00054 /// @brief %Locker guard. 00055 /** 00056 This class holds the synchronization object: constructor locks 00057 this object and destructor unlocks this object. 00058 00059 For example, the following code: 00060 00061 @code 00062 void f(Lockable &x) 00063 { 00064 x.enter(); 00065 // ... 00066 x.leave(); 00067 } 00068 @endcode 00069 00070 can be rewritten as: 00071 00072 @code 00073 void f(Lockable &x) 00074 { 00075 Locker guard(x); 00076 // ... 00077 } 00078 @endcode 00079 00080 Even exception was thrown during function execution, the 00081 synchronization object will be properly unlocked. 00082 */ 00083 class Locker: private omni::NonCopyable { 00084 public: 00085 explicit Locker(Lockable &lock); 00086 ~Locker(); 00087 00088 private: 00089 Lockable &m_lock; 00090 }; 00091 00092 00093 ////////////////////////////////////////////////////////////////////////// 00094 /// @brief Critical Section synchronization object. 00095 /** 00096 This class is used for intra-process synchronization. 00097 00098 It implements Lockable interface for @b Win32 and @b *nix 00099 platform (based on @b CRITICAL_SECTION structure for @b Win32 00100 and on pthread_mutex for @b *nix). 00101 */ 00102 class CriticalSection: public Lockable, 00103 private omni::NonCopyable { 00104 public: 00105 CriticalSection(); 00106 ~CriticalSection(); 00107 00108 public: // Lockable interface 00109 virtual void enter(); 00110 virtual void leave(); 00111 00112 private: 00113 class Impl; 00114 Impl *impl; 00115 }; 00116 00117 } // sync namespace 00118 } // omni namespace 00119 00120 #endif // __OMNI_SYNC_HPP_