1    	//
2    	// detail/scoped_lock.hpp
3    	// ~~~~~~~~~~~~~~~~~~~~~~
4    	//
5    	// Copyright (c) 2003-2018 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 BOOST_ASIO_DETAIL_SCOPED_LOCK_HPP
12   	#define BOOST_ASIO_DETAIL_SCOPED_LOCK_HPP
13   	
14   	#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15   	# pragma once
16   	#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17   	
18   	#include <boost/asio/detail/noncopyable.hpp>
19   	
20   	#include <boost/asio/detail/push_options.hpp>
21   	
22   	namespace boost {
23   	namespace asio {
24   	namespace detail {
25   	
26   	// Helper class to lock and unlock a mutex automatically.
27   	template <typename Mutex>
28   	class scoped_lock
29   	  : private noncopyable
30   	{
31   	public:
32   	  // Tag type used to distinguish constructors.
33   	  enum adopt_lock_t { adopt_lock };
34   	
35   	  // Constructor adopts a lock that is already held.
36   	  scoped_lock(Mutex& m, adopt_lock_t)
37   	    : mutex_(m),
38   	      locked_(true)
39   	  {
40   	  }
41   	
42   	  // Constructor acquires the lock.
43   	  explicit scoped_lock(Mutex& m)
44   	    : mutex_(m)
45   	  {
46   	    mutex_.lock();
47   	    locked_ = true;
48   	  }
49   	
50   	  // Destructor releases the lock.
51   	  ~scoped_lock()
52   	  {
53   	    if (locked_)
54   	      mutex_.unlock();
55   	  }
56   	
57   	  // Explicitly acquire the lock.
58   	  void lock()
59   	  {
60   	    if (!locked_)
61   	    {
(3) Event example_lock: Example 1: Locking "boost::asio::detail::posix_mutex.mutex_".
Also see events: [missing_lock][example_access]
62   	      mutex_.lock();
(4) Event example_access: Example 1 (cont.): "boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>.locked_" is accessed with lock "boost::asio::detail::posix_mutex.mutex_" held.
Also see events: [missing_lock][example_lock]
63   	      locked_ = true;
64   	    }
65   	  }
66   	
67   	  // Explicitly release the lock.
68   	  void unlock()
69   	  {
(1) Event cond_true: Condition "this->locked_", taking true branch.
70   	    if (locked_)
71   	    {
72   	      mutex_.unlock();
(2) Event missing_lock: Accessing "this->locked_" without holding lock "boost::asio::detail::posix_mutex.mutex_". Elsewhere, "_ZN5boost4asio6detail11scoped_lockINS1_11posix_mutexEEE.locked_" is accessed with "boost::asio::detail::posix_mutex.mutex_" held 1 out of 2 times (1 of these accesses strongly imply that it is necessary).
Also see events: [example_lock][example_access]
73   	      locked_ = false;
74   	    }
75   	  }
76   	
77   	  // Test whether the lock is held.
78   	  bool locked() const
79   	  {
80   	    return locked_;
81   	  }
82   	
83   	  // Get the underlying mutex.
84   	  Mutex& mutex()
85   	  {
86   	    return mutex_;
87   	  }
88   	
89   	private:
90   	  // The underlying mutex.
91   	  Mutex& mutex_;
92   	
93   	  // Whether the mutex is currently locked or unlocked.
94   	  bool locked_;
95   	};
96   	
97   	} // namespace detail
98   	} // namespace asio
99   	} // namespace boost
100  	
101  	#include <boost/asio/detail/pop_options.hpp>
102  	
103  	#endif // BOOST_ASIO_DETAIL_SCOPED_LOCK_HPP
104