Fix race condition between flushEventLog and start/endEventLogging.

Fixes #27082.

This MR changes flushEventLog to acquire/release the state_change mutex to prevent interleaving with startEventLogging and endEventLogging. This MR renames the old function to flushEventLog_ and defines flushEventLog simply as:

void flushEventLog(Capability **cap USED_IF_THREADS)
{
  ACQUIRE_LOCK(&state_change_mutex);
  flushEventLog_(cap);
  RELEASE_LOCK(&state_change_mutex);
}

The old function is still needed internally within the compilation unit, where it is used in endEventLogging in a context where the state_change mutex has already been acquired. I've chosen to mark flushEventLog_ as static and let other uses of flushEventLog within the RTS refer to the new version. There is one use in hs_init_ghc via flushTrace, where the new locking behaviour should be harmless, and one use in handle_tick, which I believe was likely vulnerable to the same race condition, so the new locking behaviour is desirable.

I have not added a test. The behaviour is highly non-deterministic and requires a program that concurrently calls flushEventLog and startEventLogging/endEventLogging. I encountered the issue while developing eventlog-socket and within that context have verified that my patch likely addresses the issue: a test that used to fail within the first dozen or so runs now has been running on repeat for several hours.

Edited by Wen Kokke

Merge request reports

Loading