2013-11-12 04:29:53 +00:00
|
|
|
/**
|
|
|
|
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
|
|
|
|
C++11 does not support std::shared_mutex and std::shared_lock yet.
|
|
|
|
This piece of code is based on the proposal submitted to the C++
|
|
|
|
standardization committee. The proposal was written by Howard
|
|
|
|
Hinnant. The proposal is also part of the Boost library which is
|
|
|
|
licensed under http://www.boost.org/LICENSE_1_0.txt
|
|
|
|
*/
|
2013-12-12 22:02:17 +00:00
|
|
|
#pragma once
|
2013-11-12 04:00:21 +00:00
|
|
|
#include <climits>
|
2013-12-09 22:56:48 +00:00
|
|
|
#include "util/thread.h"
|
2013-11-12 04:00:21 +00:00
|
|
|
|
|
|
|
namespace lean {
|
2013-12-09 23:42:08 +00:00
|
|
|
#if defined(LEAN_MULTI_THREAD)
|
2013-11-12 04:00:21 +00:00
|
|
|
class shared_mutex {
|
2013-12-09 22:56:48 +00:00
|
|
|
mutex m_mutex;
|
|
|
|
thread::id m_rw_owner;
|
2013-11-16 06:01:06 +00:00
|
|
|
unsigned m_rw_counter;
|
2013-12-09 22:56:48 +00:00
|
|
|
condition_variable m_gate1;
|
|
|
|
condition_variable m_gate2;
|
2013-11-12 04:00:21 +00:00
|
|
|
unsigned m_state;
|
|
|
|
|
|
|
|
static constexpr unsigned write_entered = 1u << (sizeof(unsigned)*8 - 1);
|
|
|
|
static constexpr unsigned readers = ~write_entered;
|
|
|
|
|
|
|
|
public:
|
|
|
|
shared_mutex();
|
|
|
|
~shared_mutex();
|
|
|
|
|
|
|
|
shared_mutex(shared_mutex const &) = delete;
|
|
|
|
shared_mutex(shared_mutex &&) = delete;
|
|
|
|
shared_mutex& operator=(shared_mutex const &) = delete;
|
|
|
|
shared_mutex&& operator=(shared_mutex &&) = delete;
|
|
|
|
|
|
|
|
void lock();
|
|
|
|
bool try_lock();
|
|
|
|
void unlock();
|
|
|
|
|
|
|
|
void lock_shared();
|
|
|
|
bool try_lock_shared();
|
|
|
|
void unlock_shared();
|
|
|
|
};
|
2013-12-09 23:42:08 +00:00
|
|
|
#else
|
|
|
|
class shared_mutex {
|
|
|
|
public:
|
|
|
|
shared_mutex() {}
|
|
|
|
shared_mutex(shared_mutex const &) = delete;
|
|
|
|
shared_mutex(shared_mutex &&) = delete;
|
|
|
|
shared_mutex& operator=(shared_mutex const &) = delete;
|
|
|
|
shared_mutex&& operator=(shared_mutex &&) = delete;
|
|
|
|
void lock() {}
|
|
|
|
bool try_lock() { return true; }
|
|
|
|
void unlock() {}
|
|
|
|
|
|
|
|
void lock_shared() {}
|
|
|
|
bool try_lock_shared() { return true; }
|
|
|
|
void unlock_shared() {}
|
|
|
|
};
|
|
|
|
#endif
|
2013-11-12 04:00:21 +00:00
|
|
|
|
|
|
|
class shared_lock {
|
|
|
|
shared_mutex & m_mutex;
|
|
|
|
public:
|
|
|
|
shared_lock(shared_mutex & m):m_mutex(m) { m_mutex.lock_shared(); }
|
|
|
|
~shared_lock() { m_mutex.unlock_shared(); }
|
|
|
|
};
|
|
|
|
|
2013-12-09 22:56:48 +00:00
|
|
|
class exclusive_lock {
|
2013-11-12 04:00:21 +00:00
|
|
|
shared_mutex & m_mutex;
|
|
|
|
public:
|
2013-12-09 22:56:48 +00:00
|
|
|
exclusive_lock(shared_mutex & m):m_mutex(m) { m_mutex.lock(); }
|
|
|
|
~exclusive_lock() { m_mutex.unlock(); }
|
2013-11-12 04:00:21 +00:00
|
|
|
};
|
|
|
|
}
|