Import 'futures-task' rust crate version 0.3.4

Bug: b/151760391
Test: m crosvm.experimental
Change-Id: Ib6a3cca58deef21f4175ebeb1ff90c88eab36a20
diff --git a/src/waker.rs b/src/waker.rs
new file mode 100644
index 0000000..635bfe8
--- /dev/null
+++ b/src/waker.rs
@@ -0,0 +1,61 @@
+use super::arc_wake::ArcWake;
+use core::mem;
+use core::task::{Waker, RawWaker, RawWakerVTable};
+use alloc::sync::Arc;
+
+pub(super) fn waker_vtable<W: ArcWake>() -> &'static RawWakerVTable {
+    &RawWakerVTable::new(
+        clone_arc_raw::<W>,
+        wake_arc_raw::<W>,
+        wake_by_ref_arc_raw::<W>,
+        drop_arc_raw::<W>,
+    )
+}
+
+/// Creates a [`Waker`] from an `Arc<impl ArcWake>`.
+///
+/// The returned [`Waker`] will call
+/// [`ArcWake.wake()`](ArcWake::wake) if awoken.
+pub fn waker<W>(wake: Arc<W>) -> Waker
+where
+    W: ArcWake,
+{
+    let ptr = Arc::into_raw(wake) as *const ();
+
+    unsafe {
+        Waker::from_raw(RawWaker::new(ptr, waker_vtable::<W>()))
+    }
+}
+
+// FIXME: panics on Arc::clone / refcount changes could wreak havoc on the
+// code here. We should guard against this by aborting.
+
+#[allow(clippy::redundant_clone)] // The clone here isn't actually redundant.
+unsafe fn increase_refcount<T: ArcWake>(data: *const ()) {
+    // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop
+    let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(data as *const T));
+    // Now increase refcount, but don't drop new refcount either
+    let _arc_clone: mem::ManuallyDrop<_> = arc.clone();
+}
+
+// used by `waker_ref`
+unsafe fn clone_arc_raw<T: ArcWake>(data: *const ()) -> RawWaker {
+    increase_refcount::<T>(data);
+    RawWaker::new(data, waker_vtable::<T>())
+}
+
+unsafe fn wake_arc_raw<T: ArcWake>(data: *const ()) {
+    let arc: Arc<T> = Arc::from_raw(data as *const T);
+    ArcWake::wake(arc);
+}
+
+// used by `waker_ref`
+unsafe fn wake_by_ref_arc_raw<T: ArcWake>(data: *const ()) {
+    // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop
+    let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(data as *const T));
+    ArcWake::wake_by_ref(&arc);
+}
+
+unsafe fn drop_arc_raw<T: ArcWake>(data: *const ()) {
+    drop(Arc::<T>::from_raw(data as *const T))
+}