Skip to content

Waker appears to be missing Rc/Arc<T, A> support #139

@jasta

Description

@jasta

The async Waker system (and in particular RawWaker and the Wake trait) appears to lack a way to work with Rc/Arc instances not in the Global allocator. It's also onerous and intrusive to manually implement this through RawWaker because the allocator instance present in Rc/Arc is lost when using Arc::into_raw/from_raw. It feels like the only way to do this currently is to store the allocator in T itself, then launder Arc<T, A> through Arc<T, Global> as such:

struct Task<A> {
  ...
  alloc: A,
}

impl<A: Allocator> Wake for Task<A> {
  fn wake(self: Arc<Self>) {
     let actual_arc = Arc::from_raw_in(Arc::into_raw(self), self.alloc.clone())
     ...
  }
}

This is very fragile though as things can appear to work correctly without this hack, papered over by the fact that it's fairly unlikely that through the Waker machinery the ref count of the Arc drops to 0 and thus deallocate is called on the Global allocator instead of the correct one. But if it does happen, it would be undefined and likely crash (as I saw in practice when trying to generalized FuturesUnordered to use allocator-api).

This problem generalizes to LocalWaker/LocalWake as well.

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