From b30734a105def55f82520f1ecea6ccd479398ddc Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 1 Nov 2016 13:22:22 +0000 Subject: [PATCH] runtime: fix a race condition with async RPCs. session.rs has code like: while !rpc_queue::empty() { try!(process_kern_queued_rpc(stream, &mut session)) } // A if mailbox::receive() != 0 { try!(process_kern_message(waiter, Some(stream), &mut session)); } If both an async and a mailbox RPC (async or large sync) are posted at point A then they will be processed out of order. This commit fixes the issue by flushing the async RPC queue before posting any RPC to the mailbox. --- artiq/runtime.rs/libksupport/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/artiq/runtime.rs/libksupport/lib.rs b/artiq/runtime.rs/libksupport/lib.rs index dc1c853e4..7e4d66b59 100644 --- a/artiq/runtime.rs/libksupport/lib.rs +++ b/artiq/runtime.rs/libksupport/lib.rs @@ -107,6 +107,7 @@ extern fn send_rpc(service: u32, tag: *const u8, data: *const *const ()) { extern { fn strlen(s: *const c_char) -> size_t; } let tag = unsafe { slice::from_raw_parts(tag, strlen(tag as *const c_char)) }; + while !rpc_queue::empty() {} send(&RpcSend { async: false, service: service, @@ -130,6 +131,7 @@ extern fn send_async_rpc(service: u32, tag: *const u8, data: *const *const ()) { }).unwrap_or_else(|err| { assert!(err.kind() == std::io::ErrorKind::WriteZero); + while !rpc_queue::empty() {} send(&RpcSend { async: true, service: service,