Source code

Revision control

Copy as Markdown

Other Tools

/*
* (C) 2019 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/internal/rwlock.h>
namespace Botan {
RWLock::RWLock() : m_state(0) {}
void RWLock::lock()
{
std::unique_lock<std::mutex> lock(m_mutex);
while(m_state & is_writing)
m_gate1.wait(lock);
m_state |= is_writing;
while(m_state & readers_mask)
m_gate2.wait(lock);
}
void RWLock::unlock()
{
std::unique_lock<std::mutex> lock(m_mutex);
m_state = 0;
m_gate1.notify_all();
}
void RWLock::lock_shared()
{
std::unique_lock<std::mutex> lock(m_mutex);
while((m_state & is_writing) || (m_state & readers_mask) == readers_mask)
m_gate1.wait(lock);
const uint32_t num_readers = (m_state & readers_mask) + 1;
m_state &= ~readers_mask;
m_state |= num_readers;
}
void RWLock::unlock_shared()
{
std::unique_lock<std::mutex> lock(m_mutex);
const uint32_t num_readers = (m_state & readers_mask) - 1;
m_state &= ~readers_mask;
m_state |= num_readers;
if(m_state & is_writing)
{
if(num_readers == 0)
m_gate2.notify_one();
}
else
{
if(num_readers == readers_mask - 1)
m_gate1.notify_one();
}
}
}