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.