diff --git a/rts/STM.c b/rts/STM.c index eee0f46bbcdc..8f4bdfbecb05 100644 --- a/rts/STM.c +++ b/rts/STM.c @@ -905,8 +905,12 @@ static StgBool check_read_only(StgTRecHeader *trec STG_UNUSED) { s = e -> tvar; if (entry_is_read_only(e)) { TRACE("%p : check_read_only for TVar %p, saw %ld", trec, s, e -> num_updates); - if (s -> num_updates != e -> num_updates) { - // ||s -> current_value != e -> expected_value) { + + // Note we need both checks and in this order as the TVar could be + // locked by another transaction that is committing but has not yet + // incremented `num_updates` (See #7815). + if (s -> current_value != e -> expected_value || + s -> num_updates != e -> num_updates) { TRACE("%p : mismatch", trec); result = FALSE; BREAK_FOR_EACH;