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