Mercurial > foo_out_sdl
comparison foosdk/sdk/foobar2000/helpers/readWriteLock.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #pragma once | |
| 2 | |
| 3 | |
| 4 namespace fb2k { | |
| 5 //! fb2k::readWriteLock: abortable readWriteLock, allowing multiple concurrent readers while not writing, or one writer while not reading. \n | |
| 6 //! Safe to release locks in different threads than obtained, contrary to system object such as SRW locks. | |
| 7 class readWriteLock { | |
| 8 pfc::mutex m_guard; | |
| 9 size_t m_readers = 0, m_writers = 0; | |
| 10 typedef std::shared_ptr < pfc::event> eventRef_t; | |
| 11 eventRef_t m_currentEvent; | |
| 12 public: | |
| 13 | |
| 14 void shutdown() { | |
| 15 for (;;) { | |
| 16 eventRef_t waitFor; | |
| 17 { | |
| 18 PFC_INSYNC(m_guard); | |
| 19 if (m_readers == 0 && m_writers == 0) return; | |
| 20 PFC_ASSERT(m_currentEvent); | |
| 21 waitFor = m_currentEvent; | |
| 22 } | |
| 23 waitFor->wait_for(-1); | |
| 24 } | |
| 25 } | |
| 26 | |
| 27 service_ptr beginRead(abort_callback& a) { | |
| 28 for (;;) { | |
| 29 a.check(); | |
| 30 eventRef_t waitFor; | |
| 31 { | |
| 32 PFC_INSYNC(m_guard); | |
| 33 if (m_writers == 0) { | |
| 34 if (!m_currentEvent) m_currentEvent = std::make_shared<pfc::event>(); | |
| 35 ++m_readers; | |
| 36 return fb2k::callOnRelease([this] { | |
| 37 PFC_INSYNC(m_guard); | |
| 38 PFC_ASSERT(m_currentEvent); | |
| 39 PFC_ASSERT(m_readers > 0 && m_writers == 0); | |
| 40 if (--m_readers == 0) { | |
| 41 m_currentEvent->set_state(true); m_currentEvent = nullptr; | |
| 42 } | |
| 43 }); | |
| 44 } | |
| 45 PFC_ASSERT(m_currentEvent); | |
| 46 waitFor = m_currentEvent; | |
| 47 } | |
| 48 a.waitForEvent(*waitFor); | |
| 49 } | |
| 50 } | |
| 51 service_ptr beginWrite(abort_callback& a) { | |
| 52 for (;;) { | |
| 53 a.check(); | |
| 54 eventRef_t waitFor; | |
| 55 { | |
| 56 PFC_INSYNC(m_guard); | |
| 57 if (m_readers == 0 && m_writers == 0) { | |
| 58 m_currentEvent = std::make_shared<pfc::event>(); | |
| 59 ++m_writers; | |
| 60 return fb2k::callOnRelease([this] { | |
| 61 PFC_INSYNC(m_guard); | |
| 62 PFC_ASSERT(m_currentEvent); | |
| 63 PFC_ASSERT(m_readers == 0 && m_writers > 0); | |
| 64 if (--m_writers == 0) { | |
| 65 m_currentEvent->set_state(true); m_currentEvent = nullptr; | |
| 66 } | |
| 67 }); | |
| 68 } | |
| 69 PFC_ASSERT(m_currentEvent); | |
| 70 waitFor = m_currentEvent; | |
| 71 } | |
| 72 a.waitForEvent(*waitFor); | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 }; | |
| 77 } |
