Skip to content

Commit

Permalink
Fix tests on Rust 1.81.0
Browse files Browse the repository at this point in the history
Unwinding across functions with the extern "C" ABI is UB, but previously
worked. See: rust-lang/rust#74990

Redo the tests so they don't rely on panics at all, using a
reference-counted counter instead.

Signed-off-by: Hector Martin <[email protected]>
  • Loading branch information
marcan committed Oct 13, 2024
1 parent 44aac00 commit 88ba8d3
Showing 1 changed file with 26 additions and 58 deletions.
84 changes: 26 additions & 58 deletions worker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,29 +480,23 @@ mod tests {
use std::mem;
use std::ops;
use std::ptr;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;

// structure to test drooping issue
struct HasDrop {
drop_count: u32,
drop_limit: u32,
drop_count: Arc<AtomicU32>,
}

impl HasDrop {
fn new(val: u32) -> Self {
Self {
drop_count: 0,
drop_limit: val,
}
fn new(val: Arc<AtomicU32>) -> Self {
Self { drop_count: val }
}
}

impl ops::Drop for HasDrop {
fn drop(&mut self) {
if self.drop_count >= self.drop_limit {
panic!("Dropped more than {} time", self.drop_limit);
} else {
self.drop_count += 1;
}
self.drop_count.fetch_add(1, Ordering::Relaxed);
}
}

Expand Down Expand Up @@ -588,7 +582,8 @@ mod tests {

#[test]
fn schedule_must_not_drop() {
let hd = HasDrop::new(0);
let ctr = Arc::new(AtomicU32::new(0));
let hd = HasDrop::new(ctr.clone());
let internal = lv2_sys::LV2_Worker_Schedule {
handle: ptr::null_mut(),
schedule_work: Some(extern_schedule),
Expand All @@ -598,12 +593,13 @@ mod tests {
phantom: PhantomData::<*const TestDropWorker>,
};
let _ = schedule.schedule_work(hd);
assert_eq!(ctr.load(Ordering::Relaxed), 0);
}

#[test]
#[should_panic(expected = "Dropped")]
fn schedule_must_enable_drop_on_error() {
let hd = HasDrop::new(0);
let ctr = Arc::new(AtomicU32::new(0));
let hd = HasDrop::new(ctr.clone());
let internal = lv2_sys::LV2_Worker_Schedule {
handle: ptr::null_mut(),
schedule_work: Some(faulty_schedule),
Expand All @@ -613,35 +609,39 @@ mod tests {
phantom: PhantomData::<*const TestDropWorker>,
};
let _ = schedule.schedule_work(hd);
assert_eq!(ctr.load(Ordering::Relaxed), 1);
}

#[test]
fn respond_must_not_drop() {
let hd = HasDrop::new(0);
let ctr = Arc::new(AtomicU32::new(0));
let hd = HasDrop::new(ctr.clone());
let respond = ResponseHandler {
response_function: Some(extern_respond),
respond_handle: ptr::null_mut(),
phantom: PhantomData::<TestDropWorker>,
};
let _ = respond.respond(hd);
assert_eq!(ctr.load(Ordering::Relaxed), 0);
}

#[test]
#[should_panic(expected = "Dropped")]
fn respond_must_enable_drop_on_error() {
let hd = HasDrop::new(0);
let ctr = Arc::new(AtomicU32::new(0));
let hd = HasDrop::new(ctr.clone());
let respond = ResponseHandler {
response_function: Some(faulty_respond),
respond_handle: ptr::null_mut(),
phantom: PhantomData::<TestDropWorker>,
};
let _ = respond.respond(hd);
assert_eq!(ctr.load(Ordering::Relaxed), 1);
}

#[test]
#[should_panic(expected = "Dropped")]
fn extern_work_should_drop() {
let hd = mem::ManuallyDrop::new(HasDrop::new(0));
fn extern_work_should_drop_once() {
let ctr = Arc::new(AtomicU32::new(0));
let hd = mem::ManuallyDrop::new(HasDrop::new(ctr.clone()));
let ptr_hd = &hd as *const _ as *const c_void;
let size = mem::size_of_val(&hd) as u32;
let mut tdw = TestDropWorker {};
Expand All @@ -657,46 +657,13 @@ mod tests {
ptr_hd,
);
}
assert_eq!(ctr.load(Ordering::Relaxed), 1);
}

#[test]
fn extern_work_should_not_drop_twice() {
let hd = mem::ManuallyDrop::new(HasDrop::new(1));
let ptr_hd = &hd as *const _ as *const c_void;
let size = mem::size_of_val(&hd) as u32;
let mut tdw = TestDropWorker {};

let ptr_tdw = &mut tdw as *mut _ as *mut c_void;
//trash trick i use Plugin ptr insteas of Pluginstance ptr
unsafe {
WorkerDescriptor::<TestDropWorker>::extern_work(
ptr_tdw,
Some(extern_respond),
ptr::null_mut(),
size,
ptr_hd,
);
}
}

#[test]
#[should_panic(expected = "Dropped")]
fn extern_work_response_should_drop() {
let hd = mem::ManuallyDrop::new(HasDrop::new(0));
let ptr_hd = &hd as *const _ as *const c_void;
let size = mem::size_of_val(&hd) as u32;
let mut tdw = TestDropWorker {};

let ptr_tdw = &mut tdw as *mut _ as *mut c_void;
//trash trick i use Plugin ptr insteas of Pluginstance ptr
unsafe {
WorkerDescriptor::<TestDropWorker>::extern_work_response(ptr_tdw, size, ptr_hd);
}
}

#[test]
fn extern_work_response_should_not_drop_twice() {
let hd = mem::ManuallyDrop::new(HasDrop::new(1));
fn extern_work_response_should_drop_once() {
let ctr = Arc::new(AtomicU32::new(0));
let hd = mem::ManuallyDrop::new(HasDrop::new(ctr.clone()));
let ptr_hd = &hd as *const _ as *const c_void;
let size = mem::size_of_val(&hd) as u32;
let mut tdw = TestDropWorker {};
Expand All @@ -706,5 +673,6 @@ mod tests {
unsafe {
WorkerDescriptor::<TestDropWorker>::extern_work_response(ptr_tdw, size, ptr_hd);
}
assert_eq!(ctr.load(Ordering::Relaxed), 1);
}
}

0 comments on commit 88ba8d3

Please sign in to comment.