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 19namespace asio { 20namespace detail { 21 22// Helper class to lock and unlock a mutex automatically. 23template <typename Mutex> 24class scoped_lock 25 : private noncopyable 26{ 27public: 28 // Tag type used to distinguish constructors. 29 enum adopt_lock_t { adopt_lock }; 30 31 // Constructor adopts a lock that is already held. 32 scoped_lock(Mutex& m, adopt_lock_t) 33 : mutex_(m), 34 locked_(true) 35 { 36 } 37 38 // Constructor acquires the lock. 39 explicit scoped_lock(Mutex& m) 40 : mutex_(m) 41 { 42 mutex_.lock(); 43 locked_ = true; 44 } 45 46 // Destructor releases the lock. 47 ~scoped_lock() 48 { 49 if (locked_) 50 mutex_.unlock(); 51 } 52 53 // Explicitly acquire the lock. 54 void lock() 55 { 56 if (!locked_) 57 { 58 mutex_.lock(); 59 locked_ = true; 60 } 61 } 62 63 // Explicitly release the lock. 64 void unlock() 65 { 66 if (locked_) 67 { 68 mutex_.unlock(); 69 locked_ = false; 70 } 71 } 72 73 // Test whether the lock is held. 74 bool locked() const 75 { 76 return locked_; 77 } 78 79 // Get the underlying mutex. 80 Mutex& mutex() 81 { 82 return mutex_; 83 } 84 85private: 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