Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AsyncFdReadyGuard should provide a method to access the inner field of AsyncFd #3068

Closed
yaa110 opened this issue Oct 29, 2020 · 7 comments
Closed
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. M-io Module: tokio/io

Comments

@yaa110
Copy link

yaa110 commented Oct 29, 2020

Is your feature request related to a problem? Please describe.
Consider implementing AsyncRead for a type that wraps another type which implements std::io::Read and AsRawFd:

// TestIo implements `std::io::Read` and `AsRawFd`.
struct TestIo;

struct Test {
    io: AsyncFd<TestIo>,
}

impl AsyncRead for Test {
    fn poll_read(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
        buf: &mut ReadBuf<'_>,
    ) -> task::Poll<io::Result<()>> {
        match self.io.poll_read_ready(cx) {
            Poll::Ready(Ok(guard)) => {
                // Here I need to access `&mut TestIo` (`&mut guard.async_fd.inner`) to `read(...)` from. 
            },
            _ => unimplemented!(),
        }
    }
}

Describe the solution you'd like
AsyncFdReadyGuard should provide access to inner field of its async_fd field. for example:

// A method for `AsyncFdReadyGuard`
pub fn inner_mut(&mut self) -> &mut T {}

Describe alternatives you've considered
Aa an alternative, AsyncFd should implement AsyncRead and AsyncWrite like unexported PollEvented type.

Additional context
PollEvented is not exported in v0.3.x, and AsyncFd was added to provide somewhat similar functionalities (based on changes in mio 0.7.x), however, it lacks some useful implementations.

@yaa110 yaa110 added A-tokio Area: The main tokio crate C-feature-request Category: A feature request. labels Oct 29, 2020
@yaa110 yaa110 changed the title AsyncFdReadyGuard should provide a method to access the inner field of AsyncFd AsyncFdReadyGuard should provide a method to access the inner field of AsyncFd Oct 29, 2020
@Darksonn Darksonn added the M-io Module: tokio/io label Oct 29, 2020
@Darksonn
Copy link
Contributor

Hmm. The AsyncFdReadyGuard only has an immutable reference to the AsyncFd due to it also being returned by readable and writable.

@bdonlan
Copy link
Contributor

bdonlan commented Nov 2, 2020

Indeed. We discussed in the original PR the possibility of later defining a AsyncFdReadyGuardMut later for the case where we can get mut access to the object. One question is how often we actually have things like std::io::Read defined, and whether it would be preferable for the underlying object to (where possible) use direct OS calls with a non-mut reference (which would enable use of the futures-oriented interface)

@Sherlock-Holo
Copy link

Sherlock-Holo commented Nov 10, 2020

the AsyncFdReadyGuard can't access the inner, and the with_io or with_poll's argument f is only a closure which can't access the inner, so how do I do some IO operation?

@Darksonn
Copy link
Contributor

Currently poll_{read,write}_ready take &self, which is why they can't access the inner variable mutably. There are two options you might make use of to get around this now:

  1. Put a raw fd into the AsyncFd and store the object to be mutated next to the AsyncFd.
  2. Construct your code to only need &self access to the inner value. This is often possible because all the std types such as File, TcpStream and so on only require &self access to read and write to them.

In the future, we can add an poll_{read,write}_ready_mut method that takes AsyncFd by &mut self and returns an AsyncFdReadyGuardMut, which allows &mut access to the inner value. Alternatively a clear_{read,write} method can be added to allow clearing it after releasing the guard.

WGH- added a commit to WGH-/rust-timerfd that referenced this issue Dec 9, 2020
Taking mutable reference makes TimerFd unusable with
tokio::io::unix::AsyncFd (recently introduced in tokio 0.4).
See tokio-rs/tokio#3068 (comment)

All std types based on file descriptors, like File and TcpStream,
actually take non-mutable references in their read/write methods as well.
@Sherlock-Holo
Copy link

@Darksonn Is there any release plan about poll_{read,write}_ready_mut?

@Darksonn
Copy link
Contributor

See #3208.

@Darksonn
Copy link
Contributor

Darksonn commented Dec 22, 2020

Fixed by #3304.

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 C-feature-request Category: A feature request. M-io Module: tokio/io
Projects
None yet
Development

No branches or pull requests

4 participants