1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/**
* std::shared_mutex et al implementation for MinGW-w64
*
* Copyright (c) 2017 by Nathaniel J. McClatchey, Athens OH, United States
* Copyright (c) 2022 the build2 authors
*
* Licensed under the simplified (2-clause) BSD License.
* You should have received a copy of the license along with this
* program.
*
* This code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef LIBBUTL_MINGW_SHARED_MUTEX_HXX
#define LIBBUTL_MINGW_SHARED_MUTEX_HXX
#if !defined(__cplusplus) || (__cplusplus < 201402L)
# error C++14 compiler required
#endif
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0601
# error _WIN32_WINNT should be 0x0601 (Windows 7) or greater
#endif
#include <cassert>
// For descriptive errors.
#include <system_error>
// For timing in shared_timed_mutex.
#include <chrono>
#include <limits>
#include <shared_mutex> // shared_lock
// For defer_lock_t, adopt_lock_t, and try_to_lock_t
#include <libbutl/mingw-mutex.hxx>
#include <synchapi.h>
namespace mingw_stdthread
{
using std::shared_lock;
class condition_variable_any;
// Slim Reader-Writer (SRW)-based implementation that requires Windows 7.
//
class shared_mutex : mutex
{
friend class condition_variable_any;
public:
using mutex::native_handle_type;
using mutex::lock;
using mutex::try_lock;
using mutex::unlock;
using mutex::native_handle;
void lock_shared ()
{
AcquireSRWLockShared(&mHandle);
}
void unlock_shared ()
{
ReleaseSRWLockShared(&mHandle);
}
bool try_lock_shared ()
{
return TryAcquireSRWLockShared(&mHandle) != 0;
}
};
class shared_timed_mutex : shared_mutex
{
typedef shared_mutex Base;
public:
using Base::lock;
using Base::try_lock;
using Base::unlock;
using Base::lock_shared;
using Base::try_lock_shared;
using Base::unlock_shared;
template< class Clock, class Duration >
bool try_lock_until ( const std::chrono::time_point<Clock,Duration>& cutoff )
{
do
{
if (try_lock())
return true;
}
while (std::chrono::steady_clock::now() < cutoff);
return false;
}
template< class Rep, class Period >
bool try_lock_for (const std::chrono::duration<Rep,Period>& rel_time)
{
return try_lock_until(std::chrono::steady_clock::now() + rel_time);
}
template< class Clock, class Duration >
bool try_lock_shared_until ( const std::chrono::time_point<Clock,Duration>& cutoff )
{
do
{
if (try_lock_shared())
return true;
}
while (std::chrono::steady_clock::now() < cutoff);
return false;
}
template< class Rep, class Period >
bool try_lock_shared_for (const std::chrono::duration<Rep,Period>& rel_time)
{
return try_lock_shared_until(std::chrono::steady_clock::now() + rel_time);
}
};
}
#endif // LIBBUTL_MINGW_SHARED_MUTEX_HXX
|