Casey Rodarmor
9 years ago
5 changed files with 100 additions and 2 deletions
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_REVERSELOCK_H |
||||
#define BITCOIN_REVERSELOCK_H |
||||
|
||||
/**
|
||||
* An RAII-style reverse lock. Unlocks on construction and locks on destruction. |
||||
*/ |
||||
template<typename Lock> |
||||
class reverse_lock |
||||
{ |
||||
public: |
||||
|
||||
explicit reverse_lock(Lock& lock) : lock(lock) { |
||||
lock.unlock(); |
||||
} |
||||
|
||||
~reverse_lock() { |
||||
lock.lock(); |
||||
} |
||||
|
||||
private: |
||||
reverse_lock(reverse_lock const&); |
||||
reverse_lock& operator=(reverse_lock const&); |
||||
|
||||
Lock& lock; |
||||
}; |
||||
|
||||
#endif // BITCOIN_REVERSELOCK_H
|
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) 2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "reverselock.h" |
||||
#include "test/test_bitcoin.h" |
||||
|
||||
#include <boost/test/unit_test.hpp> |
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(reverselock_tests, BasicTestingSetup) |
||||
|
||||
BOOST_AUTO_TEST_CASE(reverselock_basics) |
||||
{ |
||||
boost::mutex mutex; |
||||
boost::unique_lock<boost::mutex> lock(mutex); |
||||
|
||||
BOOST_CHECK(lock.owns_lock()); |
||||
{ |
||||
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); |
||||
BOOST_CHECK(!lock.owns_lock()); |
||||
} |
||||
BOOST_CHECK(lock.owns_lock()); |
||||
} |
||||
|
||||
BOOST_AUTO_TEST_CASE(reverselock_errors) |
||||
{ |
||||
boost::mutex mutex; |
||||
boost::unique_lock<boost::mutex> lock(mutex); |
||||
|
||||
// Make sure trying to reverse lock an unlocked lock fails
|
||||
lock.unlock(); |
||||
|
||||
BOOST_CHECK(!lock.owns_lock()); |
||||
|
||||
bool failed = false; |
||||
try { |
||||
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); |
||||
} catch(...) { |
||||
failed = true; |
||||
} |
||||
|
||||
BOOST_CHECK(failed); |
||||
BOOST_CHECK(!lock.owns_lock()); |
||||
|
||||
// Make sure trying to lock a lock after it has been reverse locked fails
|
||||
failed = false; |
||||
bool locked = false; |
||||
|
||||
lock.lock(); |
||||
BOOST_CHECK(lock.owns_lock()); |
||||
|
||||
try { |
||||
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock); |
||||
lock.lock(); |
||||
locked = true; |
||||
} catch(...) { |
||||
failed = true; |
||||
} |
||||
|
||||
BOOST_CHECK(locked && failed); |
||||
BOOST_CHECK(lock.owns_lock()); |
||||
} |
||||
|
||||
BOOST_AUTO_TEST_SUITE_END() |
Loading…
Reference in new issue