/usr/include/boost/thread/testable_mutex.hpp is in libboost1.55-dev 1.55.0+dfsg-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | // (C) Copyright 2012 Vicente J. Botet Escriba
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_THREAD_TESTABLE_LOCKABLE_HPP
#define BOOST_THREAD_TESTABLE_LOCKABLE_HPP
#include <boost/thread/detail/config.hpp>
#include <boost/thread/thread_only.hpp>
#include <boost/atomic.hpp>
#include <boost/assert.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
/**
* Based on Associate Mutexes with Data to Prevent Races, By Herb Sutter, May 13, 2010
* http://www.drdobbs.com/windows/associate-mutexes-with-data-to-prevent-r/224701827?pgno=3
*
* Make our mutex testable if it isn't already.
*
* Many mutex services (including boost::mutex) don't provide a way to ask,
* "Do I already hold a lock on this mutex?"
* Sometimes it is needed to know if a method like is_locked to be available.
* This wrapper associates an arbitrary lockable type with a thread id that stores the ID of the thread that
* currently holds the lockable. The thread id initially holds an invalid value that means no threads own the mutex.
* When we acquire a lock, we set the thread id; and when we release a lock, we reset it back to its default no id state.
*
*/
template <typename Lockable>
class testable_mutex
{
Lockable mtx_;
atomic<thread::id> id_;
public:
/// the type of the wrapped lockable
typedef Lockable lockable_type;
/// Non copyable
BOOST_THREAD_NO_COPYABLE(testable_mutex)
testable_mutex() : id_(thread::id()) {}
void lock()
{
BOOST_ASSERT(! is_locked_by_this_thread());
mtx_.lock();
id_ = this_thread::get_id();
}
void unlock()
{
BOOST_ASSERT(is_locked_by_this_thread());
id_ = thread::id();
mtx_.unlock();
}
bool try_lock()
{
BOOST_ASSERT(! is_locked_by_this_thread());
if (mtx_.try_lock())
{
id_ = this_thread::get_id();
return true;
}
else
{
return false;
}
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
BOOST_ASSERT(! is_locked_by_this_thread());
if (mtx_.try_lock_for(rel_time))
{
id_ = this_thread::get_id();
return true;
}
else
{
return false;
}
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
{
BOOST_ASSERT(! is_locked_by_this_thread());
if (mtx_.try_lock_until(abs_time))
{
id_ = this_thread::get_id();
return true;
}
else
{
return false;
}
}
#endif
bool is_locked_by_this_thread() const
{
return this_thread::get_id() == id_;
}
bool is_locked() const
{
return ! (thread::id() == id_);
}
thread::id get_id() const
{
return id_;
}
// todo add the shared and upgrade mutex functions
};
template <typename Lockable>
struct is_testable_lockable : false_type
{};
template <typename Lockable>
struct is_testable_lockable<testable_mutex<Lockable> > : true_type
{};
// /**
// * Overloaded function used to check if the mutex is locked when it is testable and do nothing otherwise.
// *
// * This function is used usually to assert the pre-condition when the function can only be called when the mutex
// * must be locked by the current thread.
// */
// template <typename Lockable>
// bool is_locked_by_this_thread(testable_mutex<Lockable> const& mtx)
// {
// return mtx.is_locked();
// }
// template <typename Lockable>
// bool is_locked_by_this_thread(Lockable const&)
// {
// return true;
// }
}
#include <boost/config/abi_suffix.hpp>
#endif // header
|