Skip to content

Instantly share code, notes, and snippets.

@benaubin
Last active January 16, 2021 22:49
Show Gist options
  • Save benaubin/1fd897f264e0a366e5e05b708a289518 to your computer and use it in GitHub Desktop.
Save benaubin/1fd897f264e0a366e5e05b708a289518 to your computer and use it in GitHub Desktop.
turn a mio::waker into a std::task::waker
use std::{
sync::Arc,
task::{RawWaker, RawWakerVTable, Waker},
}
/// turn a mio::waker into a std::task::Waker
fn make_waker(waker: Arc<mio::Waker>) -> Waker {
static WAKER_VTABLE: &'static RawWakerVTable =
RawWakerVTable::new(clone_waker, wake, wake_by_ref, drop);
unsafe fn clone_waker(ptr: *const mio::Waker) -> RawWaker {
// retrieve the arc, wrapping in ManuallyDrop so refcount is not decreased
let arc = std::mem::ManuallyDrop::new(Arc::from_raw(ptr));
// clone the arc. because it is wrapped in ManuallyDrop, the refcount will not be decreased, either
arc.clone();
RawWaker::new(ptr, WAKER_VTABLE)
}
unsafe fn wake(ptr: *const mio::Waker) {
Arc::from_raw(ptr).wake().unwrap();
}
unsafe fn wake_by_ref(ptr: *const mio::Waker) {
(ptr as &mio::Waker).wake().unwrap();
}
unsafe fn drop(ptr: *const mio::Waker) {
Arc::from_raw(ptr)
}
let ptr = Arc::into_raw(waker);
let waker = RawWaker::new(ptr, WAKER_VTABLE);
// safety: valid because we uphold the contract of RawWaker and RawWakerVTable
unsafe { Waker::from_raw(waker) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment