libosmscout
1.1.1
Toggle main menu visibility
Loading...
Searching...
No Matches
libosmscout
include
osmscout
async
ReadWriteLock.h
Go to the documentation of this file.
1
#ifndef LIBOSMSCOUT_READWRITELOCK_H
2
#define LIBOSMSCOUT_READWRITELOCK_H
3
4
/*
5
This source is part of the libosmscout library
6
Copyright (C) 2024 Jean-Luc Barriere
7
8
This library is free software; you can redistribute it and/or
9
modify it under the terms of the GNU Lesser General Public
10
License as published by the Free Software Foundation; either
11
version 2.1 of the License, or (at your option) any later version.
12
13
This library is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
Lesser General Public License for more details.
17
18
You should have received a copy of the GNU Lesser General Public
19
License along with this library; if not, write to the Free Software
20
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
*/
22
23
#include <
osmscout/lib/CoreImportExport.h
>
24
25
#include <atomic>
26
#include <thread>
27
#include <mutex>
28
#include <condition_variable>
29
30
namespace
osmscout
{
31
38
39
class
OSMSCOUT_API
Latch
{
40
private
:
41
mutable
std::atomic<bool> s_spin =
false
;
42
43
volatile
int
x_wait = 0;
/* counts requests in wait for X */
44
volatile
int
x_flag = 0;
/* X status: 0, 1, 2, or 3 */
45
std::thread::id x_owner;
/* X owner (thread id) */
46
47
std::mutex x_gate_lock;
48
std::condition_variable x_gate;
/* wait for release of X */
49
std::mutex s_gate_lock;
50
std::condition_variable s_gate;
/* wait for release of S */
51
52
bool
px =
true
;
/* enable X precedence */
53
54
struct
TNode {
55
TNode * _prev =
nullptr
;
56
TNode * _next =
nullptr
;
57
std::thread::id id;
58
int
count = 0;
59
};
60
TNode * s_freed =
nullptr
;
61
TNode * s_nodes =
nullptr
;
62
63
void
spin_lock() {
64
while
(s_spin.exchange(
true
, std::memory_order_acquire)) {
65
do
{
66
std::this_thread::yield();
67
}
while
(s_spin.load(std::memory_order_relaxed));
68
}
69
}
70
void
spin_unlock() {
71
s_spin.store(
false
, std::memory_order_release);
72
}
73
74
TNode * find_node(
const
std::thread::id&
id
);
75
TNode * new_node(
const
std::thread::id&
id
);
76
void
free_node(TNode * n);
77
78
public
:
79
Latch
();
80
explicit
Latch
(
bool
_px) : px(_px) { }
81
Latch
(
const
Latch
&) =
delete
;
82
Latch
(
Latch
&&) =
delete
;
83
Latch
&
operator=
(
const
Latch
&) =
delete
;
84
Latch
&
operator=
(
Latch
&&) =
delete
;
85
~Latch
();
86
87
/* Locks the latch for exclusive ownership,
88
* blocks if the latch is not available
89
*/
90
void
lock
();
91
92
/* Unlocks the latch (exclusive ownership) */
93
void
unlock
();
94
95
/* Locks the latch for shared ownership,
96
* blocks if the latch is not available
97
*/
98
void
lock_shared
();
99
100
/* Unlocks the latch (shared ownership) */
101
void
unlock_shared
();
102
103
/* Tries to lock the latch for shared ownership,
104
* returns true if the latch has no exclusive ownership or any request for
105
* exclusive ownership, else false
106
*/
107
bool
try_lock_shared
();
108
};
109
110
/*
111
* Cannot use the template std::shared_lock as Latch does not implement all the
112
* requirements of the standard
113
*/
114
class
OSMSCOUT_API
ReadLock
115
{
116
private
:
117
Latch
*p =
nullptr
;
118
bool
owns =
false
;
119
120
void
swap(
ReadLock
& rl)
noexcept
{
121
std::swap(p, rl.p);
122
std::swap(owns, rl.owns);
123
}
124
125
public
:
126
127
ReadLock
() =
default
;
128
129
explicit
ReadLock
(
Latch
& latch) : p(&latch), owns(true) { latch.
lock_shared
(); }
130
131
/* Assume the calling thread already has ownership of the shared lock */
132
ReadLock
(
Latch
& latch, std::adopt_lock_t) : p(&latch), owns(true) { }
133
134
~ReadLock
() {
135
if
(owns) {
136
p->unlock_shared();
137
}
138
}
139
140
ReadLock
(
ReadLock
const
&) =
delete
;
141
ReadLock
&
operator=
(
ReadLock
const
&) =
delete
;
142
143
ReadLock
(
ReadLock
&& rl)
noexcept
{ swap(rl); }
144
145
ReadLock
&
operator=
(
ReadLock
&& rl)
noexcept
{
146
swap(rl);
147
return
*
this
;
148
}
149
150
bool
owns_lock
() const noexcept {
151
return
owns;
152
}
153
154
void
lock
() {
155
if
(!owns && p !=
nullptr
) {
156
p->lock_shared();
157
owns =
true
;
158
}
159
}
160
161
void
unlock
() {
162
if
(owns) {
163
owns =
false
;
164
p->unlock_shared();
165
}
166
}
167
168
bool
try_lock
() {
169
if
(!owns && p !=
nullptr
) {
170
owns = p->try_lock_shared();
171
}
172
return
owns;
173
}
174
};
175
176
/*
177
* Cannot use the template std::unique_lock as Latch does not implement all the
178
* requirements of the standard
179
*/
180
class
OSMSCOUT_API
WriteLock
181
{
182
private
:
183
Latch
*p =
nullptr
;
184
bool
owns =
false
;
185
186
void
swap(
WriteLock
& wl)
noexcept
{
187
std::swap(p, wl.p);
188
std::swap(owns, wl.owns);
189
}
190
191
public
:
192
193
WriteLock
() =
default
;
194
195
explicit
WriteLock
(
Latch
& latch) : p(&latch), owns(true) { latch.
lock
(); }
196
197
~WriteLock
() {
198
if
(owns) {
199
p->unlock();
200
}
201
}
202
203
WriteLock
(
WriteLock
const
&) =
delete
;
204
WriteLock
&
operator=
(
WriteLock
const
&) =
delete
;
205
206
WriteLock
(
WriteLock
&& wl)
noexcept
{ swap(wl); }
207
208
WriteLock
&
operator=
(
WriteLock
&& wl)
noexcept
{
209
swap(wl);
210
return
*
this
;
211
}
212
213
bool
owns_lock
() const noexcept {
214
return
owns;
215
}
216
217
void
lock
() {
218
if
(!owns && p !=
nullptr
) {
219
p->lock();
220
owns =
true
;
221
}
222
}
223
224
void
unlock
() {
225
if
(owns) {
226
owns =
false
;
227
p->unlock();
228
}
229
}
230
};
231
232
}
233
234
#endif
//LIBOSMSCOUT_READWRITELOCK_H
CoreImportExport.h
OSMSCOUT_API
#define OSMSCOUT_API
Definition
CoreImportExport.h:45
osmscout::Latch
Definition
ReadWriteLock.h:39
osmscout::Latch::Latch
Latch(Latch &&)=delete
osmscout::Latch::Latch
Latch(const Latch &)=delete
osmscout::Latch::try_lock_shared
bool try_lock_shared()
osmscout::Latch::lock_shared
void lock_shared()
osmscout::Latch::~Latch
~Latch()
osmscout::Latch::operator=
Latch & operator=(const Latch &)=delete
osmscout::Latch::operator=
Latch & operator=(Latch &&)=delete
osmscout::Latch::lock
void lock()
osmscout::Latch::unlock
void unlock()
osmscout::Latch::Latch
Latch(bool _px)
Definition
ReadWriteLock.h:80
osmscout::Latch::Latch
Latch()
osmscout::Latch::unlock_shared
void unlock_shared()
osmscout::ReadLock::try_lock
bool try_lock()
Definition
ReadWriteLock.h:168
osmscout::ReadLock::operator=
ReadLock & operator=(ReadLock &&rl) noexcept
Definition
ReadWriteLock.h:145
osmscout::ReadLock::ReadLock
ReadLock(ReadLock const &)=delete
osmscout::ReadLock::~ReadLock
~ReadLock()
Definition
ReadWriteLock.h:134
osmscout::ReadLock::ReadLock
ReadLock(Latch &latch)
Definition
ReadWriteLock.h:129
osmscout::ReadLock::ReadLock
ReadLock()=default
osmscout::ReadLock::owns_lock
bool owns_lock() const noexcept
Definition
ReadWriteLock.h:150
osmscout::ReadLock::ReadLock
ReadLock(Latch &latch, std::adopt_lock_t)
Definition
ReadWriteLock.h:132
osmscout::ReadLock::operator=
ReadLock & operator=(ReadLock const &)=delete
osmscout::ReadLock::ReadLock
ReadLock(ReadLock &&rl) noexcept
Definition
ReadWriteLock.h:143
osmscout::ReadLock::unlock
void unlock()
Definition
ReadWriteLock.h:161
osmscout::ReadLock::lock
void lock()
Definition
ReadWriteLock.h:154
osmscout::WriteLock::~WriteLock
~WriteLock()
Definition
ReadWriteLock.h:197
osmscout::WriteLock::operator=
WriteLock & operator=(WriteLock &&wl) noexcept
Definition
ReadWriteLock.h:208
osmscout::WriteLock::WriteLock
WriteLock(WriteLock const &)=delete
osmscout::WriteLock::operator=
WriteLock & operator=(WriteLock const &)=delete
osmscout::WriteLock::lock
void lock()
Definition
ReadWriteLock.h:217
osmscout::WriteLock::owns_lock
bool owns_lock() const noexcept
Definition
ReadWriteLock.h:213
osmscout::WriteLock::WriteLock
WriteLock(Latch &latch)
Definition
ReadWriteLock.h:195
osmscout::WriteLock::WriteLock
WriteLock()=default
osmscout::WriteLock::unlock
void unlock()
Definition
ReadWriteLock.h:224
osmscout::WriteLock::WriteLock
WriteLock(WriteLock &&wl) noexcept
Definition
ReadWriteLock.h:206
osmscout
Definition
Area.h:39
Generated by
1.17.0