Casey Rodarmor
9 years ago
5 changed files with 100 additions and 2 deletions
@ -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 @@ |
|||||||
|
// 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