Skip to content

Commit

Permalink
Fix FastCWakerState drop code
Browse files Browse the repository at this point in the history
  • Loading branch information
h33p committed Jul 27, 2024
1 parent cc4bb18 commit 74c7c87
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 10 deletions.
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions cglue/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cglue"
version = "0.3.0"
version = "0.3.1"
authors = ["Aurimas Blažulionis <[email protected]>"]
edition = "2018"
description = "FFI safe abstractions for making plugins and C-compatible libraries"
Expand All @@ -25,10 +25,10 @@ _futures = { package = "futures", version = "0.3", optional = true, default-feat
rustc_version = "0.4"

[dev-dependencies]
pollster = "0.1"
pollster = "0.2"

[features]
default = ["std"]
default = ["std", "task"]
std = ["no-std-compat/std", "tarc/std"]
rust_void = ["cglue-macro/rust_void"]
unstable = ["cglue-macro/unstable", "try_default"]
Expand Down
115 changes: 111 additions & 4 deletions cglue/src/task/sound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use core::task::*;
use tarc::BaseArc;

unsafe extern "C" fn clone_adapter(data: *const (), clone: *const ()) -> CRawWaker {
let clone: unsafe fn(*const ()) -> CRawWaker = core::mem::transmute(clone);
clone(data)
let clone: unsafe fn(*const ()) -> RawWaker = core::mem::transmute(clone);
core::mem::transmute(clone(data))
}

unsafe extern "C" fn other_adapter(data: *const (), other: *const ()) {
Expand Down Expand Up @@ -178,7 +178,7 @@ impl<'a> FastCWaker<'a> {
impl<'a> Drop for FastCWakerState<'a> {
fn drop(&mut self) {
if let Self::Owned(s) = self {
unsafe { BaseArc::decrement_strong_count(s) };
unsafe { BaseArc::decrement_strong_count(s.as_ptr()) };
}
}
}
Expand Down Expand Up @@ -243,7 +243,7 @@ impl<'a> FastCWaker<'a> {
};
this.release();

adapter(data, wake as _)
adapter(data, wake as _);
}

let vtbl = &RawWakerVTable::new(clone, unreach, wake_by_ref, noop);
Expand Down Expand Up @@ -293,3 +293,110 @@ impl<'a> FastCWaker<'a> {
ret
}
}

#[cfg(test)]
mod tests {
use super::*;
use pollster::block_on;

// Since unavailable before 1.64
use core::fmt;
use core::pin::*;
use core::future::Future;

pub fn poll_fn<T, F>(f: F) -> PollFn<F>
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
{
PollFn { f }
}

/// A Future that wraps a function returning [`Poll`].
///
/// This `struct` is created by [`poll_fn()`]. See its
/// documentation for more.
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct PollFn<F> {
f: F,
}

impl<F: Unpin> Unpin for PollFn<F> {}

impl<F> fmt::Debug for PollFn<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PollFn").finish()
}
}

impl<T, F> Future for PollFn<F>
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
{
type Output = T;

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
// SAFETY: We are not moving out of the pinned field.
(unsafe { &mut self.get_unchecked_mut().f })(cx)
}
}

#[test]
fn fastcwaker_simple() {
let mut polled = false;
let fut = poll_fn(|cx| {
if !polled {
polled = true;
cx.waker().wake_by_ref();
Poll::Pending
} else {
Poll::Ready(())
}
});
let fut = crate::trait_obj!(fut as Future);
block_on(fut)
}

#[test]
fn fastcwaker_simple_cloned() {
let mut polled = false;
let fut = poll_fn(|cx| {
if !polled {
polled = true;
cx.waker().clone().wake();
Poll::Pending
} else {
Poll::Ready(())
}
});
let fut = crate::trait_obj!(fut as Future);
block_on(fut)
}

#[test]
fn fastcwaker_threaded() {
let (tx, rx) = std::sync::mpsc::channel::<Waker>();

let thread = std::thread::spawn(move || {
for waker in rx.into_iter() {
waker.wake();
}
});

let mut polled = false;
let fut = poll_fn(|cx| {
if !polled {
polled = true;
tx.send(cx.waker().clone()).unwrap();
Poll::Pending
} else {
Poll::Ready(())
}
});
let fut = crate::trait_obj!(fut as Future);
block_on(fut);

core::mem::drop(tx);

thread.join().unwrap();
}
}
3 changes: 3 additions & 0 deletions version-hack/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ proc-macro2 = "=1.0.65"
memchr = "=2.4.1"
log = "=0.4.18"
crossbeam-utils = "=0.8.16"

[dev-dependencies]
pollster = "=0.2.0"

0 comments on commit 74c7c87

Please sign in to comment.