Correct FIFA17 SBC dispatch notifier lifecycle guard to post-exit invariant
This commit is contained in:
@@ -180,9 +180,15 @@ fn decide(input: DecisionInput) -> Result<Decision, Rejection> {
|
|||||||
if input.live_category_count != input.category_count {
|
if input.live_category_count != input.category_count {
|
||||||
return Err(Rejection::ModelChanged);
|
return Err(Rejection::ModelChanged);
|
||||||
}
|
}
|
||||||
|
// The category-success notifier for this generation must have entered and
|
||||||
|
// fully returned before the SBC completion runs. On the pinned CardsDLL the
|
||||||
|
// completion fires immediately after the notifier unwinds (measured: notifier
|
||||||
|
// entries == exits == generation at completion), not nested inside it, so we
|
||||||
|
// bind both notifier counts to the current generation rather than requiring
|
||||||
|
// an in-flight notifier.
|
||||||
if input.notifier_entries != generation
|
if input.notifier_entries != generation
|
||||||
|| input.notifier_entries == 0
|
|| input.notifier_entries == 0
|
||||||
|| input.notifier_exits.checked_add(1) != Some(input.notifier_entries)
|
|| input.notifier_exits != generation
|
||||||
{
|
{
|
||||||
return Err(Rejection::NotifierNotCurrent);
|
return Err(Rejection::NotifierNotCurrent);
|
||||||
}
|
}
|
||||||
@@ -730,7 +736,7 @@ mod tests {
|
|||||||
live_category_count: 2,
|
live_category_count: 2,
|
||||||
category_count: 2,
|
category_count: 2,
|
||||||
notifier_entries: generation,
|
notifier_entries: generation,
|
||||||
notifier_exits: generation - 1,
|
notifier_exits: generation,
|
||||||
controller_matches: true,
|
controller_matches: true,
|
||||||
controller_model_matches: true,
|
controller_model_matches: true,
|
||||||
last_repaired_generation: generation - 1,
|
last_repaired_generation: generation - 1,
|
||||||
@@ -776,8 +782,16 @@ mod tests {
|
|||||||
input.status = None;
|
input.status = None;
|
||||||
assert_eq!(decide(input), Err(Rejection::StatusUnreadable));
|
assert_eq!(decide(input), Err(Rejection::StatusUnreadable));
|
||||||
|
|
||||||
|
// Notifier still in flight for this generation (has not returned) is rejected:
|
||||||
|
// on the pinned build the completion only runs after the notifier unwinds.
|
||||||
let mut input = valid_input(1);
|
let mut input = valid_input(1);
|
||||||
input.notifier_exits = 1;
|
input.notifier_exits = 0;
|
||||||
|
assert_eq!(decide(input), Err(Rejection::NotifierNotCurrent));
|
||||||
|
|
||||||
|
// A notifier count that does not match the current generation is rejected.
|
||||||
|
let mut input = valid_input(1);
|
||||||
|
input.notifier_entries = 2;
|
||||||
|
input.notifier_exits = 2;
|
||||||
assert_eq!(decide(input), Err(Rejection::NotifierNotCurrent));
|
assert_eq!(decide(input), Err(Rejection::NotifierNotCurrent));
|
||||||
|
|
||||||
let mut input = valid_input(1);
|
let mut input = valid_input(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user