1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#![allow(clippy::cast_ptr_alignment)]
use std::marker::PhantomData;
use std::ops::Deref;
use std::ptr::NonNull;
use std::sync::Arc;
use std::task::{LocalWaker, Waker, Wake, UnsafeWake};
#[derive(Debug)]
pub struct LocalWakerRef<'a> {
local_waker: LocalWaker,
_marker: PhantomData<&'a ()>,
}
impl<'a> LocalWakerRef<'a> {
pub fn new(local_waker: LocalWaker) -> Self {
LocalWakerRef {
local_waker,
_marker: PhantomData,
}
}
}
impl<'a> Deref for LocalWakerRef<'a> {
type Target = LocalWaker;
fn deref(&self) -> &LocalWaker {
&self.local_waker
}
}
struct ReferencedArc<W> {
_marker: PhantomData<W>,
}
unsafe impl<W: Wake + 'static> UnsafeWake for ReferencedArc<W> {
#[inline]
unsafe fn clone_raw(&self) -> Waker {
let me = self as *const ReferencedArc<W> as *const Arc<W>;
Arc::clone(&*me).into()
}
#[inline]
unsafe fn drop_raw(&self) {}
#[inline]
unsafe fn wake(&self) {
let me = self as *const ReferencedArc<W> as *const Arc<W>;
W::wake(&*me)
}
#[inline]
unsafe fn wake_local(&self) {
let me = self as *const ReferencedArc<W> as *const Arc<W>;
W::wake_local(&*me)
}
}
#[inline]
pub unsafe fn local_waker_ref<W>(wake: &Arc<W>) -> LocalWakerRef<'_>
where
W: Wake + 'static,
{
let ptr = wake
as *const Arc<W>
as *const ReferencedArc<W>
as *const dyn UnsafeWake
as *mut dyn UnsafeWake;
let local_waker = LocalWaker::new(NonNull::new_unchecked(ptr));
LocalWakerRef::new(local_waker)
}
struct NonlocalReferencedArc<W> {
_marker: PhantomData<W>,
}
unsafe impl<W: Wake + 'static> UnsafeWake for NonlocalReferencedArc<W> {
#[inline]
unsafe fn clone_raw(&self) -> Waker {
let me = self as *const NonlocalReferencedArc<W> as *const Arc<W>;
Arc::clone(&*me).into()
}
#[inline]
unsafe fn drop_raw(&self) {}
#[inline]
unsafe fn wake(&self) {
let me = self as *const NonlocalReferencedArc<W> as *const Arc<W>;
W::wake(&*me)
}
#[inline]
unsafe fn wake_local(&self) {
let me = self as *const NonlocalReferencedArc<W> as *const Arc<W>;
W::wake(&*me)
}
}
#[inline]
pub fn local_waker_ref_from_nonlocal<W>(wake: &Arc<W>) -> LocalWakerRef<'_>
where
W: Wake + 'static,
{
let ptr = wake
as *const Arc<W>
as *const NonlocalReferencedArc<W>
as *const dyn UnsafeWake
as *mut dyn UnsafeWake;
let local_waker = unsafe { LocalWaker::new(NonNull::new_unchecked(ptr)) };
LocalWakerRef::new(local_waker)
}