-
Notifications
You must be signed in to change notification settings - Fork 1.8k
RAII chapter for idiomatic rust #2820
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
base: main
Are you sure you want to change the base?
Conversation
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
src/idiomatic/leveraging-the-type-system/raii/drop_limitations.md
Outdated
Show resolved
Hide resolved
src/idiomatic/leveraging-the-type-system/raii/drop_limitations.md
Outdated
Show resolved
Hide resolved
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.
Looks pretty good, there's lots of good stuff in this chapter 😁 I've got various feedback below, but it's definitely off to a good start!
I started to action all feedback since today. I'll explicitly re-request reviews once I am done. Probably best not to review again until then. |
- directly where possible - otherwise as inline feedback as notes to take into account for next draft
refresher on `RAII` and use the OS File Descriptor example to start the discussions around RAII all previous content is for now moved to `_old` for my own reference, will add the new content based on the agreed upon new structure next.
The four slides in the RAII chapter are ready for review again. |
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.
This is looking pretty good. The drop bomb and scope guard slides look good to me, my biggest suggestion is that we might want to split the mutex slide up so that it flows a bit better.
- Insert `panic!("oops")` at the start of `read_to_end()` to show that `drop()` | ||
still runs during unwinding. Rust guarantees this unless the panic strategy is | ||
set to `abort`. |
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.
- Insert `panic!("oops")` at the start of `read_to_end()` to show that `drop()` | |
still runs during unwinding. Rust guarantees this unless the panic strategy is | |
set to `abort`. | |
- Insert `panic!("oops")` at the start of `read_to_end()` to show that `drop()` | |
still runs during unwinding. |
You cover this in the next bullet point, so I think this one can be simplified.
fn drop(&mut self) { | ||
// [...] | ||
println!("drop MutexGuard"); | ||
} |
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.
I think this is failing to demonstrate the crucial part of MutexGuard
: That it reports back to the Mutex
on drop, unlocking the mutex. I think we should have a stubbed-out unlock
method on Mutex
and call it on drop here.
impl<'a, T> std::ops::Deref for MutexGuard<'a, T> { | ||
type Target = T; | ||
fn deref(&self) -> &T { | ||
self.value | ||
} | ||
} | ||
|
||
impl<'a, T> std::ops::DerefMut for MutexGuard<'a, T> { | ||
fn deref_mut(&mut self) -> &mut T { | ||
self.value | ||
} | ||
} |
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.
For brevity I think we can omit the Deref
impls from the example and have the code in main
directly access guard.value
. That's not an accurate depiction of how the actual MutexGuard
works, but I think is good enough for us 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.
I've left a couple of comments in here about improving the example code, but I'd like to also propose a higher level change. I think we could split this slide in two, where the first slide would be "Mutex and MutexGuard" that just demonstrates using a mutex, i.e. what's in the main
function on this slide. Then we'd have a second slide "Drop Guards" that shows the dummy implementation of Mutex
and MutexGuard
in order to show how to implement this pattern.
I think doing it that way would flow a bit better, because we would first show how the pattern is used, then dig into the details of how the pattern is implemented. It'd also allow us to slightly expand the example implementation to be a bit more detailed. Here's a playground link with a rough example of what the second slide would show. That doesn't compile currently because it's modifying a field of Mutex
in a &self
method. That could be fixed with atomics, which would be more accurate but would also add more clutter that I think would distract from the main point of demonstrating the general pattern of drop guards.
## Poisoning | ||
|
||
- If a thread panics while holding the lock, the value may be in a corrupt | ||
state. | ||
|
||
- To signal this, the standard library uses poisoning. When `Drop` runs during a | ||
panic, the mutex marks itself as poisoned. | ||
|
||
- On the next `lock()`, this shows up as an error. The caller must decide | ||
whether to proceed or handle the error differently. | ||
|
||
- See this example showing the standard library API with poisoning: | ||
<https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=6fb0c2e9e5cbcbbae1c664f4650b8c92> |
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.
I don't think it's worth going into poisoning here. The point here is to demonstrate the drop guard pattern, not to talk in detail about how mutexes work.
### Mutex Lock Lifecycle | ||
|
||
```bob | ||
+---------------+ +----------------------+ | ||
| Mutex<T> | lock | MutexGuard<T> | | ||
| Unlocked | ------> | Exclusive Access | | ||
+---------------+ +----------------------+ | ||
|
||
^ | drop | ||
| no | | ||
+---------------+ | | ||
| | | ||
| V | ||
|
||
+---------------+ yes +-------------------+ | ||
| Mutex<T> | <---- | Thread panicking? | | ||
| Poisoned | +-------------------+ | ||
+---------------+ | ||
|
||
| | ||
| lock | ||
| | ||
v | ||
|
||
+------------------+ | ||
| Err ( Poisoned ) | | ||
+------------------+ | ||
``` |
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.
I don't think we need this diagram, especially if we drop the discussion of poisoning as I suggested in another comment.
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.
I had a brief look at the updates since my last comments, and I'm happy enough!
This PR adds the RAII chapter for the idiomatic Rust deep dive.