1 // 2 // detail/scoped_lock.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 11 #ifndef ASIO_DETAIL_SCOPED_LOCK_HPP 12 #define ASIO_DETAIL_SCOPED_LOCK_HPP 13 14 15 #include "asio/detail/noncopyable.hpp" 16 17 #include "asio/detail/push_options.hpp" 18 19 namespace asio { 20 namespace detail { 21 22 // Helper class to lock and unlock a mutex automatically. 23 template <typename Mutex> 24 class scoped_lock 25 : private noncopyable 26 { 27 public: 28 // Tag type used to distinguish constructors. 29 enum adopt_lock_t { adopt_lock }; 30 31 // Constructor adopts a lock that is already held. scoped_lock(Mutex & m,adopt_lock_t)32 scoped_lock(Mutex& m, adopt_lock_t) 33 : mutex_(m), 34 locked_(true) 35 { 36 } 37 38 // Constructor acquires the lock. scoped_lock(Mutex & m)39 explicit scoped_lock(Mutex& m) 40 : mutex_(m) 41 { 42 mutex_.lock(); 43 locked_ = true; 44 } 45 46 // Destructor releases the lock. ~scoped_lock()47 ~scoped_lock() 48 { 49 if (locked_) 50 mutex_.unlock(); 51 } 52 53 // Explicitly acquire the lock. lock()54 void lock() 55 { 56 if (!locked_) 57 { 58 mutex_.lock(); 59 locked_ = true; 60 } 61 } 62 63 // Explicitly release the lock. unlock()64 void unlock() 65 { 66 if (locked_) 67 { 68 mutex_.unlock(); 69 locked_ = false; 70 } 71 } 72 73 // Test whether the lock is held. locked() const74 bool locked() const 75 { 76 return locked_; 77 } 78 79 // Get the underlying mutex. mutex()80 Mutex& mutex() 81 { 82 return mutex_; 83 } 84 85 private: 86 // The underlying mutex. 87 Mutex& mutex_; 88 89 // Whether the mutex is currently locked or unlocked. 90 bool locked_; 91 }; 92 93 } // namespace detail 94 } // namespace asio 95 96 #include "asio/detail/pop_options.hpp" 97 98 #endif // ASIO_DETAIL_SCOPED_LOCK_HPP 99