File indexing completed on 2024-11-15 09:32:42
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_THREAD_EXTERNALLY_LOCKED_HPP
0008 #define BOOST_THREAD_EXTERNALLY_LOCKED_HPP
0009
0010 #include <boost/thread/detail/config.hpp>
0011
0012 #include <boost/thread/exceptions.hpp>
0013 #include <boost/thread/lock_concepts.hpp>
0014 #include <boost/thread/lock_traits.hpp>
0015 #include <boost/thread/lockable_concepts.hpp>
0016 #include <boost/thread/strict_lock.hpp>
0017
0018 #include <boost/static_assert.hpp>
0019 #include <boost/type_traits/is_same.hpp>
0020 #include <boost/throw_exception.hpp>
0021 #include <boost/core/invoke_swap.hpp>
0022
0023 #include <boost/config/abi_prefix.hpp>
0024
0025 namespace boost
0026 {
0027 class mutex;
0028
0029
0030
0031
0032
0033
0034
0035
0036 template <typename T, typename MutexType = boost::mutex>
0037 class externally_locked;
0038 template <typename T, typename MutexType>
0039 class externally_locked
0040 {
0041
0042 BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
0043
0044 public:
0045 typedef MutexType mutex_type;
0046
0047 BOOST_THREAD_COPYABLE_AND_MOVABLE( externally_locked )
0048
0049
0050
0051
0052 externally_locked(mutex_type& mtx, const T& obj) :
0053 obj_(obj), mtx_(&mtx)
0054 {
0055 }
0056
0057
0058
0059
0060
0061 externally_locked(mutex_type& mtx, BOOST_THREAD_RV_REF(T) obj) :
0062 obj_(move(obj)), mtx_(&mtx)
0063 {
0064 }
0065
0066
0067
0068
0069
0070 externally_locked(mutex_type& mtx)
0071 : obj_(), mtx_(&mtx)
0072 {
0073 }
0074
0075
0076
0077
0078 externally_locked(externally_locked const& rhs)
0079 : obj_(rhs.obj_), mtx_(rhs.mtx_)
0080 {
0081 }
0082
0083
0084
0085 externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs)
0086 : obj_(move(rhs.obj_)), mtx_(rhs.mtx_)
0087 {
0088 }
0089
0090
0091 externally_locked& operator=(externally_locked const& rhs)
0092 {
0093 obj_=rhs.obj_;
0094 mtx_=rhs.mtx_;
0095 return *this;
0096 }
0097
0098
0099 externally_locked& operator=(BOOST_THREAD_RV_REF(externally_locked) rhs)
0100 {
0101 obj_=move(BOOST_THREAD_RV(rhs).obj_);
0102 mtx_=rhs.mtx_;
0103 return *this;
0104 }
0105
0106 void swap(externally_locked& rhs)
0107 {
0108 boost::core::invoke_swap(obj_, rhs.obj_);
0109 boost::core::invoke_swap(mtx_, rhs.mtx_);
0110 }
0111
0112
0113
0114
0115
0116
0117
0118
0119 T& get(strict_lock<mutex_type>& lk)
0120 {
0121 BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() );
0122 return obj_;
0123 }
0124
0125 const T& get(strict_lock<mutex_type>& lk) const
0126 {
0127 BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() );
0128 return obj_;
0129 }
0130
0131 template <class Lock>
0132 T& get(nested_strict_lock<Lock>& lk)
0133 {
0134 BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value));
0135 BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() );
0136 return obj_;
0137 }
0138
0139 template <class Lock>
0140 const T& get(nested_strict_lock<Lock>& lk) const
0141 {
0142 BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value));
0143 BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() );
0144 return obj_;
0145 }
0146
0147
0148
0149
0150
0151
0152
0153 template <class Lock>
0154 T& get(Lock& lk)
0155 {
0156 BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
0157 BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value));
0158 BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value));
0159
0160 BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() );
0161
0162 return obj_;
0163 }
0164
0165 mutex_type* mutex() const BOOST_NOEXCEPT
0166 {
0167 return mtx_;
0168 }
0169
0170
0171
0172 void lock()
0173 {
0174 mtx_->lock();
0175 }
0176 void unlock()
0177 {
0178 mtx_->unlock();
0179 }
0180 bool try_lock()
0181 {
0182 return mtx_->try_lock();
0183 }
0184
0185
0186 private:
0187 T obj_;
0188 mutex_type* mtx_;
0189 };
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199 template <typename T, typename MutexType>
0200 class externally_locked<T&, MutexType>
0201 {
0202
0203 BOOST_CONCEPT_ASSERT(( BasicLockable<MutexType> ));
0204
0205 public:
0206 typedef MutexType mutex_type;
0207
0208 BOOST_THREAD_COPYABLE_AND_MOVABLE( externally_locked )
0209
0210
0211
0212
0213 externally_locked(T& obj, mutex_type& mtx) BOOST_NOEXCEPT :
0214 obj_(&obj), mtx_(&mtx)
0215 {
0216 }
0217
0218
0219 externally_locked(externally_locked const& rhs) BOOST_NOEXCEPT :
0220 obj_(rhs.obj_), mtx_(rhs.mtx_)
0221 {
0222 }
0223
0224
0225 externally_locked(BOOST_THREAD_RV_REF(externally_locked) rhs) BOOST_NOEXCEPT :
0226 obj_(rhs.obj_), mtx_(rhs.mtx_)
0227 {
0228 }
0229
0230
0231 externally_locked& operator=(externally_locked const& rhs) BOOST_NOEXCEPT
0232 {
0233 obj_=rhs.obj_;
0234 mtx_=rhs.mtx_;
0235 return *this;
0236 }
0237
0238
0239 externally_locked& operator=(BOOST_THREAD_RV_REF(externally_locked) rhs) BOOST_NOEXCEPT
0240 {
0241 obj_=rhs.obj_;
0242 mtx_=rhs.mtx_;
0243 return *this;
0244 }
0245
0246 void swap(externally_locked& rhs) BOOST_NOEXCEPT
0247 {
0248 boost::core::invoke_swap(obj_, rhs.obj_);
0249 boost::core::invoke_swap(mtx_, rhs.mtx_);
0250 }
0251
0252
0253
0254
0255
0256
0257
0258 T& get(strict_lock<mutex_type> const& lk)
0259 {
0260 BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() );
0261 return *obj_;
0262 }
0263
0264 const T& get(strict_lock<mutex_type> const& lk) const
0265 {
0266 BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() );
0267 return *obj_;
0268 }
0269
0270 template <class Lock>
0271 T& get(nested_strict_lock<Lock> const& lk)
0272 {
0273 BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value));
0274 BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() );
0275 return *obj_;
0276 }
0277
0278 template <class Lock>
0279 const T& get(nested_strict_lock<Lock> const& lk) const
0280 {
0281 BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value));
0282 BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() );
0283 return *obj_;
0284 }
0285
0286
0287
0288
0289
0290
0291
0292 template <class Lock>
0293 T& get(Lock const& lk)
0294 {
0295 BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
0296 BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value));
0297 BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value));
0298 BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() );
0299 return *obj_;
0300 }
0301
0302
0303
0304
0305
0306
0307
0308 template <class Lock>
0309 T const& get(Lock const& lk) const
0310 {
0311 BOOST_CONCEPT_ASSERT(( StrictLock<Lock> ));
0312 BOOST_STATIC_ASSERT( (is_strict_lock<Lock>::value));
0313 BOOST_STATIC_ASSERT( (is_same<mutex_type, typename Lock::mutex_type>::value));
0314 BOOST_THREAD_ASSERT_PRECONDITION( lk.owns_lock(mtx_), lock_error() );
0315 return *obj_;
0316 }
0317 mutex_type* mutex() const BOOST_NOEXCEPT
0318 {
0319 return mtx_;
0320 }
0321
0322 void lock()
0323 {
0324 mtx_->lock();
0325 }
0326 void unlock()
0327 {
0328 mtx_->unlock();
0329 }
0330 bool try_lock()
0331 {
0332 return mtx_->try_lock();
0333 }
0334
0335
0336 protected:
0337 T* obj_;
0338 mutex_type* mtx_;
0339 };
0340
0341
0342 template <typename T, typename MutexType>
0343 void swap(externally_locked<T, MutexType> & lhs, externally_locked<T, MutexType> & rhs)
0344 {
0345 lhs.swap(rhs);
0346 }
0347
0348 }
0349
0350 #include <boost/config/abi_suffix.hpp>
0351
0352 #endif