Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Jan 12, 2022
1 parent d3d8119 commit 0e72d61
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 23 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Expand Up @@ -244,9 +244,9 @@ jobs:
- name: Install Rust
run: rustup toolchain install nightly --component miri && rustup default nightly
# futures-executor uses boxed futures so many tests trigger https://github.com/rust-lang/miri/issues/1038
- run: cargo miri test --workspace --exclude futures-executor --all-features
- run: cargo miri test --workspace --exclude futures-executor --all-features --no-fail-fast
env:
MIRIFLAGS: -Zmiri-disable-isolation # TODO: use -Zmiri-tag-raw-pointers
MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-tag-raw-pointers

san:
name: cargo test -Z sanitizer=${{ matrix.sanitizer }}
Expand Down
23 changes: 10 additions & 13 deletions futures-task/src/future_obj.rs
Expand Up @@ -224,7 +224,7 @@ mod if_alloc {
}

unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) {
drop(Box::from_raw(ptr as *mut F))
drop(Box::from_raw(ptr.cast::<F>()))
}
}

Expand Down Expand Up @@ -252,10 +252,9 @@ mod if_alloc {
where
F: Future<Output = T> + 'a,
{
fn into_raw(mut self) -> *mut (dyn Future<Output = T> + 'a) {
let ptr = unsafe { self.as_mut().get_unchecked_mut() as *mut _ };
mem::forget(self);
ptr
fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
let mut this = mem::ManuallyDrop::new(self);
unsafe { this.as_mut().get_unchecked_mut() as *mut _ }
}

unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) {
Expand All @@ -264,10 +263,9 @@ mod if_alloc {
}

unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Pin<Box<dyn Future<Output = T> + 'a>> {
fn into_raw(mut self) -> *mut (dyn Future<Output = T> + 'a) {
let ptr = unsafe { self.as_mut().get_unchecked_mut() as *mut _ };
mem::forget(self);
ptr
fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
let mut this = mem::ManuallyDrop::new(self);
unsafe { this.as_mut().get_unchecked_mut() as *mut _ }
}

unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) {
Expand All @@ -276,10 +274,9 @@ mod if_alloc {
}

unsafe impl<'a, T: 'a> UnsafeFutureObj<'a, T> for Pin<Box<dyn Future<Output = T> + Send + 'a>> {
fn into_raw(mut self) -> *mut (dyn Future<Output = T> + 'a) {
let ptr = unsafe { self.as_mut().get_unchecked_mut() as *mut _ };
mem::forget(self);
ptr
fn into_raw(self) -> *mut (dyn Future<Output = T> + 'a) {
let mut this = mem::ManuallyDrop::new(self);
unsafe { this.as_mut().get_unchecked_mut() as *mut _ }
}

unsafe fn drop(ptr: *mut (dyn Future<Output = T> + 'a)) {
Expand Down
10 changes: 5 additions & 5 deletions futures-task/src/waker.rs
Expand Up @@ -20,7 +20,7 @@ pub fn waker<W>(wake: Arc<W>) -> Waker
where
W: ArcWake + 'static,
{
let ptr = Arc::into_raw(wake) as *const ();
let ptr = Arc::into_raw(wake).cast::<()>();

unsafe { Waker::from_raw(RawWaker::new(ptr, waker_vtable::<W>())) }
}
Expand All @@ -31,7 +31,7 @@ where
#[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));
let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(data.cast::<T>()));
// Now increase refcount, but don't drop new refcount either
let _arc_clone: mem::ManuallyDrop<_> = arc.clone();
}
Expand All @@ -43,17 +43,17 @@ unsafe fn clone_arc_raw<T: ArcWake>(data: *const ()) -> RawWaker {
}

unsafe fn wake_arc_raw<T: ArcWake>(data: *const ()) {
let arc: Arc<T> = Arc::from_raw(data as *const T);
let arc: Arc<T> = Arc::from_raw(data.cast::<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));
let arc = mem::ManuallyDrop::new(Arc::<T>::from_raw(data.cast::<T>()));
ArcWake::wake_by_ref(&arc);
}

unsafe fn drop_arc_raw<T: ArcWake>(data: *const ()) {
drop(Arc::<T>::from_raw(data as *const T))
drop(Arc::<T>::from_raw(data.cast::<T>()))
}
2 changes: 1 addition & 1 deletion futures-task/src/waker_ref.rs
Expand Up @@ -55,7 +55,7 @@ where
{
// simply copy the pointer instead of using Arc::into_raw,
// as we don't actually keep a refcount by using ManuallyDrop.<
let ptr = (&**wake as *const W) as *const ();
let ptr = Arc::as_ptr(wake).cast::<()>();

let waker =
ManuallyDrop::new(unsafe { Waker::from_raw(RawWaker::new(ptr, waker_vtable::<W>())) });
Expand Down
4 changes: 2 additions & 2 deletions futures-util/src/stream/futures_unordered/mod.rs
Expand Up @@ -150,7 +150,7 @@ impl<Fut> FuturesUnordered<Fut> {
queued: AtomicBool::new(true),
ready_to_run_queue: Weak::new(),
});
let stub_ptr = &*stub as *const Task<Fut>;
let stub_ptr = Arc::as_ptr(&stub);
let ready_to_run_queue = Arc::new(ReadyToRunQueue {
waker: AtomicWaker::new(),
head: AtomicPtr::new(stub_ptr as *mut _),
Expand Down Expand Up @@ -403,7 +403,7 @@ impl<Fut> FuturesUnordered<Fut> {
// The `ReadyToRunQueue` stub is never inserted into the `head_all`
// list, and its pointer value will remain valid for the lifetime of
// this `FuturesUnordered`, so we can make use of its value here.
&*self.ready_to_run_queue.stub as *const _ as *mut _
Arc::as_ptr(&self.ready_to_run_queue.stub) as *mut _
}
}

Expand Down

0 comments on commit 0e72d61

Please sign in to comment.