bitcore-node-zcash/deps/boost/thread/v2/shared_mutex.hpp

1063 lines
29 KiB
C++
Executable File

#ifndef BOOST_THREAD_V2_SHARED_MUTEX_HPP
#define BOOST_THREAD_V2_SHARED_MUTEX_HPP
// shared_mutex.hpp
//
// Copyright Howard Hinnant 2007-2010.
// Copyright Vicente J. Botet Escriba 2012.
//
// 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)
/*
<shared_mutex> synopsis
namespace boost
{
namespace thread_v2
{
class shared_mutex
{
public:
shared_mutex();
~shared_mutex();
shared_mutex(const shared_mutex&) = delete;
shared_mutex& operator=(const shared_mutex&) = delete;
// Exclusive ownership
void lock();
bool try_lock();
template <class Rep, class Period>
bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
void unlock();
// Shared ownership
void lock_shared();
bool try_lock_shared();
template <class Rep, class Period>
bool
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
void unlock_shared();
};
class upgrade_mutex
{
public:
upgrade_mutex();
~upgrade_mutex();
upgrade_mutex(const upgrade_mutex&) = delete;
upgrade_mutex& operator=(const upgrade_mutex&) = delete;
// Exclusive ownership
void lock();
bool try_lock();
template <class Rep, class Period>
bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
void unlock();
// Shared ownership
void lock_shared();
bool try_lock_shared();
template <class Rep, class Period>
bool
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
void unlock_shared();
// Upgrade ownership
void lock_upgrade();
bool try_lock_upgrade();
template <class Rep, class Period>
bool
try_lock_upgrade_for(
const boost::chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
void unlock_upgrade();
// Shared <-> Exclusive
bool try_unlock_shared_and_lock();
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_for(
const boost::chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
void unlock_and_lock_shared();
// Shared <-> Upgrade
bool try_unlock_shared_and_lock_upgrade();
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_upgrade_for(
const boost::chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
void unlock_upgrade_and_lock_shared();
// Upgrade <-> Exclusive
void unlock_upgrade_and_lock();
bool try_unlock_upgrade_and_lock();
template <class Rep, class Period>
bool
try_unlock_upgrade_and_lock_for(
const boost::chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_unlock_upgrade_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
void unlock_and_lock_upgrade();
};
} // thread_v2
} // boost
*/
#include <boost/thread/detail/config.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/chrono.hpp>
#include <climits>
#include <boost/system/system_error.hpp>
#define BOOST_THREAD_INLINE inline
namespace boost {
namespace thread_v2 {
class shared_mutex
{
typedef ::boost::mutex mutex_t;
typedef ::boost::condition_variable cond_t;
typedef unsigned count_t;
mutex_t mut_;
cond_t gate1_;
cond_t gate2_;
count_t state_;
static const count_t write_entered_ = 1U << (sizeof(count_t)*CHAR_BIT - 1);
static const count_t n_readers_ = ~write_entered_;
public:
BOOST_THREAD_INLINE shared_mutex();
BOOST_THREAD_INLINE ~shared_mutex();
#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
shared_mutex(shared_mutex const&) = delete;
shared_mutex& operator=(shared_mutex const&) = delete;
#else // BOOST_NO_CXX11_DELETED_FUNCTIONS
private:
shared_mutex(shared_mutex const&);
shared_mutex& operator=(shared_mutex const&);
public:
#endif // BOOST_NO_CXX11_DELETED_FUNCTIONS
// Exclusive ownership
BOOST_THREAD_INLINE void lock();
BOOST_THREAD_INLINE bool try_lock();
template <class Rep, class Period>
bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_lock_until(boost::chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
BOOST_THREAD_INLINE void unlock();
// Shared ownership
BOOST_THREAD_INLINE void lock_shared();
BOOST_THREAD_INLINE bool try_lock_shared();
template <class Rep, class Period>
bool
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_lock_shared_until(boost::chrono::steady_clock::now() +
rel_time);
}
template <class Clock, class Duration>
bool
try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
BOOST_THREAD_INLINE void unlock_shared();
#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(system_time const& timeout);
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time)
{
return timed_lock(get_system_time()+relative_time);
}
bool timed_lock_shared(system_time const& timeout);
template<typename TimeDuration>
bool timed_lock_shared(TimeDuration const & relative_time)
{
return timed_lock_shared(get_system_time()+relative_time);
}
#endif
};
template <class Clock, class Duration>
bool
shared_mutex::try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ & write_entered_)
{
while (true)
{
boost::cv_status status = gate1_.wait_until(lk, abs_time);
if ((state_ & write_entered_) == 0)
break;
if (status == boost::cv_status::timeout)
return false;
}
}
state_ |= write_entered_;
if (state_ & n_readers_)
{
while (true)
{
boost::cv_status status = gate2_.wait_until(lk, abs_time);
if ((state_ & n_readers_) == 0)
break;
if (status == boost::cv_status::timeout)
{
state_ &= ~write_entered_;
return false;
}
}
}
return true;
}
template <class Clock, class Duration>
bool
shared_mutex::try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
{
while (true)
{
boost::cv_status status = gate1_.wait_until(lk, abs_time);
if ((state_ & write_entered_) == 0 &&
(state_ & n_readers_) < n_readers_)
break;
if (status == boost::cv_status::timeout)
return false;
}
}
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= num_readers;
return true;
}
#if defined BOOST_THREAD_USES_DATETIME
bool shared_mutex::timed_lock(system_time const& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ & write_entered_)
{
while (true)
{
bool status = gate1_.timed_wait(lk, abs_time);
if ((state_ & write_entered_) == 0)
break;
if (!status)
return false;
}
}
state_ |= write_entered_;
if (state_ & n_readers_)
{
while (true)
{
bool status = gate2_.timed_wait(lk, abs_time);
if ((state_ & n_readers_) == 0)
break;
if (!status)
{
state_ &= ~write_entered_;
return false;
}
}
}
return true;
}
bool shared_mutex::timed_lock_shared(system_time const& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ & write_entered_)
{
while (true)
{
bool status = gate1_.timed_wait(lk, abs_time);
if ((state_ & write_entered_) == 0)
break;
if (!status )
return false;
}
}
state_ |= write_entered_;
if (state_ & n_readers_)
{
while (true)
{
bool status = gate2_.timed_wait(lk, abs_time);
if ((state_ & n_readers_) == 0)
break;
if (!status)
{
state_ &= ~write_entered_;
return false;
}
}
}
return true;
}
#endif
class upgrade_mutex
{
typedef boost::mutex mutex_t;
typedef boost::condition_variable cond_t;
typedef unsigned count_t;
mutex_t mut_;
cond_t gate1_;
cond_t gate2_;
count_t state_;
static const unsigned write_entered_ = 1U << (sizeof(count_t)*CHAR_BIT - 1);
static const unsigned upgradable_entered_ = write_entered_ >> 1;
static const unsigned n_readers_ = ~(write_entered_ | upgradable_entered_);
public:
BOOST_THREAD_INLINE upgrade_mutex();
BOOST_THREAD_INLINE ~upgrade_mutex();
#ifndef BOOST_CXX11_NO_DELETED_FUNCTIONS
upgrade_mutex(const upgrade_mutex&) = delete;
upgrade_mutex& operator=(const upgrade_mutex&) = delete;
#else // BOOST_CXX11_NO_DELETED_FUNCTIONS
private:
upgrade_mutex(const upgrade_mutex&);
upgrade_mutex& operator=(const upgrade_mutex&);
public:
#endif // BOOST_CXX11_NO_DELETED_FUNCTIONS
// Exclusive ownership
BOOST_THREAD_INLINE void lock();
BOOST_THREAD_INLINE bool try_lock();
template <class Rep, class Period>
bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_lock_until(boost::chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
BOOST_THREAD_INLINE void unlock();
// Shared ownership
BOOST_THREAD_INLINE void lock_shared();
BOOST_THREAD_INLINE bool try_lock_shared();
template <class Rep, class Period>
bool
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_lock_shared_until(boost::chrono::steady_clock::now() +
rel_time);
}
template <class Clock, class Duration>
bool
try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
BOOST_THREAD_INLINE void unlock_shared();
// Upgrade ownership
BOOST_THREAD_INLINE void lock_upgrade();
BOOST_THREAD_INLINE bool try_lock_upgrade();
template <class Rep, class Period>
bool
try_lock_upgrade_for(
const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_lock_upgrade_until(boost::chrono::steady_clock::now() +
rel_time);
}
template <class Clock, class Duration>
bool
try_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
BOOST_THREAD_INLINE void unlock_upgrade();
// Shared <-> Exclusive
BOOST_THREAD_INLINE bool try_unlock_shared_and_lock();
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_for(
const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_shared_and_lock_until(
boost::chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
BOOST_THREAD_INLINE void unlock_and_lock_shared();
// Shared <-> Upgrade
BOOST_THREAD_INLINE bool try_unlock_shared_and_lock_upgrade();
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_upgrade_for(
const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_shared_and_lock_upgrade_until(
boost::chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
BOOST_THREAD_INLINE void unlock_upgrade_and_lock_shared();
// Upgrade <-> Exclusive
BOOST_THREAD_INLINE void unlock_upgrade_and_lock();
BOOST_THREAD_INLINE bool try_unlock_upgrade_and_lock();
template <class Rep, class Period>
bool
try_unlock_upgrade_and_lock_for(
const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_upgrade_and_lock_until(
boost::chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_upgrade_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
BOOST_THREAD_INLINE void unlock_and_lock_upgrade();
#if defined BOOST_THREAD_USES_DATETIME
inline bool timed_lock(system_time const& abs_time);
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time)
{
return timed_lock(get_system_time()+relative_time);
}
inline bool timed_lock_shared(system_time const& abs_time);
template<typename TimeDuration>
bool timed_lock_shared(TimeDuration const & relative_time)
{
return timed_lock_shared(get_system_time()+relative_time);
}
inline bool timed_lock_upgrade(system_time const& abs_time);
template<typename TimeDuration>
bool timed_lock_upgrade(TimeDuration const & relative_time)
{
return timed_lock_upgrade(get_system_time()+relative_time);
}
#endif
};
template <class Clock, class Duration>
bool
upgrade_mutex::try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ & (write_entered_ | upgradable_entered_))
{
while (true)
{
boost::cv_status status = gate1_.wait_until(lk, abs_time);
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
break;
if (status == boost::cv_status::timeout)
return false;
}
}
state_ |= write_entered_;
if (state_ & n_readers_)
{
while (true)
{
boost::cv_status status = gate2_.wait_until(lk, abs_time);
if ((state_ & n_readers_) == 0)
break;
if (status == boost::cv_status::timeout)
{
state_ &= ~write_entered_;
return false;
}
}
}
return true;
}
template <class Clock, class Duration>
bool
upgrade_mutex::try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
{
while (true)
{
boost::cv_status status = gate1_.wait_until(lk, abs_time);
if ((state_ & write_entered_) == 0 &&
(state_ & n_readers_) < n_readers_)
break;
if (status == boost::cv_status::timeout)
return false;
}
}
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= num_readers;
return true;
}
template <class Clock, class Duration>
bool
upgrade_mutex::try_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & (write_entered_ | upgradable_entered_)) ||
(state_ & n_readers_) == n_readers_)
{
while (true)
{
boost::cv_status status = gate1_.wait_until(lk, abs_time);
if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
(state_ & n_readers_) < n_readers_)
break;
if (status == boost::cv_status::timeout)
return false;
}
}
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= upgradable_entered_ | num_readers;
return true;
}
#if defined BOOST_THREAD_USES_DATETIME
bool upgrade_mutex::timed_lock(system_time const& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ & (write_entered_ | upgradable_entered_))
{
while (true)
{
bool status = gate1_.timed_wait(lk, abs_time);
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
break;
if (!status)
return false;
}
}
state_ |= write_entered_;
if (state_ & n_readers_)
{
while (true)
{
bool status = gate2_.timed_wait(lk, abs_time);
if ((state_ & n_readers_) == 0)
break;
if (!status)
{
state_ &= ~write_entered_;
return false;
}
}
}
return true;
}
bool upgrade_mutex::timed_lock_shared(system_time const& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
{
while (true)
{
bool status = gate1_.timed_wait(lk, abs_time);
if ((state_ & write_entered_) == 0 &&
(state_ & n_readers_) < n_readers_)
break;
if (!status)
return false;
}
}
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= num_readers;
return true;
}
bool upgrade_mutex::timed_lock_upgrade(system_time const& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & (write_entered_ | upgradable_entered_)) ||
(state_ & n_readers_) == n_readers_)
{
while (true)
{
bool status = gate1_.timed_wait(lk, abs_time);
if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
(state_ & n_readers_) < n_readers_)
break;
if (!status)
return false;
}
}
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= upgradable_entered_ | num_readers;
return true;
}
#endif
template <class Clock, class Duration>
bool
upgrade_mutex::try_unlock_shared_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ != 1)
{
while (true)
{
boost::cv_status status = gate2_.wait_until(lk, abs_time);
if (state_ == 1)
break;
if (status == boost::cv_status::timeout)
return false;
}
}
state_ = write_entered_;
return true;
}
template <class Clock, class Duration>
bool
upgrade_mutex::try_unlock_shared_and_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & (write_entered_ | upgradable_entered_)) != 0)
{
while (true)
{
boost::cv_status status = gate2_.wait_until(lk, abs_time);
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
break;
if (status == boost::cv_status::timeout)
return false;
}
}
state_ |= upgradable_entered_;
return true;
}
template <class Clock, class Duration>
bool
upgrade_mutex::try_unlock_upgrade_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & n_readers_) != 1)
{
while (true)
{
boost::cv_status status = gate2_.wait_until(lk, abs_time);
if ((state_ & n_readers_) == 1)
break;
if (status == boost::cv_status::timeout)
return false;
}
}
state_ = write_entered_;
return true;
}
//////
// shared_mutex
shared_mutex::shared_mutex()
: state_(0)
{
}
shared_mutex::~shared_mutex()
{
boost::lock_guard<mutex_t> _(mut_);
}
// Exclusive ownership
void
shared_mutex::lock()
{
boost::unique_lock<mutex_t> lk(mut_);
while (state_ & write_entered_)
gate1_.wait(lk);
state_ |= write_entered_;
while (state_ & n_readers_)
gate2_.wait(lk);
}
bool
shared_mutex::try_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == 0)
{
state_ = write_entered_;
return true;
}
return false;
}
void
shared_mutex::unlock()
{
boost::lock_guard<mutex_t> _(mut_);
state_ = 0;
gate1_.notify_all();
}
// Shared ownership
void
shared_mutex::lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
gate1_.wait(lk);
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= num_readers;
}
bool
shared_mutex::try_lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = state_ & n_readers_;
if (!(state_ & write_entered_) && num_readers != n_readers_)
{
++num_readers;
state_ &= ~n_readers_;
state_ |= num_readers;
return true;
}
return false;
}
void
shared_mutex::unlock_shared()
{
boost::lock_guard<mutex_t> _(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~n_readers_;
state_ |= num_readers;
if (state_ & write_entered_)
{
if (num_readers == 0)
gate2_.notify_one();
}
else
{
if (num_readers == n_readers_ - 1)
gate1_.notify_one();
}
}
// upgrade_mutex
upgrade_mutex::upgrade_mutex()
: gate1_(),
gate2_(),
state_(0)
{
}
upgrade_mutex::~upgrade_mutex()
{
boost::lock_guard<mutex_t> _(mut_);
}
// Exclusive ownership
void
upgrade_mutex::lock()
{
boost::unique_lock<mutex_t> lk(mut_);
while (state_ & (write_entered_ | upgradable_entered_))
gate1_.wait(lk);
state_ |= write_entered_;
while (state_ & n_readers_)
gate2_.wait(lk);
}
bool
upgrade_mutex::try_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == 0)
{
state_ = write_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock()
{
boost::lock_guard<mutex_t> _(mut_);
state_ = 0;
gate1_.notify_all();
}
// Shared ownership
void
upgrade_mutex::lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
gate1_.wait(lk);
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= num_readers;
}
bool
upgrade_mutex::try_lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = state_ & n_readers_;
if (!(state_ & write_entered_) && num_readers != n_readers_)
{
++num_readers;
state_ &= ~n_readers_;
state_ |= num_readers;
return true;
}
return false;
}
void
upgrade_mutex::unlock_shared()
{
boost::lock_guard<mutex_t> _(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~n_readers_;
state_ |= num_readers;
if (state_ & write_entered_)
{
if (num_readers == 0)
gate2_.notify_one();
}
else
{
if (num_readers == n_readers_ - 1)
gate1_.notify_one();
}
}
// Upgrade ownership
void
upgrade_mutex::lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
while ((state_ & (write_entered_ | upgradable_entered_)) ||
(state_ & n_readers_) == n_readers_)
gate1_.wait(lk);
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= upgradable_entered_ | num_readers;
}
bool
upgrade_mutex::try_lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = state_ & n_readers_;
if (!(state_ & (write_entered_ | upgradable_entered_))
&& num_readers != n_readers_)
{
++num_readers;
state_ &= ~n_readers_;
state_ |= upgradable_entered_ | num_readers;
return true;
}
return false;
}
void
upgrade_mutex::unlock_upgrade()
{
{
boost::lock_guard<mutex_t> _(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~(upgradable_entered_ | n_readers_);
state_ |= num_readers;
}
gate1_.notify_all();
}
// Shared <-> Exclusive
bool
upgrade_mutex::try_unlock_shared_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == 1)
{
state_ = write_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock_and_lock_shared()
{
{
boost::lock_guard<mutex_t> _(mut_);
state_ = 1;
}
gate1_.notify_all();
}
// Shared <-> Upgrade
bool
upgrade_mutex::try_unlock_shared_and_lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
if (!(state_ & (write_entered_ | upgradable_entered_)))
{
state_ |= upgradable_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock_upgrade_and_lock_shared()
{
{
boost::lock_guard<mutex_t> _(mut_);
state_ &= ~upgradable_entered_;
}
gate1_.notify_all();
}
// Upgrade <-> Exclusive
void
upgrade_mutex::unlock_upgrade_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~(upgradable_entered_ | n_readers_);
state_ |= write_entered_ | num_readers;
while (state_ & n_readers_)
gate2_.wait(lk);
}
bool
upgrade_mutex::try_unlock_upgrade_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == (upgradable_entered_ | 1))
{
state_ = write_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock_and_lock_upgrade()
{
{
boost::lock_guard<mutex_t> _(mut_);
state_ = upgradable_entered_ | 1;
}
gate1_.notify_all();
}
} // thread_v2
} // boost
namespace boost {
//using thread_v2::shared_mutex;
using thread_v2::upgrade_mutex;
typedef thread_v2::upgrade_mutex shared_mutex;
}
#endif