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 }