From: Ian Jackson Date: Wed, 31 Mar 2021 18:46:20 +0000 (+0100) Subject: cmd updates: Restart updates when insert follows delete (properly) X-Git-Tag: otter-0.5.0~343 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=a366aefeb9453e60c0ccd8bbfcf6a3c22e17dc65;p=otter.git cmd updates: Restart updates when insert follows delete (properly) We do this prospectively, when we see AddPieces but before it has been processed. This means execute_for_game has special knowledge of particular commands - oh well. Signed-off-by: Ian Jackson --- diff --git a/daemon/cmdlistener.rs b/daemon/cmdlistener.rs index 48b45944..54d9300a 100644 --- a/daemon/cmdlistener.rs +++ b/daemon/cmdlistener.rs @@ -849,8 +849,9 @@ fn execute_for_game<'cs, 'igr, 'ig: 'igr>( struct St { uh: UpdateHandler, auth: Authorisation, + have_deleted: bool, } - let mut uh_auth = None; + let mut uh_auth: Option = None; let mk_uh = || UpdateHandler::from_how(how); let who = if_chain! { let account = &cs.current_account()?.notional_account; @@ -869,14 +870,29 @@ fn execute_for_game<'cs, 'igr, 'ig: 'igr>( let res = (||{ for insn in insns.drain(0..) { trace_dbg!("exeucting game insns", insn); + + if let (MGI::AddPieces{..}, + &mut Some(St { ref mut uh, auth, have_deleted: true })) + = (&insn, &mut uh_auth) + { + // This makes sure that all the updates we have queued up + // talking about the old PieceId, will be Prepared (ie, the + // vpid lookup done) before we reuse the slot and render the + // vpid lookup impossible. + let ig = igu.by_mut(auth); + mem::replace(uh, mk_uh()).complete(ig, &who)?; + }; + let was_delete = matches!(&insn, MGI::DeletePiece(..)); + let (updates, resp, unprepared, ig) = execute_game_insn(cs, ag, igu, insn, &who, &mut to_permute)?; let st = uh_auth.get_or_insert_with(||{ let auth = Authorisation::authorised(&*ig.name); let uh = mk_uh(); - St { uh, auth } + St { uh, auth, have_deleted: false } }); + st.have_deleted |= was_delete; st.uh.accumulate(ig, updates)?; responses.push(resp); if let Some(unprepared) = unprepared {