Line data Source code
1 : // Copyright (c) 2015-2021 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 <sync.h> 6 : #include <test/util/setup_common.h> 7 : 8 : #include <boost/test/unit_test.hpp> 9 : 10 : #include <stdexcept> 11 : 12 146 : BOOST_AUTO_TEST_SUITE(reverselock_tests) 13 : 14 148 : BOOST_AUTO_TEST_CASE(reverselock_basics) 15 : { 16 1 : Mutex mutex; 17 1 : WAIT_LOCK(mutex, lock); 18 : 19 1 : BOOST_CHECK(lock.owns_lock()); 20 : { 21 1 : REVERSE_LOCK(lock); 22 1 : BOOST_CHECK(!lock.owns_lock()); 23 1 : } 24 1 : BOOST_CHECK(lock.owns_lock()); 25 1 : } 26 : 27 148 : BOOST_AUTO_TEST_CASE(reverselock_multiple) 28 : { 29 1 : Mutex mutex2; 30 1 : Mutex mutex; 31 1 : WAIT_LOCK(mutex2, lock2); 32 1 : WAIT_LOCK(mutex, lock); 33 : 34 : // Make sure undoing two locks succeeds 35 : { 36 1 : REVERSE_LOCK(lock); 37 1 : BOOST_CHECK(!lock.owns_lock()); 38 1 : REVERSE_LOCK(lock2); 39 1 : BOOST_CHECK(!lock2.owns_lock()); 40 1 : } 41 1 : BOOST_CHECK(lock.owns_lock()); 42 1 : BOOST_CHECK(lock2.owns_lock()); 43 1 : } 44 : 45 148 : BOOST_AUTO_TEST_CASE(reverselock_errors) 46 : { 47 1 : Mutex mutex2; 48 1 : Mutex mutex; 49 1 : WAIT_LOCK(mutex2, lock2); 50 1 : WAIT_LOCK(mutex, lock); 51 : 52 : #ifdef DEBUG_LOCKORDER 53 : bool prev = g_debug_lockorder_abort; 54 : g_debug_lockorder_abort = false; 55 : 56 : // Make sure trying to reverse lock a previous lock fails 57 : BOOST_CHECK_EXCEPTION(REVERSE_LOCK(lock2), std::logic_error, HasReason("lock2 was not most recent critical section locked")); 58 : BOOST_CHECK(lock2.owns_lock()); 59 : 60 : g_debug_lockorder_abort = prev; 61 : #endif 62 : 63 : // Make sure trying to reverse lock an unlocked lock fails 64 1 : lock.unlock(); 65 : 66 1 : BOOST_CHECK(!lock.owns_lock()); 67 : 68 1 : bool failed = false; 69 : try { 70 1 : REVERSE_LOCK(lock); 71 1 : } catch(...) { 72 1 : failed = true; 73 1 : } 74 : 75 1 : BOOST_CHECK(failed); 76 1 : BOOST_CHECK(!lock.owns_lock()); 77 : 78 : // Locking the original lock after it has been taken by a reverse lock 79 : // makes no sense. Ensure that the original lock no longer owns the lock 80 : // after giving it to a reverse one. 81 : 82 1 : lock.lock(); 83 1 : BOOST_CHECK(lock.owns_lock()); 84 : { 85 1 : REVERSE_LOCK(lock); 86 1 : BOOST_CHECK(!lock.owns_lock()); 87 1 : } 88 : 89 1 : BOOST_CHECK(failed); 90 1 : BOOST_CHECK(lock.owns_lock()); 91 2 : } 92 : 93 146 : BOOST_AUTO_TEST_SUITE_END()