Skip to content

Commit b521cc2

Browse files
authored
doc: document cancellation safety (#3900)
This patch documents cancellation safety. It also moves the "Avoid racy if preconditions" section in the select! documentation since otherwise the first code block on the page shows how not to use it, which seems counterintuitive.
1 parent 57c90c9 commit b521cc2

File tree

18 files changed

+500
-102
lines changed

18 files changed

+500
-102
lines changed

tokio/src/io/util/async_read_ext.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ cfg_io_util! {
105105
/// async fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>;
106106
/// ```
107107
///
108-
/// This function does not provide any guarantees about whether it
109-
/// completes immediately or asynchronously
108+
/// This method does not provide any guarantees about whether it
109+
/// completes immediately or asynchronously.
110110
///
111111
/// # Return
112112
///
@@ -138,6 +138,12 @@ cfg_io_util! {
138138
/// variant will be returned. If an error is returned then it must be
139139
/// guaranteed that no bytes were read.
140140
///
141+
/// # Cancel safety
142+
///
143+
/// This method is cancel safe. If you use it as the event in a
144+
/// [`tokio::select!`](crate::select) statement and some other branch
145+
/// completes first, then it is guaranteed that no data was read.
146+
///
141147
/// # Examples
142148
///
143149
/// [`File`][crate::fs::File]s implement `Read`:
@@ -177,8 +183,8 @@ cfg_io_util! {
177183
/// Usually, only a single `read` syscall is issued, even if there is
178184
/// more space in the supplied buffer.
179185
///
180-
/// This function does not provide any guarantees about whether it
181-
/// completes immediately or asynchronously
186+
/// This method does not provide any guarantees about whether it
187+
/// completes immediately or asynchronously.
182188
///
183189
/// # Return
184190
///
@@ -197,6 +203,12 @@ cfg_io_util! {
197203
/// variant will be returned. If an error is returned then it must be
198204
/// guaranteed that no bytes were read.
199205
///
206+
/// # Cancel safety
207+
///
208+
/// This method is cancel safe. If you use it as the event in a
209+
/// [`tokio::select!`](crate::select) statement and some other branch
210+
/// completes first, then it is guaranteed that no data was read.
211+
///
200212
/// # Examples
201213
///
202214
/// [`File`] implements `Read` and [`BytesMut`] implements [`BufMut`]:
@@ -261,6 +273,13 @@ cfg_io_util! {
261273
/// it has read, but it will never read more than would be necessary to
262274
/// completely fill the buffer.
263275
///
276+
/// # Cancel safety
277+
///
278+
/// This method is not cancellation safe. If the method is used as the
279+
/// event in a [`tokio::select!`](crate::select) statement and some
280+
/// other branch completes first, then some data may already have been
281+
/// read into `buf`.
282+
///
264283
/// # Examples
265284
///
266285
/// [`File`][crate::fs::File]s implement `Read`:

tokio/src/io/util/async_write_ext.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ cfg_io_util! {
9797
/// It is **not** considered an error if the entire buffer could not be
9898
/// written to this writer.
9999
///
100+
/// # Cancel safety
101+
///
102+
/// This method is cancellation safe in the sense that if it is used as
103+
/// the event in a [`tokio::select!`](crate::select) statement and some
104+
/// other branch completes first, then it is guaranteed that no data was
105+
/// written to this `AsyncWrite`.
106+
///
100107
/// # Examples
101108
///
102109
/// ```no_run
@@ -129,6 +136,13 @@ cfg_io_util! {
129136
///
130137
/// See [`AsyncWrite::poll_write_vectored`] for more details.
131138
///
139+
/// # Cancel safety
140+
///
141+
/// This method is cancellation safe in the sense that if it is used as
142+
/// the event in a [`tokio::select!`](crate::select) statement and some
143+
/// other branch completes first, then it is guaranteed that no data was
144+
/// written to this `AsyncWrite`.
145+
///
132146
/// # Examples
133147
///
134148
/// ```no_run
@@ -195,6 +209,13 @@ cfg_io_util! {
195209
/// It is **not** considered an error if the entire buffer could not be
196210
/// written to this writer.
197211
///
212+
/// # Cancel safety
213+
///
214+
/// This method is cancellation safe in the sense that if it is used as
215+
/// the event in a [`tokio::select!`](crate::select) statement and some
216+
/// other branch completes first, then it is guaranteed that no data was
217+
/// written to this `AsyncWrite`.
218+
///
198219
/// # Examples
199220
///
200221
/// [`File`] implements [`AsyncWrite`] and [`Cursor`]`<&[u8]>` implements [`Buf`]:
@@ -243,6 +264,7 @@ cfg_io_util! {
243264
/// while buf.has_remaining() {
244265
/// self.write_buf(&mut buf).await?;
245266
/// }
267+
/// Ok(())
246268
/// }
247269
/// ```
248270
///
@@ -254,13 +276,23 @@ cfg_io_util! {
254276
/// The buffer is advanced after each chunk is successfully written. After failure,
255277
/// `src.chunk()` will return the chunk that failed to write.
256278
///
279+
/// # Cancel safety
280+
///
281+
/// If `write_all_buf` is used as the event in a
282+
/// [`tokio::select!`](crate::select) statement and some other branch
283+
/// completes first, then the data in the provided buffer may have been
284+
/// partially written. However, it is guaranteed that the provided
285+
/// buffer has been [advanced] by the amount of bytes that have been
286+
/// partially written.
287+
///
257288
/// # Examples
258289
///
259290
/// [`File`] implements [`AsyncWrite`] and [`Cursor`]`<&[u8]>` implements [`Buf`]:
260291
///
261292
/// [`File`]: crate::fs::File
262293
/// [`Buf`]: bytes::Buf
263294
/// [`Cursor`]: std::io::Cursor
295+
/// [advanced]: bytes::Buf::advance
264296
///
265297
/// ```no_run
266298
/// use tokio::io::{self, AsyncWriteExt};
@@ -300,6 +332,14 @@ cfg_io_util! {
300332
/// has been successfully written or such an error occurs. The first
301333
/// error generated from this method will be returned.
302334
///
335+
/// # Cancel safety
336+
///
337+
/// This method is not cancellation safe. If it is used as the event
338+
/// in a [`tokio::select!`](crate::select) statement and some other
339+
/// branch completes first, then the provided buffer may have been
340+
/// partially written, but future calls to `write_all` will start over
341+
/// from the beginning of the buffer.
342+
///
303343
/// # Errors
304344
///
305345
/// This function will return the first error that [`write`] returns.

0 commit comments

Comments
 (0)