Skip to content

Commit dd163f5

Browse files
committed
Merge #9674: Always enforce strict lock ordering (try or not)
618ee92 Further-enforce lockordering by enforcing directly after TRY_LOCKs (Matt Corallo) 2a962d4 Fixup style a bit by moving { to the same line as if statements (Matt Corallo) 8465631 Always enforce lock strict lock ordering (try or not) (Matt Corallo) fd13eca Lock cs_vSend and cs_inventory in a consistent order even in TRY (Matt Corallo)
2 parents 6a55515 + 618ee92 commit dd163f5

File tree

2 files changed

+20
-48
lines changed

2 files changed

+20
-48
lines changed

src/net.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,20 +1093,18 @@ void CConnman::ThreadSocketHandler()
10931093
BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
10941094
{
10951095
// wait until threads are done using it
1096-
if (pnode->GetRefCount() <= 0)
1097-
{
1096+
if (pnode->GetRefCount() <= 0) {
10981097
bool fDelete = false;
10991098
{
1100-
TRY_LOCK(pnode->cs_vSend, lockSend);
1101-
if (lockSend)
1102-
{
1103-
TRY_LOCK(pnode->cs_inventory, lockInv);
1104-
if (lockInv)
1105-
fDelete = true;
1099+
TRY_LOCK(pnode->cs_inventory, lockInv);
1100+
if (lockInv) {
1101+
TRY_LOCK(pnode->cs_vSend, lockSend);
1102+
if (lockSend) {
1103+
fDelete = true;
1104+
}
11061105
}
11071106
}
1108-
if (fDelete)
1109-
{
1107+
if (fDelete) {
11101108
vNodesDisconnected.remove(pnode);
11111109
DeleteNode(pnode);
11121110
}

src/sync.cpp

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -77,52 +77,28 @@ boost::thread_specific_ptr<LockStack> lockstack;
7777

7878
static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
7979
{
80-
// We attempt to not assert on probably-not deadlocks by assuming that
81-
// a try lock will immediately have otherwise bailed if it had
82-
// failed to get the lock
83-
// We do this by, for the locks which triggered the potential deadlock,
84-
// in either lockorder, checking that the second of the two which is locked
85-
// is only a TRY_LOCK, ignoring locks if they are reentrant.
86-
bool firstLocked = false;
87-
bool secondLocked = false;
88-
bool onlyMaybeDeadlock = false;
89-
9080
LogPrintf("POTENTIAL DEADLOCK DETECTED\n");
9181
LogPrintf("Previous lock order was:\n");
9282
BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s2) {
9383
if (i.first == mismatch.first) {
9484
LogPrintf(" (1)");
95-
if (!firstLocked && secondLocked && i.second.fTry)
96-
onlyMaybeDeadlock = true;
97-
firstLocked = true;
9885
}
9986
if (i.first == mismatch.second) {
10087
LogPrintf(" (2)");
101-
if (!secondLocked && firstLocked && i.second.fTry)
102-
onlyMaybeDeadlock = true;
103-
secondLocked = true;
10488
}
10589
LogPrintf(" %s\n", i.second.ToString());
10690
}
107-
firstLocked = false;
108-
secondLocked = false;
10991
LogPrintf("Current lock order is:\n");
11092
BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s1) {
11193
if (i.first == mismatch.first) {
11294
LogPrintf(" (1)");
113-
if (!firstLocked && secondLocked && i.second.fTry)
114-
onlyMaybeDeadlock = true;
115-
firstLocked = true;
11695
}
11796
if (i.first == mismatch.second) {
11897
LogPrintf(" (2)");
119-
if (!secondLocked && firstLocked && i.second.fTry)
120-
onlyMaybeDeadlock = true;
121-
secondLocked = true;
12298
}
12399
LogPrintf(" %s\n", i.second.ToString());
124100
}
125-
assert(onlyMaybeDeadlock);
101+
assert(false);
126102
}
127103

128104
static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
@@ -134,21 +110,19 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
134110

135111
(*lockstack).push_back(std::make_pair(c, locklocation));
136112

137-
if (!fTry) {
138-
BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, (*lockstack)) {
139-
if (i.first == c)
140-
break;
113+
BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, (*lockstack)) {
114+
if (i.first == c)
115+
break;
141116

142-
std::pair<void*, void*> p1 = std::make_pair(i.first, c);
143-
if (lockdata.lockorders.count(p1))
144-
continue;
145-
lockdata.lockorders[p1] = (*lockstack);
117+
std::pair<void*, void*> p1 = std::make_pair(i.first, c);
118+
if (lockdata.lockorders.count(p1))
119+
continue;
120+
lockdata.lockorders[p1] = (*lockstack);
146121

147-
std::pair<void*, void*> p2 = std::make_pair(c, i.first);
148-
lockdata.invlockorders.insert(p2);
149-
if (lockdata.lockorders.count(p2))
150-
potential_deadlock_detected(p1, lockdata.lockorders[p2], lockdata.lockorders[p1]);
151-
}
122+
std::pair<void*, void*> p2 = std::make_pair(c, i.first);
123+
lockdata.invlockorders.insert(p2);
124+
if (lockdata.lockorders.count(p2))
125+
potential_deadlock_detected(p1, lockdata.lockorders[p2], lockdata.lockorders[p1]);
152126
}
153127
}
154128

0 commit comments

Comments
 (0)