Skip to content

Rust guest async bindings: low-overhead streams with no copies difficult to make memory safe #471

Open
@alexcrichton

Description

@alexcrichton

Whether or not we'll change anything as a result of this, I'm not sure. In thinking more about how bindings will work in Rust I'm realizing that many possible bindings to futures/streams are all memory-unsafe in Rust and would require unsafe (which is something we want to avoid). The tl;dr; is:

  • "Leaking" an object in Rust is safe. I can go more into why, but the basic assumption in rust is that destructors are optional and cannot be required for memory safety.
  • Ideally we'd have a binding for stream<u8> that looks something along the lines of async fn write(&mut self, bytes: &[u8]) -> Result<()> which implicitly borrows bytes for the duration of the entire async function.
  • This was originally going to be made sound by having a destructor of the returned future which cancelled the write, but that's not possible because it's possible to leak the future and not run its destructor.

Effectively all interaction with futures/streams will have to take ownership of buffers temporarily while the operation is in progress. AFAIK that's pretty un-idiomatic in Rust and gets quite cumbersome, but there's effectively no other option for memory-safe code. It basically means that the Rust APIs will have to get opinionated very quickly which isn't a great sign for foundational APIs.

There's not really anything that can be done about this at the component model level apart from radically redesigning things which is more-or-less off the table at this point. Otherwise I mostly wanted to note this down as a consequence of an io-uring style API (which AFAIK io-uring has no low-level safe bindings in Rust as well, probably for similar reasons)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions