gen_server: drop-guard drains live timers + debug_assert no leak (RFC 015 §4.7)
This commit is contained in:
@@ -646,3 +646,27 @@ fn traffic_resets_the_idle_window() {
|
||||
assert_eq!(*before_quiet.lock().unwrap(), 0, "steady traffic must suppress idle");
|
||||
assert!(*idles.lock().unwrap() >= 1, "idle fires once the inbox falls quiet");
|
||||
}
|
||||
|
||||
// RFC 015 §4.7 — no armed timer survives loop exit. A server with a live
|
||||
// periodic is dropped; the loop's drop guard drains and cancels it (a surviving
|
||||
// re-arming timer would trip the in-Drop debug_assert), runs terminate, and no
|
||||
// further tick lands after exit.
|
||||
#[test]
|
||||
fn no_timer_survives_exit() {
|
||||
let fired = Arc::new(Mutex::new(Vec::new()));
|
||||
let f_server = fired.clone();
|
||||
let f_read = fired.clone();
|
||||
run(move || {
|
||||
let server = start(timed(f_server, Arc::new(Mutex::new(None))));
|
||||
server.cast(TkCast::Tick(Duration::from_millis(15))).unwrap();
|
||||
let _ = server.call(()).unwrap(); // sync: periodic armed
|
||||
smarm::sleep(Duration::from_millis(45)); // a couple of ticks
|
||||
let mon = smarm::monitor(server.pid());
|
||||
drop(server); // inbox closes → loop exits → guard drains timers
|
||||
// Clean Down ⇒ the loop returned without the no-leak assert aborting.
|
||||
assert!(mon.rx.recv().is_ok());
|
||||
let at_exit = f_read.lock().unwrap().len();
|
||||
smarm::sleep(Duration::from_millis(90)); // would be several more ticks
|
||||
assert_eq!(f_read.lock().unwrap().len(), at_exit, "no tick may fire after exit");
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user