mirror of
https://github.com/dashpay/dash.git
synced 2024-12-30 14:25:53 +01:00
f3b92a95d9
noexcept is default for destructors as of c++11. By throwing in reverselock's destructor if it's lock has been tampered with, the likely result is std::terminate being called. Indeed that happened before this change. Once reverselock has taken another lock (its ctor didn't throw), it makes no sense to try to grab or lock the parent lock. That is be broken/undefined behavior depending on the parent lock's implementation, but it shouldn't cause the reverselock to fail to re-lock when destroyed. To avoid those problems, simply swap the parent lock's contents with a dummy for the duration of the lock. That will ensure that any undefined behavior is caught at the call-site rather than the reverse lock's destruction. Barring a failed mutex unlock which would be indicative of a larger problem, the destructor should now never throw.
61 lines
1.5 KiB
C++
61 lines
1.5 KiB
C++
// 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_dash.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());
|
|
|
|
// Locking the original lock after it has been taken by a reverse lock
|
|
// makes no sense. Ensure that the original lock no longer owns the lock
|
|
// after giving it to a reverse one.
|
|
|
|
lock.lock();
|
|
BOOST_CHECK(lock.owns_lock());
|
|
{
|
|
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
|
|
BOOST_CHECK(!lock.owns_lock());
|
|
}
|
|
|
|
BOOST_CHECK(failed);
|
|
BOOST_CHECK(lock.owns_lock());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|