@@ -16,7 +16,7 @@ use std::sync::RwLockWriteGuard as StdRwLockWriteGuard;
16
16
use std:: sync:: Condvar as StdCondvar ;
17
17
18
18
#[ cfg( feature = "backtrace" ) ]
19
- use { prelude:: HashMap , backtrace:: Backtrace , std:: sync:: Once } ;
19
+ use { prelude:: { HashMap , hash_map } , backtrace:: Backtrace , std:: sync:: Once } ;
20
20
21
21
#[ cfg( not( feature = "backtrace" ) ) ]
22
22
struct Backtrace { }
@@ -111,6 +111,9 @@ impl LockMetadata {
111
111
let sync_mutex_constr_regex = regex:: Regex :: new ( r"lightning.*debug_sync.*new" ) . unwrap ( ) ;
112
112
let mut found_debug_sync = false ;
113
113
for frame in backtrace. frames ( ) {
114
+ // If a constructor was inlined we should take the frame in which it was inlined
115
+ // (as its specific to the callsite), thus we look at the last available symbol,
116
+ // which the `backtrace` docs say will be the caller.
114
117
let symbol_name = frame. symbols ( ) . last ( ) . unwrap ( ) . name ( ) . unwrap ( ) . as_str ( ) . unwrap ( ) ;
115
118
if !sync_mutex_constr_regex. is_match ( symbol_name) {
116
119
if found_debug_sync {
@@ -126,11 +129,21 @@ impl LockMetadata {
126
129
}
127
130
}
128
131
129
- Arc :: new ( LockMetadata {
132
+ let res = Arc :: new ( LockMetadata {
130
133
locked_before : StdMutex :: new ( HashSet :: new ( ) ) ,
131
134
lock_idx,
132
135
lock_construction_bt : backtrace,
133
- } )
136
+ } ) ;
137
+
138
+ #[ cfg( feature = "backtrace" ) ]
139
+ {
140
+ let mut locks = unsafe { LOCKS . as_ref ( ) } . unwrap ( ) . lock ( ) . unwrap ( ) ;
141
+ match locks. entry ( lock_idx) {
142
+ hash_map:: Entry :: Occupied ( e) => return Arc :: clone ( e. get ( ) ) ,
143
+ hash_map:: Entry :: Vacant ( e) => { e. insert ( Arc :: clone ( & res) ) ; } ,
144
+ }
145
+ }
146
+ res
134
147
}
135
148
136
149
// Returns whether we were a recursive lock (only relevant for read)
@@ -150,7 +163,7 @@ impl LockMetadata {
150
163
if !read && * locked == * this {
151
164
// With `feature = "backtrace"` set, we may be looking at different instances
152
165
// of the same lock.
153
- debug_assert ! ( cfg!( feature = "backtrace" ) , "Tried to lock a lock while it was held!" ) ;
166
+ debug_assert ! ( cfg!( feature = "backtrace" ) , "Tried to acquire a lock while it was held!" ) ;
154
167
}
155
168
for locked_dep in locked. locked_before . lock ( ) . unwrap ( ) . iter ( ) {
156
169
if locked_dep. lock == * this && locked_dep. lock != * locked {
@@ -409,7 +422,7 @@ mod tests {
409
422
}
410
423
411
424
#[ test]
412
- fn read_recurisve_no_lockorder ( ) {
425
+ fn read_recursive_no_lockorder ( ) {
413
426
// Like the above, but note that no lockorder is implied when we recursively read-lock a
414
427
// RwLock, causing this to pass just fine.
415
428
let a = RwLock :: new ( ( ) ) ;
0 commit comments