Skip to content

Conversation

@leshow
Copy link
Contributor

@leshow leshow commented Dec 8, 2025

Motivation

Closes #3679

Was recently looking for write_all_vectored and found it missing, went to add it before realizing the MSRV is not there yet.

I thought I'd submit this anyway, when the MSRV version moves ahead you can accept, or we could copy in the IoSlice::advance_slices fn until that happens?

Solution

Tried to follow existing pattern for write_x methods

@leshow leshow changed the title add write_all_vectored to AsyncWriteExt (#3679) add write_all_vectored to AsyncWriteExt Dec 8, 2025
@leshow leshow force-pushed the write_all_vectored branch from 16eed02 to 34aa2a3 Compare December 8, 2025 21:30
@leshow leshow marked this pull request as draft December 8, 2025 21:34
@mox692
Copy link
Member

mox692 commented Dec 9, 2025

We could implement write_all_vectored but we should probably wait for the std stabilization. It's unlikely, but it's still possible for std version to change its api.

@mox692 mox692 added A-tokio Area: The main tokio crate M-io Module: tokio/io labels Dec 9, 2025
@leshow
Copy link
Contributor Author

leshow commented Dec 10, 2025

I thought that as well but I saw is_write_vectored implemented and it's also not stabilized. In any case, I just thought I would submit and offer. Ping me if you want to move forward with this in any way.

Copy link
Member

@martin-g martin-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this PR will be finished then it also needs an IT test.

/// &mut self,
/// bufs: &mut [IoSlice<'_>],
/// ) -> io::Result<()> {
/// let mut pos = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pos variable is never used. Maybe return it as a result to make the example more complete ?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, it was left over from a previous iteration. If you have a look at this playground link (ignore the generic param, just for testing) I think this is a valid representation if you were translating to async https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f25ce7e316683307b91a474f6c7f9496


pub(crate) fn write_all_vectored<'a, 'b, W>(
writer: &'a mut W,
bufs: &'a mut [IoSlice<'b>],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signature in std is a bit different:

Suggested change
bufs: &'a mut [IoSlice<'b>],
bufs: &'a mut &'a mut [IoSlice<'b>],

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's for advance_slices though, std signature for write_all_vectored has single &mut. https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all_vectored

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦
👍

let me = self.project();
while !me.bufs.is_empty() {
let n = ready!(Pin::new(&mut *me.writer).poll_write_vectored(cx, me.bufs))?;
if n == 0 {
Copy link
Member

@martin-g martin-g Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs extra care for the case when all bufs are empty. In this case 0 is not really an error.
Same improvement should be done in the (ignored) sample code in async_write_ext.rs

Copy link
Contributor Author

@leshow leshow Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what write_all_buf does. It calls poll_write_vectored and checks n == 0. It works in practice even with empty buffers when I've tried it with the async version (see the playground link)

I didn't see the tests folder, I will add some tests there and update the branch

edit:
I added some tests, including some with empty buffers to show this should work as expected

@leshow leshow force-pushed the write_all_vectored branch from 34aa2a3 to c2ff951 Compare December 12, 2025 07:11
@leshow leshow force-pushed the write_all_vectored branch from c2ff951 to a6c9bef Compare December 12, 2025 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-tokio Area: The main tokio crate M-io Module: tokio/io

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add AsyncWriteExt::write_all_vectored

3 participants