1 // (C) Copyright 2012 Vicente Botet 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #ifndef BOOST_THREAD_LOCKABLE_CONCEPTS_HPP 7 #define BOOST_THREAD_LOCKABLE_CONCEPTS_HPP 8 9 #include <boost/chrono/chrono.hpp> 10 #include <boost/concept_check.hpp> 11 12 namespace boost 13 { 14 15 /** 16 * BasicLockable object supports the basic features 17 * required to delimit a critical region 18 * Supports the basic lock and unlock functions. 19 */ 20 21 //[BasicLockable 22 template <typename Mutex> 23 struct BasicLockable 24 { 25 BOOST_CONCEPT_USAGEboost::BasicLockable26 BOOST_CONCEPT_USAGE(BasicLockable) 27 { 28 l.lock(); 29 l.unlock(); 30 } BasicLockableboost::BasicLockable31 BasicLockable() : l(*static_cast<Mutex*>(0)) {} 32 private: 33 BasicLockable operator=(BasicLockable const&); 34 35 Mutex& l; 36 } 37 ; 38 //] 39 /** 40 * Lockable extends BasicLockable 41 * with try_lock functions. 42 */ 43 44 //[Lockable 45 template <typename Mutex> 46 struct Lockable 47 { 48 BOOST_CONCEPT_ASSERT(( BasicLockable<Mutex> )); 49 BOOST_CONCEPT_USAGEboost::Lockable50 BOOST_CONCEPT_USAGE(Lockable) 51 { 52 if (l.try_lock()) return; 53 } Lockableboost::Lockable54 Lockable() : l(*static_cast<Mutex*>(0)) {} 55 private: 56 Lockable operator=(Lockable const&); 57 Mutex& l; 58 }; 59 //] 60 61 /** 62 * TimedLockable object extends Lockable 63 * with timed lock functions: try_lock_until and try_lock_for and the exception based lock_until and lock_for 64 */ 65 66 //[TimedLockable 67 template <typename Mutex> 68 struct TimedLockable 69 { 70 BOOST_CONCEPT_ASSERT(( Lockable<Mutex> )); 71 BOOST_CONCEPT_USAGEboost::TimedLockable72 BOOST_CONCEPT_USAGE(TimedLockable) 73 { 74 if (l.try_lock_until(t)) return; 75 if (l.try_lock_for(d)) return; 76 } TimedLockableboost::TimedLockable77 TimedLockable() : l(*static_cast<Mutex*>(0)) {} 78 private: 79 TimedLockable operator=(TimedLockable const&); 80 Mutex& l; 81 chrono::system_clock::time_point t; 82 chrono::system_clock::duration d; 83 }; 84 //] 85 86 /** 87 * SharedLockable object extends TimedLockable 88 * with the lock_shared, lock_shared_until, lock_shared_for, try_lock_shared_until, try_lock_shared 89 * and unlock_shared functions 90 */ 91 //[SharedLockable 92 template <typename Mutex> 93 struct SharedLockable 94 { 95 BOOST_CONCEPT_ASSERT(( TimedLockable<Mutex> )); 96 BOOST_CONCEPT_USAGEboost::SharedLockable97 BOOST_CONCEPT_USAGE(SharedLockable) 98 { 99 l.lock_shared(); 100 l.unlock_shared(); 101 if (l.try_lock_shared()) return; 102 if (l.try_lock_shared_until(t)) return; 103 if (l.try_lock_shared_for(d)) return; 104 } SharedLockableboost::SharedLockable105 SharedLockable() : l(*static_cast<Mutex*>(0)) {} 106 private: 107 SharedLockable operator=(SharedLockable const&); 108 Mutex& l; 109 chrono::system_clock::time_point t; 110 chrono::system_clock::duration d; 111 }; 112 //] 113 114 /** 115 * UpgradeLockable object extends SharedLockable 116 * with the lock_upgrade, lock_upgrade_until, unlock_upgrade_and_lock, 117 * unlock_and_lock_shared and unlock_upgrade_and_lock_shared functions 118 */ 119 120 //[UpgradeLockable 121 template <typename Mutex> 122 struct UpgradeLockable 123 { 124 BOOST_CONCEPT_ASSERT(( SharedLockable<Mutex> )); 125 BOOST_CONCEPT_USAGEboost::UpgradeLockable126 BOOST_CONCEPT_USAGE(UpgradeLockable) 127 { 128 l.lock_upgrade(); 129 l.unlock_upgrade(); 130 if (l.try_lock_upgrade()) return; 131 if (l.try_lock_upgrade_until(t)) return; 132 if (l.try_lock_upgrade_for(d)) return; 133 if (l.try_unlock_shared_and_lock()) return; 134 if (l.try_unlock_shared_and_lock_until(t)) return; 135 if (l.try_unlock_shared_and_lock_for(d)) return; 136 l.unlock_and_lock_shared(); 137 if (l.try_unlock_shared_and_lock_upgrade()) return; 138 if (l.try_unlock_shared_and_lock_upgrade_until(t)) return; 139 if (l.try_unlock_shared_and_lock_upgrade_for(d)) return; 140 l.unlock_and_lock_upgrade(); 141 l.unlock_upgrade_and_lock(); 142 if (l.try_unlock_upgrade_and_lock()) return; 143 if (l.try_unlock_upgrade_and_lock_until(t)) return; 144 if (l.try_unlock_upgrade_and_lock_for(d)) return; 145 l.unlock_upgrade_and_lock_shared(); 146 } UpgradeLockableboost::UpgradeLockable147 UpgradeLockable() : l(*static_cast<Mutex*>(0)) {} 148 private: 149 UpgradeLockable operator=(UpgradeLockable const&); 150 Mutex& l; 151 chrono::system_clock::time_point t; 152 chrono::system_clock::duration d; 153 }; 154 //] 155 156 } 157 #endif 158