Skip to content

Commit 195942d

Browse files
committed
Merge pull request #6630
86270c8 Replace boost::reverse_lock with our own. (Casey Rodarmor)
2 parents 69dc5b5 + 86270c8 commit 195942d

File tree

5 files changed

+100
-2
lines changed

5 files changed

+100
-2
lines changed

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ BITCOIN_CORE_H = \
119119
protocol.h \
120120
pubkey.h \
121121
random.h \
122+
reverselock.h \
122123
rpcclient.h \
123124
rpcprotocol.h \
124125
rpcserver.h \

src/Makefile.test.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ BITCOIN_TESTS =\
6262
test/pmt_tests.cpp \
6363
test/policyestimator_tests.cpp \
6464
test/pow_tests.cpp \
65+
test/reverselock_tests.cpp \
6566
test/rpc_tests.cpp \
6667
test/sanity_tests.cpp \
6768
test/scheduler_tests.cpp \

src/reverselock.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) 2015 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_REVERSELOCK_H
6+
#define BITCOIN_REVERSELOCK_H
7+
8+
/**
9+
* An RAII-style reverse lock. Unlocks on construction and locks on destruction.
10+
*/
11+
template<typename Lock>
12+
class reverse_lock
13+
{
14+
public:
15+
16+
explicit reverse_lock(Lock& lock) : lock(lock) {
17+
lock.unlock();
18+
}
19+
20+
~reverse_lock() {
21+
lock.lock();
22+
}
23+
24+
private:
25+
reverse_lock(reverse_lock const&);
26+
reverse_lock& operator=(reverse_lock const&);
27+
28+
Lock& lock;
29+
};
30+
31+
#endif // BITCOIN_REVERSELOCK_H

src/scheduler.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
#include "scheduler.h"
66

7+
#include "reverselock.h"
8+
79
#include <assert.h>
810
#include <boost/bind.hpp>
9-
#include <boost/thread/reverse_lock.hpp>
1011
#include <utility>
1112

1213
CScheduler::CScheduler() : nThreadsServicingQueue(0), stopRequested(false), stopWhenEmpty(false)
@@ -69,7 +70,7 @@ void CScheduler::serviceQueue()
6970
{
7071
// Unlock before calling f, so it can reschedule itself or another task
7172
// without deadlocking:
72-
boost::reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
73+
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
7374
f();
7475
}
7576
} catch (...) {

src/test/reverselock_tests.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright (c) 2015 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include "reverselock.h"
6+
#include "test/test_bitcoin.h"
7+
8+
#include <boost/test/unit_test.hpp>
9+
10+
BOOST_FIXTURE_TEST_SUITE(reverselock_tests, BasicTestingSetup)
11+
12+
BOOST_AUTO_TEST_CASE(reverselock_basics)
13+
{
14+
boost::mutex mutex;
15+
boost::unique_lock<boost::mutex> lock(mutex);
16+
17+
BOOST_CHECK(lock.owns_lock());
18+
{
19+
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
20+
BOOST_CHECK(!lock.owns_lock());
21+
}
22+
BOOST_CHECK(lock.owns_lock());
23+
}
24+
25+
BOOST_AUTO_TEST_CASE(reverselock_errors)
26+
{
27+
boost::mutex mutex;
28+
boost::unique_lock<boost::mutex> lock(mutex);
29+
30+
// Make sure trying to reverse lock an unlocked lock fails
31+
lock.unlock();
32+
33+
BOOST_CHECK(!lock.owns_lock());
34+
35+
bool failed = false;
36+
try {
37+
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
38+
} catch(...) {
39+
failed = true;
40+
}
41+
42+
BOOST_CHECK(failed);
43+
BOOST_CHECK(!lock.owns_lock());
44+
45+
// Make sure trying to lock a lock after it has been reverse locked fails
46+
failed = false;
47+
bool locked = false;
48+
49+
lock.lock();
50+
BOOST_CHECK(lock.owns_lock());
51+
52+
try {
53+
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
54+
lock.lock();
55+
locked = true;
56+
} catch(...) {
57+
failed = true;
58+
}
59+
60+
BOOST_CHECK(locked && failed);
61+
BOOST_CHECK(lock.owns_lock());
62+
}
63+
64+
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)