Today I was explaining some details of async and I noticed that:
RawWaker is !Send + !Sync
RawWakerVTable's documentation describes what the function pointers must do but doesn't mention any thread-safety requirements.
But is it not the case that (because Waker is Send + Sync) a waker can be invoked on any thread, so the vtable's functions must be prepared to run on any thread?
And, is there reason for RawWaker to be !Send + !Sync, or is that merely the happenstance that it contains raw pointers?
If I'm right about the above, then I think it would be good if the documentation specified that the functions must expect threading (e.g. the vtable clone, if using a reference count, should use Arc and not Rc or similar). I'd be interested in writing that documentation, but I wanted to check my assumptions, hence this post.
I would say it’s rather obvious (with sufficient experience, and looking at the implementations and use-cases) that your interpretation is correct and RawWaker is only !Send + !Sync because it contains a raw pointer
(and given that it’s safely constructible from, and (with waker_getters) gives access to its fields, it’s probably a good design to keep it this way, as a simple plain-old-datatype wrapper around *const+&'static RawWakerVTable).
So I would say, yes there’s definitely a poorly documented (or essentially undocumented) but essential thread-safety requirement for the implementation of a Waker via RawWaker.