forked from M-Labs/artiq
1
0
Fork 0

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.
This commit is contained in:
whitequark 2016-11-01 13:22:22 +00:00
parent 6fcd57a41a
commit b30734a105
1 changed files with 2 additions and 0 deletions

View File

@ -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; } extern { fn strlen(s: *const c_char) -> size_t; }
let tag = unsafe { slice::from_raw_parts(tag, strlen(tag as *const c_char)) }; let tag = unsafe { slice::from_raw_parts(tag, strlen(tag as *const c_char)) };
while !rpc_queue::empty() {}
send(&RpcSend { send(&RpcSend {
async: false, async: false,
service: service, service: service,
@ -130,6 +131,7 @@ extern fn send_async_rpc(service: u32, tag: *const u8, data: *const *const ()) {
}).unwrap_or_else(|err| { }).unwrap_or_else(|err| {
assert!(err.kind() == std::io::ErrorKind::WriteZero); assert!(err.kind() == std::io::ErrorKind::WriteZero);
while !rpc_queue::empty() {}
send(&RpcSend { send(&RpcSend {
async: true, async: true,
service: service, service: service,