Branch data Line data Source code
1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : : // Copyright (c) 2009-present The Bitcoin Core developers
3 : : // Distributed under the MIT software license, see the accompanying
4 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 : :
6 : : #ifndef BITCOIN_SEMAPHORE_GRANT_H
7 : : #define BITCOIN_SEMAPHORE_GRANT_H
8 : :
9 : : #include <semaphore>
10 : :
11 : : /** RAII-style semaphore lock */
12 : : template <std::ptrdiff_t LeastMaxValue = std::counting_semaphore<>::max()>
13 : : class CountingSemaphoreGrant
14 : : {
15 : : private:
16 : : std::counting_semaphore<LeastMaxValue>* sem;
17 : : bool fHaveGrant;
18 : :
19 : : public:
20 : 9025 : void Acquire() noexcept
21 : : {
22 [ + - ]: 9025 : if (fHaveGrant) {
23 : : return;
24 : : }
25 : 9025 : sem->acquire();
26 : 9025 : fHaveGrant = true;
27 : : }
28 : :
29 : 12659 : void Release() noexcept
30 : : {
31 [ + + ]: 12659 : if (!fHaveGrant) {
32 : : return;
33 : : }
34 : 9175 : sem->release();
35 : 9175 : fHaveGrant = false;
36 : : }
37 : :
38 : 150 : bool TryAcquire() noexcept
39 : : {
40 [ + - + - ]: 150 : if (!fHaveGrant && sem->try_acquire()) {
41 : 150 : fHaveGrant = true;
42 : : }
43 : 150 : return fHaveGrant;
44 : : }
45 : :
46 : : // Disallow copy.
47 : : CountingSemaphoreGrant(const CountingSemaphoreGrant&) = delete;
48 : : CountingSemaphoreGrant& operator=(const CountingSemaphoreGrant&) = delete;
49 : :
50 : : // Allow move.
51 : 3 : CountingSemaphoreGrant(CountingSemaphoreGrant&& other) noexcept
52 : : {
53 : 3 : sem = other.sem;
54 : 3 : fHaveGrant = other.fHaveGrant;
55 : 3 : other.fHaveGrant = false;
56 [ + - ]: 3 : other.sem = nullptr;
57 : : }
58 : :
59 : 591 : CountingSemaphoreGrant& operator=(CountingSemaphoreGrant&& other) noexcept
60 : : {
61 : 591 : Release();
62 : 591 : sem = other.sem;
63 : 591 : fHaveGrant = other.fHaveGrant;
64 : 591 : other.fHaveGrant = false;
65 : 591 : other.sem = nullptr;
66 : : return *this;
67 : : }
68 : :
69 [ + - # # ]: 2055 : CountingSemaphoreGrant() noexcept : sem(nullptr), fHaveGrant(false) {}
[ + - + - ]
70 : :
71 : 9175 : explicit CountingSemaphoreGrant(std::counting_semaphore<LeastMaxValue>& sema, bool fTry = false) noexcept : sem(&sema), fHaveGrant(false)
72 : : {
73 : : if (fTry) {
74 : 150 : TryAcquire();
75 : : } else {
76 : 9025 : Acquire();
77 : : }
78 : : }
79 : :
80 : 9627 : ~CountingSemaphoreGrant()
81 : : {
82 : 9627 : Release();
83 : 9627 : }
84 : :
85 : 151 : explicit operator bool() const noexcept
86 : : {
87 [ + - + - : 151 : return fHaveGrant;
+ - ]
88 : : }
89 : : };
90 : :
91 : : using BinarySemaphoreGrant = CountingSemaphoreGrant<1>;
92 : :
93 : : #endif // BITCOIN_SEMAPHORE_GRANT_H
|