summaryrefslogtreecommitdiffstats
path: root/src/test/ui/async-await/auxiliary/arc_wake.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/async-await/auxiliary/arc_wake.rs')
-rw-r--r--src/test/ui/async-await/auxiliary/arc_wake.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/test/ui/async-await/auxiliary/arc_wake.rs b/src/test/ui/async-await/auxiliary/arc_wake.rs
new file mode 100644
index 000000000..c21886f26
--- /dev/null
+++ b/src/test/ui/async-await/auxiliary/arc_wake.rs
@@ -0,0 +1,64 @@
+// edition:2018
+
+use std::sync::Arc;
+use std::task::{
+ Waker, RawWaker, RawWakerVTable,
+};
+
+macro_rules! waker_vtable {
+ ($ty:ident) => {
+ &RawWakerVTable::new(
+ clone_arc_raw::<$ty>,
+ wake_arc_raw::<$ty>,
+ wake_by_ref_arc_raw::<$ty>,
+ drop_arc_raw::<$ty>,
+ )
+ };
+}
+
+pub trait ArcWake {
+ fn wake(self: Arc<Self>);
+
+ fn wake_by_ref(arc_self: &Arc<Self>) {
+ arc_self.clone().wake()
+ }
+
+ fn into_waker(wake: Arc<Self>) -> Waker where Self: Sized
+ {
+ let ptr = Arc::into_raw(wake) as *const ();
+
+ unsafe {
+ Waker::from_raw(RawWaker::new(ptr, waker_vtable!(Self)))
+ }
+ }
+}
+
+unsafe fn increase_refcount<T: ArcWake>(data: *const ()) {
+ // Retain Arc by creating a copy
+ let arc: Arc<T> = Arc::from_raw(data as *const T);
+ let arc_clone = arc.clone();
+ // Forget the Arcs again, so that the refcount isn't decrased
+ let _ = Arc::into_raw(arc);
+ let _ = Arc::into_raw(arc_clone);
+}
+
+unsafe fn clone_arc_raw<T: ArcWake>(data: *const ()) -> RawWaker {
+ increase_refcount::<T>(data);
+ RawWaker::new(data, waker_vtable!(T))
+}
+
+unsafe fn drop_arc_raw<T: ArcWake>(data: *const ()) {
+ // Drop Arc
+ let _: Arc<T> = Arc::from_raw(data as *const T);
+}
+
+unsafe fn wake_arc_raw<T: ArcWake>(data: *const ()) {
+ let arc: Arc<T> = Arc::from_raw(data as *const T);
+ ArcWake::wake(arc);
+}
+
+unsafe fn wake_by_ref_arc_raw<T: ArcWake>(data: *const ()) {
+ let arc: Arc<T> = Arc::from_raw(data as *const T);
+ ArcWake::wake_by_ref(&arc);
+ let _ = Arc::into_raw(arc);
+}