Skip to content

Commit 54657a3

Browse files
committed
Merge branch 'master' of https://github.com/tokio-rs/tokio into sem-token-bucket
2 parents 8edc422 + a6be73e commit 54657a3

File tree

8 files changed

+136
-5
lines changed

8 files changed

+136
-5
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,16 +218,17 @@ releases are:
218218

219219
* `1.20.x` - LTS release until September 2023. (MSRV 1.49)
220220
* `1.25.x` - LTS release until March 2024. (MSRV 1.49)
221+
* `1.32.x` - LTS release until September 2024 (MSRV 1.63)
221222

222223
Each LTS release will continue to receive backported fixes for at least a year.
223224
If you wish to use a fixed minor release in your project, we recommend that you
224225
use an LTS release.
225226

226227
To use a fixed minor version, you can specify the version with a tilde. For
227-
example, to specify that you wish to use the newest `1.18.x` patch release, you
228+
example, to specify that you wish to use the newest `1.25.x` patch release, you
228229
can use the following dependency specification:
229230
```text
230-
tokio = { version = "~1.18", features = [...] }
231+
tokio = { version = "~1.25", features = [...] }
231232
```
232233

233234
### Previous LTS releases

tokio-util/src/codec/lines_codec.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use std::{cmp, fmt, io, str, usize};
66

77
/// A simple [`Decoder`] and [`Encoder`] implementation that splits up data into lines.
88
///
9+
/// This uses the `\n` character as the line ending on all platforms.
10+
///
911
/// [`Decoder`]: crate::codec::Decoder
1012
/// [`Encoder`]: crate::codec::Encoder
1113
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]

tokio/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,16 +218,17 @@ releases are:
218218

219219
* `1.20.x` - LTS release until September 2023. (MSRV 1.49)
220220
* `1.25.x` - LTS release until March 2024. (MSRV 1.49)
221+
* `1.32.x` - LTS release until September 2024 (MSRV 1.63)
221222

222223
Each LTS release will continue to receive backported fixes for at least a year.
223224
If you wish to use a fixed minor release in your project, we recommend that you
224225
use an LTS release.
225226

226227
To use a fixed minor version, you can specify the version with a tilde. For
227-
example, to specify that you wish to use the newest `1.18.x` patch release, you
228+
example, to specify that you wish to use the newest `1.25.x` patch release, you
228229
can use the following dependency specification:
229230
```text
230-
tokio = { version = "~1.18", features = [...] }
231+
tokio = { version = "~1.25", features = [...] }
231232
```
232233

233234
### Previous LTS releases

tokio/src/io/util/mem.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,18 @@ impl AsyncWrite for DuplexStream {
124124
Pin::new(&mut *self.write.lock()).poll_write(cx, buf)
125125
}
126126

127+
fn poll_write_vectored(
128+
self: Pin<&mut Self>,
129+
cx: &mut task::Context<'_>,
130+
bufs: &[std::io::IoSlice<'_>],
131+
) -> Poll<Result<usize, std::io::Error>> {
132+
Pin::new(&mut *self.write.lock()).poll_write_vectored(cx, bufs)
133+
}
134+
135+
fn is_write_vectored(&self) -> bool {
136+
true
137+
}
138+
127139
#[allow(unused_mut)]
128140
fn poll_flush(
129141
mut self: Pin<&mut Self>,
@@ -224,6 +236,37 @@ impl Pipe {
224236
}
225237
Poll::Ready(Ok(len))
226238
}
239+
240+
fn poll_write_vectored_internal(
241+
mut self: Pin<&mut Self>,
242+
cx: &mut task::Context<'_>,
243+
bufs: &[std::io::IoSlice<'_>],
244+
) -> Poll<Result<usize, std::io::Error>> {
245+
if self.is_closed {
246+
return Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()));
247+
}
248+
let avail = self.max_buf_size - self.buffer.len();
249+
if avail == 0 {
250+
self.write_waker = Some(cx.waker().clone());
251+
return Poll::Pending;
252+
}
253+
254+
let mut rem = avail;
255+
for buf in bufs {
256+
if rem == 0 {
257+
break;
258+
}
259+
260+
let len = buf.len().min(rem);
261+
self.buffer.extend_from_slice(&buf[..len]);
262+
rem -= len;
263+
}
264+
265+
if let Some(waker) = self.read_waker.take() {
266+
waker.wake();
267+
}
268+
Poll::Ready(Ok(avail - rem))
269+
}
227270
}
228271

229272
impl AsyncRead for Pipe {
@@ -285,6 +328,38 @@ impl AsyncWrite for Pipe {
285328
}
286329
}
287330

331+
cfg_coop! {
332+
fn poll_write_vectored(
333+
self: Pin<&mut Self>,
334+
cx: &mut task::Context<'_>,
335+
bufs: &[std::io::IoSlice<'_>],
336+
) -> Poll<Result<usize, std::io::Error>> {
337+
ready!(crate::trace::trace_leaf(cx));
338+
let coop = ready!(crate::runtime::coop::poll_proceed(cx));
339+
340+
let ret = self.poll_write_vectored_internal(cx, bufs);
341+
if ret.is_ready() {
342+
coop.made_progress();
343+
}
344+
ret
345+
}
346+
}
347+
348+
cfg_not_coop! {
349+
fn poll_write_vectored(
350+
self: Pin<&mut Self>,
351+
cx: &mut task::Context<'_>,
352+
bufs: &[std::io::IoSlice<'_>],
353+
) -> Poll<Result<usize, std::io::Error>> {
354+
ready!(crate::trace::trace_leaf(cx));
355+
self.poll_write_vectored_internal(cx, bufs)
356+
}
357+
}
358+
359+
fn is_write_vectored(&self) -> bool {
360+
true
361+
}
362+
288363
fn poll_flush(self: Pin<&mut Self>, _: &mut task::Context<'_>) -> Poll<std::io::Result<()>> {
289364
Poll::Ready(Ok(()))
290365
}

tokio/src/process/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,10 @@ impl Child {
11661166
/// If the caller wishes to explicitly control when the child's stdin
11671167
/// handle is closed, they may `.take()` it before calling `.wait()`:
11681168
///
1169+
/// # Cancel safety
1170+
///
1171+
/// This function is cancel safe.
1172+
///
11691173
/// ```
11701174
/// # #[cfg(not(unix))]fn main(){}
11711175
/// # #[cfg(unix)]

tokio/src/runtime/metrics/runtime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ impl RuntimeMetrics {
474474
///
475475
/// This metric only applies to the **multi-threaded** scheduler.
476476
///
477-
/// The worker steal count starts at zero when the runtime is created and
477+
/// The worker overflow count starts at zero when the runtime is created and
478478
/// increases by one each time the worker attempts to schedule a task
479479
/// locally, but its local queue is full. When this happens, half of the
480480
/// local queue is moved to the injection queue.

tokio/src/task/local.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ impl LocalSet {
575575
run_until.await
576576
}
577577

578+
#[track_caller]
578579
pub(in crate::task) fn spawn_named<F>(
579580
&self,
580581
future: F,

tokio/tests/duplex_stream.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#![warn(rust_2018_idioms)]
2+
#![cfg(feature = "full")]
3+
4+
use std::io::IoSlice;
5+
use tokio::io::{AsyncReadExt, AsyncWriteExt};
6+
7+
const HELLO: &[u8] = b"hello world...";
8+
9+
#[tokio::test]
10+
async fn write_vectored() {
11+
let (mut client, mut server) = tokio::io::duplex(64);
12+
13+
let ret = client
14+
.write_vectored(&[IoSlice::new(HELLO), IoSlice::new(HELLO)])
15+
.await
16+
.unwrap();
17+
assert_eq!(ret, HELLO.len() * 2);
18+
19+
client.flush().await.unwrap();
20+
drop(client);
21+
22+
let mut buf = Vec::with_capacity(HELLO.len() * 2);
23+
let bytes_read = server.read_to_end(&mut buf).await.unwrap();
24+
25+
assert_eq!(bytes_read, HELLO.len() * 2);
26+
assert_eq!(buf, [HELLO, HELLO].concat());
27+
}
28+
29+
#[tokio::test]
30+
async fn write_vectored_and_shutdown() {
31+
let (mut client, mut server) = tokio::io::duplex(64);
32+
33+
let ret = client
34+
.write_vectored(&[IoSlice::new(HELLO), IoSlice::new(HELLO)])
35+
.await
36+
.unwrap();
37+
assert_eq!(ret, HELLO.len() * 2);
38+
39+
client.shutdown().await.unwrap();
40+
drop(client);
41+
42+
let mut buf = Vec::with_capacity(HELLO.len() * 2);
43+
let bytes_read = server.read_to_end(&mut buf).await.unwrap();
44+
45+
assert_eq!(bytes_read, HELLO.len() * 2);
46+
assert_eq!(buf, [HELLO, HELLO].concat());
47+
}

0 commit comments

Comments
 (0)