Quelle sync.rs
Sprache: Rust
use core::mem;
use oneshot::TryRecvError;
#[ cfg(feature = "std" )]
use oneshot::{RecvError, RecvTimeoutError};
#[ cfg(feature = "std" )]
use std::time::{Duration, Instant};
#[ cfg(feature = "std" )]
mod thread {
#[ cfg(oneshot_loom)]
pub use loom::thread::spawn;
#[ cfg(not(oneshot_loom))]
pub use std::thread::{sleep, spawn};
#[ cfg(oneshot_loom)]
pub fn sleep(_timeout: core::time::Duration) {
loom::thread::yield_now()
}
}
mod helpers;
use helpers::{maybe_loom_model, DropCounter};
#[ test]
fn send_before_try_recv() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel();
assert!(!receiver.has_message());
assert!(sender.send(19 i128).is_ok());
assert!(receiver.has_message());
assert_eq!(receiver.try_recv(), Ok(19 i128));
assert!(!receiver.has_message());
assert_eq!(receiver.try_recv(), Err(TryRecvError::Disconnected));
#[ cfg(feature = "std" )]
{
assert_eq!(receiver.recv_ref(), Err(RecvError));
assert!(receiver.recv_timeout(Duration::from_secs(1 )).is_err());
}
})
}
#[ cfg(feature = "std" )]
#[ test]
fn send_before_recv() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<()>();
assert!(sender.send(()).is_ok());
assert_eq!(receiver.recv(), Ok(()));
});
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<u8>();
assert!(sender.send(19 ).is_ok());
assert_eq!(receiver.recv(), Ok(19 ));
});
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<u64>();
assert!(sender.send(21 ).is_ok());
assert_eq!(receiver.recv(), Ok(21 ));
});
// FIXME: This test does not work with loom. There is something that happens after the
// channel object becomes larger than ~500 bytes and that makes an atomic read from the state
// result in "signal: 10, SIGBUS: access to undefined memory"
#[ cfg(not(oneshot_loom))]
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<[u8; 4096 ]>();
assert!(sender.send([0 b10101010; 4096 ]).is_ok());
assert!(receiver.recv().unwrap()[..] == [0 b10101010; 4096 ][..]);
});
}
#[ cfg(feature = "std" )]
#[ test]
fn send_before_recv_ref() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel();
assert!(sender.send(19 i128).is_ok());
assert_eq!(receiver.recv_ref(), Ok(19 i128));
assert_eq!(receiver.recv_ref(), Err(RecvError));
assert_eq!(receiver.try_recv(), Err(TryRecvError::Disconnected));
assert!(receiver.recv_timeout(Duration::from_secs(1 )).is_err());
})
}
#[ cfg(feature = "std" )]
#[ test]
fn send_before_recv_timeout() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel();
assert!(sender.send(19 i128).is_ok());
let start = Instant::now();
let timeout = Duration::from_secs(1 );
assert_eq!(receiver.recv_timeout(timeout), Ok(19 i128));
assert!(start.elapsed() < Duration::from_millis(100 ));
assert!(receiver.recv_timeout(timeout).is_err());
assert!(receiver.try_recv().is_err());
assert!(receiver.recv().is_err());
})
}
#[ test]
fn send_then_drop_receiver() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel();
assert!(sender.send(19 i128).is_ok());
mem::drop(receiver);
})
}
#[ test]
fn send_with_dropped_receiver() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel();
mem::drop(receiver);
let send_error = sender.send(5 u128).unwrap_err();
assert_eq!(*send_error.as_inner(), 5 );
assert_eq!(send_error.into_inner(), 5 );
})
}
#[ test]
fn try_recv_with_dropped_sender() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<u128>();
mem::drop(sender);
assert!(!receiver.has_message());
receiver.try_recv().unwrap_err();
})
}
#[ cfg(feature = "std" )]
#[ test]
fn recv_with_dropped_sender() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<u128>();
mem::drop(sender);
receiver.recv().unwrap_err();
})
}
#[ cfg(feature = "std" )]
#[ test]
fn recv_before_send() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel();
let t = thread::spawn(move || {
thread::sleep(Duration::from_millis(2 ));
sender.send(9 u128).unwrap();
});
assert_eq!(receiver.recv(), Ok(9 ));
t.join().unwrap();
})
}
#[ cfg(feature = "std" )]
#[ test]
fn recv_timeout_before_send() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel();
let t = thread::spawn(move || {
thread::sleep(Duration::from_millis(2 ));
sender.send(9 u128).unwrap();
});
assert_eq!(receiver.recv_timeout(Duration::from_secs(1 )), Ok(9 ));
t.join().unwrap();
})
}
#[ cfg(feature = "std" )]
#[ test]
fn recv_before_send_then_drop_sender() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<u128>();
let t = thread::spawn(move || {
thread::sleep(Duration::from_millis(10 ));
mem::drop(sender);
});
assert!(receiver.recv().is_err());
t.join().unwrap();
})
}
#[ cfg(feature = "std" )]
#[ test]
fn recv_timeout_before_send_then_drop_sender() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<u128>();
let t = thread::spawn(move || {
thread::sleep(Duration::from_millis(10 ));
mem::drop(sender);
});
assert!(receiver.recv_timeout(Duration::from_secs(1 )).is_err());
t.join().unwrap();
})
}
#[ test]
fn try_recv() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<u128>();
assert_eq!(receiver.try_recv(), Err(TryRecvError::Empty));
mem::drop(sender)
})
}
#[ cfg(feature = "std" )]
#[ test]
fn try_recv_then_drop_receiver() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<u128>();
let t1 = thread::spawn(move || {
let _ = sender.send(42 );
});
let t2 = thread::spawn(move || {
assert!(matches!(
receiver.try_recv(),
Ok(42 ) | Err(TryRecvError::Empty)
));
mem::drop(receiver);
});
t1.join().unwrap();
t2.join().unwrap();
})
}
#[ cfg(feature = "std" )]
#[ test]
fn recv_deadline_and_timeout_no_time() {
maybe_loom_model(|| {
let (_sender, receiver) = oneshot::channel::<u128>();
let start = Instant::now();
assert_eq!(
receiver.recv_deadline(start),
Err(RecvTimeoutError::Timeout)
);
assert!(start.elapsed() < Duration::from_millis(200 ));
let start = Instant::now();
assert_eq!(
receiver.recv_timeout(Duration::from_millis(0 )),
Err(RecvTimeoutError::Timeout)
);
assert!(start.elapsed() < Duration::from_millis(200 ));
})
}
// This test doesn't give meaningful results when run with oneshot_test_delay and loom
#[ cfg(all(feature = "std" , not(all(oneshot_test_delay, oneshot_loom))))]
#[ test]
fn recv_deadline_time_should_elapse() {
maybe_loom_model(|| {
let (_sender, receiver) = oneshot::channel::<u128>();
let start = Instant::now();
#[ cfg(not(oneshot_loom))]
let timeout = Duration::from_millis(100 );
#[ cfg(oneshot_loom)]
let timeout = Duration::from_millis(1 );
assert_eq!(
receiver.recv_deadline(start + timeout),
Err(RecvTimeoutError::Timeout)
);
assert!(start.elapsed() > timeout);
assert!(start.elapsed() < timeout * 3 );
})
}
#[ cfg(all(feature = "std" , not(all(oneshot_test_delay, oneshot_loom))))]
#[ test]
fn recv_timeout_time_should_elapse() {
maybe_loom_model(|| {
let (_sender, receiver) = oneshot::channel::<u128>();
let start = Instant::now();
#[ cfg(not(oneshot_loom))]
let timeout = Duration::from_millis(100 );
#[ cfg(oneshot_loom)]
let timeout = Duration::from_millis(1 );
assert_eq!(
receiver.recv_timeout(timeout),
Err(RecvTimeoutError::Timeout)
);
assert!(start.elapsed() > timeout);
assert!(start.elapsed() < timeout * 3 );
})
}
#[ cfg(not(oneshot_loom))]
#[ test]
fn non_send_type_can_be_used_on_same_thread() {
use std::ptr;
#[ derive(Debug, Eq, PartialEq)]
struct NotSend(*mut ());
let (sender, receiver) = oneshot::channel();
sender.send(NotSend(ptr::null_mut())).unwrap();
let reply = receiver.try_recv().unwrap();
assert_eq!(reply, NotSend(ptr::null_mut()));
}
#[ test]
fn message_in_channel_dropped_on_receiver_drop() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel();
let (message, counter) = DropCounter::new(());
assert_eq!(counter.count(), 0 );
sender.send(message).unwrap();
assert_eq!(counter.count(), 0 );
mem::drop(receiver);
assert_eq!(counter.count(), 1 );
})
}
#[ test]
fn send_error_drops_message_correctly() {
maybe_loom_model(|| {
let (sender, _) = oneshot::channel();
let (message, counter) = DropCounter::new(());
let send_error = sender.send(message).unwrap_err();
assert_eq!(counter.count(), 0 );
mem::drop(send_error);
assert_eq!(counter.count(), 1 );
});
}
#[ test]
fn send_error_drops_message_correctly_on_into_inner() {
maybe_loom_model(|| {
let (sender, _) = oneshot::channel();
let (message, counter) = DropCounter::new(());
let send_error = sender.send(message).unwrap_err();
assert_eq!(counter.count(), 0 );
let message = send_error.into_inner();
assert_eq!(counter.count(), 0 );
mem::drop(message);
assert_eq!(counter.count(), 1 );
});
}
#[ test]
fn dropping_receiver_disconnects_sender() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<()>();
assert!(!sender.is_closed());
assert!(!receiver.is_closed());
drop(receiver);
assert!(sender.is_closed());
});
}
#[ test]
fn dropping_sender_disconnects_receiver() {
maybe_loom_model(|| {
let (sender, receiver) = oneshot::channel::<()>();
assert!(!sender.is_closed());
assert!(!receiver.is_closed());
drop(sender);
assert!(receiver.is_closed());
});
}
Messung V0.5 in Prozent C=87 H=91 G=88
¤ Dauer der Verarbeitung: 0.6 Sekunden
¤
*© Formatika GbR, Deutschland
2026-08-25
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=277311
#Domains=752002