#![cfg(target_os = "linux")]
#![allow(clippy::manual_async_fn)]
use std::future::Future;
use std::time::{Duration, Instant};
use ringline::{AsyncEventHandler, Config, ConfigBuilder, ConnCtx, RinglineBuilder};
struct NoopHandler;
impl AsyncEventHandler for NoopHandler {
fn on_accept(&self, _conn: ConnCtx) -> impl Future<Output = ()> + 'static {
async {}
}
fn create_for_worker(_id: usize) -> Self {
NoopHandler
}
}
fn test_config_builder() -> ConfigBuilder {
ConfigBuilder::new()
.workers(1)
.pin_to_core(false)
.sq_entries(64)
.recv_buffer(16, 1024)
.max_connections(16)
.send_pool(16, 16384)
.max_registered_regions(4)
}
fn test_config() -> Config {
test_config_builder().build().expect("valid config")
}
#[test]
fn drop_handle_triggers_shutdown_and_join_returns() {
let (shutdown, handles) = RinglineBuilder::new(test_config())
.launch::<NoopHandler>()
.expect("launch");
drop(shutdown);
let joiner = std::thread::spawn(move || {
for h in handles {
h.join().expect("worker panicked").expect("worker error");
}
});
let deadline = Instant::now() + Duration::from_secs(5);
while !joiner.is_finished() && Instant::now() < deadline {
std::thread::sleep(Duration::from_millis(20));
}
assert!(
joiner.is_finished(),
"workers did not exit within 5s after ShutdownHandle drop \
— Drop probably no longer signals shutdown",
);
joiner.join().expect("joiner thread panicked");
}
#[test]
fn explicit_shutdown_then_drop_is_idempotent() {
let (shutdown, handles) = RinglineBuilder::new(test_config())
.launch::<NoopHandler>()
.expect("launch");
shutdown.shutdown();
drop(shutdown);
let joiner = std::thread::spawn(move || {
for h in handles {
h.join().expect("worker panicked").expect("worker error");
}
});
let deadline = Instant::now() + Duration::from_secs(5);
while !joiner.is_finished() && Instant::now() < deadline {
std::thread::sleep(Duration::from_millis(20));
}
assert!(
joiner.is_finished(),
"workers did not exit within 5s after explicit shutdown + drop",
);
joiner.join().expect("joiner thread panicked");
}