webrtc
webrtc copied to clipboard
Cancel safety audit
When writing futures that are likely to run in race with others using e.g. tokio::select! it's important to consider cancel safety.
A typical pattern that isn't cancel safe is
async fn read_parsed<T>() -> Result<T>
where T: TryFrom<Vec<u8>>
{
let mut buf = vec![0; 100];
let n = read_io(&mut buf).await?;
buf.truncate(n);
let parsed = T::try_from(buf)?;
// If the future is dropped here the data has still been read from some I/O device
// but the buffer and parsed result are deallocated and never returned to the caller.
some_other_thing(&parsed).await?;
Ok(parsed)
}
We should audit the codebase for patterns like this and either: make the futures cancel safe or at least document the fact that they aren't.
I've discovered three cases so far:
- ~
GeneratorStream::read~ Fixed - ~
interceptor::report::receiver::receiver_stream ::Receiverstream::read~ Fixed interceptor::twcc::receiver::receiver_stream ::ReceiverStream::read
We might able to utilise Codec from tokio-utils in some instances to help with this.
Crates
Here's a list of all the crates and their audit status for cancel saftey
- [ ] rtp
- [ ] rtcp
- [ ] sctp
- [ ] data
- [ ] ice
- [ ] dtls
- [ ] mdns
- [ ] media
- [ ] interceptor
- [ ] webrtc
- [ ] sdp
- [ ] stun
- [ ] turn
- [ ] util
More reading about cancel safety
- https://blog.yoshuawuyts.com/async-cancellation-1/#cancelling-futures
- http://smallcultfollowing.com/babysteps/blog/2022/06/13/async-cancellation-a-case-study-of-pub-sub-in-mini-redis/
This PR is a first step in this, it fixes two of the above identified issues