//----------------------------------------------- // popov.h: reader/writer fairness //----------------------------------------------- #ifndef popov_h #define popov_h //----------------------------------------------- #include // std::size_t #include // std::mutex #include // std::counting_semaphore //----------------------------------------------- class popov_lock { public: popov_lock(std::size_t) {} void reader_lock() { in.acquire(); ++ctrin; in.release(); } void reader_unlock() { out.acquire(); ++ctrout; if (wait && ctrin == ctrout) wrt.release(); out.release(); } void writer_lock() { in.acquire(); out.acquire(); if (ctrin == ctrout) { out.release(); } else { wait = true; out.release(); wrt.acquire(); wait = false; } } void writer_unlock() { in.release(); } private: std::binary_semaphore in{1}, out{1}, wrt{0}; std::size_t ctrin = 0, ctrout = 0; bool wait = false; }; //----------------------------------------------- #endif // popov_h