5

In the documentation for AsyncReadExt::read_u64 it says it has the same errors as AsyncReadExt::read_exact, but says nothing about cancellation safety. The same holds for all the other read_<type> functions on AsyncReadExt. It seems likely that they have the same cancellation safety as read_exact (that is, none), but is that true?

Is there another way to read the next 4 bytes in a cancel safe way?

There's stuff in Tokio that covers my use case at a higher level, but I'd like to know how I would do this myself.

AlbertGarde
  • 369
  • 1
  • 13

1 Answers1

3

No it's not cancel safe

While the implementations of read_exact and the read_* functions differ they do the exact same thing:

  1. Poll the underlying AsyncRead into a buffer, propagating errors appropriately.
  2. If the reader returns Poll::Pending, propagate that.
  3. If the buffer is full, return Ok(()).
  4. If the buffer isn't full, repeat the whole thing over again.

If the future is canceled after some bytes are read it leaves the reader in an unknown state, thereby rendering them not cancel safe.

edit: making these methods object safe is difficult, the only way to do it is to rewrite the methods to do one of two things: when it is dropped, somehow communicate the internal state to a listener on the outside, probably via a channel, or have the future somehow run itself to completion when it's dropped. It would be preferrable to rewrite the surrounding code to not depend on its cancel safety.

Aiden4
  • 2,504
  • 1
  • 7
  • 24
  • Thanks, this answers the first part of the question, but not the second question of how I then should do this in a cancel safe way. If you can answer that as well, I'll accept this answer. – AlbertGarde Oct 08 '21 at 08:05
  • @PenguinAgen edited, I hope the new edit answers your question – Aiden4 Oct 08 '21 at 14:31