1

I have a UIO driver that within a so-called wait_on_complete function, polls a file descriptor to wait on an interrupt. This is completely synchronous, so blocks (with a timeout). I'd like to migrate the code such that wait_on_complete is async (or can be wrapped easily so as to create a useful Future), but I'm not sure of the best strategy for this.

My thinking on options are:

  1. Use mio::Poll, which as I understand it implies using the Tokio reactor, but I can't follow the API for this in Tokio ^0.3. There seemed to be a few things around this in Tokio 0.2, but they've gone (though it still seems to be in the code - is this just missing docs?).
  2. Use something like polling which comes with it's own reactor. The problem with this is the driver seems the wrong location for the reactor.
  3. Run the synchronous code in its own thread and communicate with async channels. Given one of the points of async is to integrate asynchronous IO properly, this seems architecturally a poor choice (indeed, the IO fits very well into the main state machine).
  4. Something else I don't know about.

(1) Seems like the obvious solution, but I'm not entirely clear how to go about this. Is there some up-to-date documentation on creating one's own mio device and using that in a Tokio runtime?

Are there other methods I've missed for doing what I'm wanting to do? Have I missed something in my considerations?

Henry Gomersall
  • 8,434
  • 3
  • 31
  • 54
  • Most runtimes have a way to handle blocking tasks by running them on a seperate thread. See [`tokio::spawn_blocking`](https://docs.rs/tokio/0.3.5/tokio/task/fn.spawn_blocking.html) – Ibraheem Ahmed Dec 07 '20 at 15:25
  • @IbraheemAhmed Thanks, I'm aware of that (it was the supposed mechanism of (3) in my list). – Henry Gomersall Dec 07 '20 at 15:43

1 Answers1

1

This is very easy to do with Async from async-io.

Make a struct encapsulating your fd, implement AsRawFd for it, then wrap it with Async.

This allows you to do custom async operations with read_with and write_with.

Dirbaio
  • 2,921
  • 16
  • 15
  • This look similar to the [Tokio approach](https://docs.rs/tokio/0.3.6/tokio/io/unix/struct.AsyncFd.html) I've subsequently learned is the current Tokio strategy. Where does the reactor run in the case of `async-io`? (as in, does it depend on the runtime in some way?) – Henry Gomersall Dec 22 '20 at 14:02
  • There's a doc paragraph on `Async`: "However, do not use Async with types like File, Stdin, Stdout, or Stderr because all operating systems have issues with them when put in non-blocking mode." – Henry Gomersall Dec 22 '20 at 14:09
  • `async-io` spawns its own reactor thread, so it doesn't depend on a particular runtime/executor. It itself is the reactor used for `async-std` too. – Dirbaio Dec 23 '20 at 00:46
  • 1
    If your fd is something you obtained with `open()` from a UIO device it should be fine. The problem with files is for "real" files that store data on a filesystem. – Dirbaio Dec 23 '20 at 00:47
  • Just for completeness for future readers: Tokio takes a different approach to the reactor in that it runs in an executor thread. Which is better depends on the use case. – Henry Gomersall Dec 23 '20 at 12:51