-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix potential deadlock in state_key::Entry::drop #14670
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stamp
@@ -152,7 +152,7 @@ where | |||
let mut locked = self.inner.write(); | |||
if let Some(map2) = locked.get_mut(key1) { | |||
if let Some(entry) = map2.get(key2) { | |||
if entry.upgrade().is_none() { | |||
if entry.strong_count() == 0 { | |||
map2.remove(key2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not move the other conditional inside this if
statement, while already here :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure. I tried to think of why I wrote it that way other than one less level of nesting but I can't 🧌
d14009e
to
91caac6
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
If before Entry::drop() calls Registry::maybe_remove, the weak ref under the same key1 and key2 is replaced, Entry::drop can be called recursively resulting in a deadlock. The crux is we try to see if the entry has been replaced by trying to upgrading it to a strong ref, and it possible that the upgrade is successful and the result becomes a only ref to the new entry. This tries to fix it by determining the same thing by seeing if Weak::strong_count() is 0 instead of upgrading the weak ref.
5af585d
to
a67cf58
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
✅ Forge suite
|
✅ Forge suite
|
✅ Forge suite
|
(cherry picked from commit 8eb8b52)
💚 All backports created successfully
Questions ?Please refer to the Backport tool documentation and see the Github Action logs for details |
Description
If before Entry::drop() calls Registry::maybe_remove, the weak ref under the same key1 and key2 is replaced, Entry::drop can be called recursively resulting in a deadlock. The crux is we try to see if the entry has been replaced by trying to upgrading it to a strong ref, and it possible that the upgrade is successful and the result becomes a only ref to the new entry.
This tries to fix it by determining the same thing by seeing if Weak::strong_count() is 0 instead of upgrading the weak ref.
Type of Change
Which Components or Systems Does This Change Impact?
How Has This Been Tested?
eyes of hackers