kvdb-rocksdb: fix deadlock caused by double read lock #396
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR fixes a deadlock caused by double read lock in kvdb-rocksdb/src/lib.rs.
The first read lock is in
write()
:parity-common/kvdb-rocksdb/src/lib.rs
Lines 480 to 481 in 8e12159
Then
iter_with_prefix()
is called.parity-common/kvdb-rocksdb/src/lib.rs
Line 511 in 8e12159
The second readlock is in
iter_with_prefix()
:parity-common/kvdb-rocksdb/src/lib.rs
Lines 575 to 576 in 8e12159
According to parking_lot::RwLock:
“readers trying to acquire the lock will block even if the lock is unlocked when there are writers waiting to acquire the lock.”
“attempts to recursively acquire a read lock within a single thread may result in a deadlock.”
Therefore, when two read locks are interleaved by a write lock (e.g. in
close()
,restore()
) from another thread, a deadlock happens.The fix is to use a
read_recursive()
initer_with_prefix()
. It concerns me thatread_recursive()
may starve the write lock. But this seems the only solution currently.Or maybe we can create a new version
iter_with_prefix_recursive()
usingread_recursive()
and use this version inwrite()