Skip to content

Commit cd2ee06

Browse files
committed
Address review: improve test with safe ownership transfer and clarify None context case
1 parent aff92eb commit cd2ee06

File tree

2 files changed

+22
-25
lines changed

2 files changed

+22
-25
lines changed

src/rs/lib.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,9 @@ extern "C" fn raw_conn_callback(
867867
event: *mut ffi::QUIC_CONNECTION_EVENT,
868868
) -> QUIC_STATUS {
869869
let event_ref = unsafe { event.as_ref().expect("cannot get connection event") };
870-
let status = match unsafe { (context as *mut Box<ConnectionCallback>).as_mut() } {
870+
// Context may be null if ConnectionClose triggers ShutdownComplete synchronously
871+
// after we've already taken the context in close_inner(). This is expected.
872+
match unsafe { (context as *mut Box<ConnectionCallback>).as_mut() } {
871873
Some(f) => {
872874
let event = ConnectionEvent::from(event_ref);
873875
let conn = unsafe { ConnectionRef::from_raw(connection) };
@@ -876,11 +878,8 @@ extern "C" fn raw_conn_callback(
876878
Err(e) => e.0,
877879
}
878880
}
879-
// Context already cleaned (e.g. after ShutdownComplete). Nothing to do.
880881
None => StatusCode::QUIC_STATUS_SUCCESS.into(),
881-
};
882-
883-
status
882+
}
884883
}
885884

886885
impl Connection {

src/rs/server_client_test.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -323,32 +323,28 @@ fn connection_ref_callback_cleanup() {
323323
let server_config = Arc::new(server_config);
324324

325325
let drop_counter = Arc::new(AtomicUsize::new(0));
326-
let (server_handle_tx, server_handle_rx) = mpsc::channel::<crate::ffi::HQUIC>();
327326

327+
let (conn_tx, conn_rx) = mpsc::channel::<Connection>();
328328
let listener = Listener::open(&reg, {
329329
let server_config = server_config.clone();
330330
let drop_counter = drop_counter.clone();
331-
let server_handle_tx = server_handle_tx.clone();
331+
let conn_tx = conn_tx.clone();
332332
move |_, ev| {
333333
if let crate::ListenerEvent::NewConnection { connection, .. } = ev {
334334
let callback_guard = DropGuard {
335335
counter: drop_counter.clone(),
336336
};
337-
let server_handle_tx = server_handle_tx.clone();
338-
connection.set_callback_handler(move |conn: ConnectionRef, ev: ConnectionEvent| {
339-
let _guard_ref = &callback_guard;
340-
match ev {
341-
ConnectionEvent::Connected { .. } => {}
342-
ConnectionEvent::ShutdownComplete { .. } => {
343-
let _ = server_handle_tx.send(unsafe { conn.as_raw() });
344-
}
345-
_ => {}
346-
};
347-
Ok(())
348-
});
337+
let conn_tx = conn_tx.clone();
338+
connection.set_callback_handler(
339+
move |_conn: ConnectionRef, _ev: ConnectionEvent| {
340+
// Reference the guard so it lives as long as the callback.
341+
let _guard_ref = &callback_guard;
342+
Ok(())
343+
},
344+
);
349345
connection.set_configuration(&server_config)?;
350-
// Keep connection alive until ShutdownComplete closes it.
351-
let _ = unsafe { connection.into_raw() };
346+
// Transfer ownership to the test so it can close the connection.
347+
let _ = conn_tx.send(connection);
352348
}
353349
Ok(())
354350
}
@@ -392,15 +388,17 @@ fn connection_ref_callback_cleanup() {
392388
.start(&client_config, "127.0.0.1", port)
393389
.unwrap();
394390

395-
let raw_conn = server_handle_rx
391+
// Receive the owned connection from the listener callback.
392+
let server_conn = conn_rx
396393
.recv_timeout(Duration::from_secs(5))
397-
.expect("Server did not receive shutdown event");
398-
// Close now to drop the server-side callback context.
399-
unsafe { Connection::from_raw(raw_conn) };
394+
.expect("Server did not receive connection");
400395
client_done_rx
401396
.recv_timeout(Duration::from_secs(5))
402397
.expect("Client did not complete shutdown");
403398

399+
// Drop the server connection to trigger cleanup of the callback context.
400+
drop(server_conn);
401+
404402
let mut retries = 50;
405403
while drop_counter.load(Ordering::SeqCst) == 0 && retries > 0 {
406404
std::thread::sleep(Duration::from_millis(10));

0 commit comments

Comments
 (0)