Skip to content

Conversation

@tontinton
Copy link
Contributor

@tontinton tontinton commented Jan 2, 2026

built on #609

Usage (file -> socket example)

use compio_fs::pipe::{anonymous, splice};
use compio_fs::File;

let file = File::open("data.bin").await?;
let (rx, tx) = anonymous()?;

// Splice file -> pipe (zero-copy)
let n = splice(&file, &tx, 4096).offset_in(0).await?;

// Then splice pipe -> socket (zero-copy)
let n = splice(&rx, &socket, 4096).await?;


#[cfg(linux_all)]
impl<TIn: AsFd + 'static, TOut: AsFd + 'static> IntoFuture for SpliceBuilder<TIn, TOut> {
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output>>>;
Copy link
Member

Choose a reason for hiding this comment

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

Please don't use Box. It's OK to add a new async fn to do so. Actually I guess a simple splice method is OK instead of a builder...

Copy link
Member

Choose a reason for hiding this comment

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

It's OK to keep the builder. Just don't Box please.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh so I need to add a build() method to create the Splice, do we want to keep that API? or should I make a simple splice method that receives all arguments instead?

Copy link
Member

Choose a reason for hiding this comment

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

Hi! I have exposed the future type for submit in #614. You can rebase and use that directly so no need for the Box.

self.offset_out,
self.len,
)
.flags(self.flags);
Copy link
Member

Choose a reason for hiding this comment

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

Another problem is that, it's OK to assume nonblocking everywhere on polling driver. Therefore, we should wait for the readiness of the fds, either in the driver, or here with PollFd.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the same comment as #609 (comment), right?

Copy link
Member

Choose a reason for hiding this comment

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

Yes. I made it to check the in fd in the driver, but the out fd has to be polled manually. The flags should also be modified to use the nonblocking IO. Please check the driver type at runtime.

@Berrysoft
Copy link
Member

Could you rebase this PR?

@tontinton
Copy link
Contributor Author

rebased

@tontinton tontinton requested a review from George-Miao January 6, 2026 09:29
Copy link
Member

@Berrysoft Berrysoft left a comment

Choose a reason for hiding this comment

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

Thanks for the rebase. I think there are some existing issues to be solved.

@tontinton tontinton force-pushed the splice-fs branch 2 times, most recently from 6c82d3e to d81b1c1 Compare January 6, 2026 19:05
@tontinton tontinton requested a review from Berrysoft January 6, 2026 19:05
@tontinton
Copy link
Contributor Author

yeah I only rebased :)
now I think I resolved all comments

@tontinton tontinton force-pushed the splice-fs branch 4 times, most recently from b785541 to f18ba9d Compare January 6, 2026 21:19
@tontinton
Copy link
Contributor Author

I modified the driver to include op_type() like other opcodes in file, otherwise the test (nightly, ubuntu-22.04, polling,ring, true) and test (nightly, ubuntu-22.04, polling,native-tls,ring, true) tests failed for me

@Berrysoft
Copy link
Member

Berrysoft commented Jan 7, 2026

Thanks! Your changes for op_type is correct.

However, I still think that it's not easy to implement IntoFuture or Future directly. Splice on polling driver only polls one fd, but the other one should also be polled. The method should be like

if driver_type == DriverType::Poll {
    loop {
        let poll_in = PollFd::new(in_fd, Read);
        let poll_out = PollFd::new(out_fd, Write);
        try_join!(submit(poll_in), submit(poll_out))?;
        match syscall!(libc::splice(...)) {
            Ok(n) => break Ok(n),
            Err(e) if e.kind() == ErrorKind::WouldBlock => continue,
            Err(e) => break Err(e),
        }
    }
} else {
    let op = Splice::new(...);
    submit(op).await
}

unsafe fn call(&self) -> libc::ssize_t {
let mut offset_in = self.offset_in;
let mut offset_out = self.offset_out;
unsafe {
Copy link
Member

Choose a reason for hiding this comment

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

Can you move the safe compuation of arguments out of the unsafe block so that we don't accidently missing any unwanted unsafe calls?

/// .flags(libc::SPLICE_F_MOVE)
/// .await?;
/// ```
#[cfg(linux_all)]
Copy link
Member

Choose a reason for hiding this comment

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

Okay I'm thinking maybe we want to have a dedicated linux_all mod for these operations. Slapping cfg(linux_all) everywhere seems too tedious.

@tontinton
Copy link
Contributor Author

ok I've sat on it some time now, I got to something working, but I think we should wait for #617, it will improve the solution

@tontinton tontinton requested a review from George-Miao January 7, 2026 20:48
@tontinton tontinton force-pushed the splice-fs branch 2 times, most recently from d663a84 to 077ab56 Compare January 7, 2026 20:53
@George-Miao
Copy link
Member

@tontinton Yeah.. we are having some trouble actually implement #617 (for now it still wakes whenever fd has an event). It's kind of hard.

@tontinton
Copy link
Contributor Author

@tontinton Yeah.. we are having some trouble actually implement #617 (for now it still wakes whenever fd has an event). It's kind of hard.

Maybe we can merge this anyway then?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request package: fs Related to compio-fs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants