rustasync-await

How to construct !Send objects on another thread?


I have the following code:

trait Foo {
  fn do_it(&self) -> ();
}

struct FooImpl {
  make_this_not_send: *const (),
}

impl Foo for FooImpl { ... }

fn spawn(new: impl FnOnce() -> Box<dyn Foo> + Send + 'static) {
  tokio::spawn(async move {
    let foo = new();
    
    loop {
      foo.do_it();

      // ...
    }
  });
}

Problem is that this does not compile because Foo is not easily Send. I do not really understand why it needs to be though. I only want to create a foo in some thread and leave it there. I hoped the new() approach outlined above would do it, but it still requires Foo to be Send.

Why does it need to be Send? What is the idiomatic way of solving this problem?


Solution

  • The default tokio runtime is multi-threaded, so this means that any Future has to be able to be Send to another thread.

    This means that any async function which owns an non Send object across .await calls will not be Send and does not work with the multi-threaded runtime.

    You have three options: