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

How to use stabby futures #56

Closed
kylezs opened this issue Feb 20, 2024 · 2 comments
Closed

How to use stabby futures #56

kylezs opened this issue Feb 20, 2024 · 2 comments

Comments

@kylezs
Copy link

kylezs commented Feb 20, 2024

It's not clear to me what's meant by the comment on the futures module.

/// Futures can be ABI-stable if you wish hard enough
#[cfg_attr(
    feature = "unsafe_wakers",
    deprecated = "Warning! you are using the `stabby/unsafe_wakers` feature. This could cause UB if you poll a future received from another shared library with mismatching ABI! (this API isn't actually deprecated)"
)]

I've currently got a simple entry point that returns a future:

#[stabby::import(name = "first_shared_lib", canaries = "none")]
extern "C" {
    fn entry_point(
        args: crate::MyArgsMirror,
    ) -> stabby::future::DynFuture<'static, stabby::result::Result<(), ()>>;
}

This works, the code is called and returned correctly (nb: both are compiled with the same version here, but they won't necessarily be in the future - hence I'm trying to use stabby) - however I get a warning:

warning: `extern` block uses type `RawWaker`, which is not FFI-safe
  --> runner/src/main.rs:14:10
   |
14 |     ) -> stabby::future::DynFuture<'static, stabby::result::Result<(), ()>>;
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
   |
   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
   = note: this struct has unspecified layout
   = note: `#[warn(improper_ctypes)]` on by default

What's the intended way for this to work? Are there more detailed examples somewhere?

Thanks!

@p-avital
Copy link
Collaborator

p-avital commented Apr 3, 2024

Hi there,

Sorry for taking so long to reply, this fell through while I was on holiday.

The unsafe_wakers feature exists for users who do compiler-version pinning and use canaries (ideally without disabling any of them) to detect if compiler options that might affect ABI have occurred. Even if you do pin compiler version and options, there's no guarantee the layout of the standard waker won't change between compiling the dynamic library and its host, hence their name.

I strongly advise against using that feature (which has now become a cfg to let the final crate in the compile chain have final say on whether or not it is enabled, regardless of the dependencies) if you don't do compiler pinning, as this will be a very fast way to get UB.

In general, I'd advise you stick with safe wakers until you've measured that the (small) overhead they add is unacceptable for your application (and that compiler pinning is an option for you).

Finally, I'm working (at the slow pace that my schedule and small experience in rustc's codebase dictate) on an RFC to make futures generic over their wakers, allowing the existence of stable wakers with a stable ABI without compromising the current wakers' API and performance.

If you need ABI-stability and 0-overhead cross-FFI futures (arguably, this need is unlikely since the overhead is negligible compared to the typical time-scales of async workloads), I'd appreciate any support you can give to this RFC to try and get traction for it :)

@p-avital
Copy link
Collaborator

p-avital commented Apr 3, 2024

Closing this issue as it doesn't really have a CTA. Feel free to reopen it if you have more questions on the topic that you feel haven't been addressed :)

@p-avital p-avital closed this as completed Apr 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants