Hi guys,
I’ve found that FMultiReaderSingleWriterGT has at least 2 bugs:
The one that caused a deadlock in our game and caused me to investigate was this:
- Worker Thread Acquires Read lock
- Game Thread Acquires Read lock (Steps 1 and 2 can happen in either order)
- Worker Thread Releases Read lock
- Game Thread Releases Read lock
- Game Thread attempts to acquire Write lock (Deadlocks here)
This is deadlocked because ReadCounter is 0, but Action is left set as ReadingAction when the game thread releases the lock. Removing the IsInGameThread() guards in LockRead() and UnlockRead() would fix this.
I also noticed there is also a more standard problem that occurs with these kinds of lock, that the control data isn’t guarded, so you can get two threads modifying the lock in this pattern:
- Thread 1 - In LockRead Sets action to ReadingAction and Increments ReadCounter to 1
- Thread 2 - In Lock Read Sets ReadingAction,
- Thread 1 - In UnlockRead Decrements ReadCounter to 0 and sets action to NoAction
- Thread 2 - Increments ReadCounter to 1
Result: Thread 2 is reading, but lock is set to NoAction.
We’re on UE4.10, but a quick look seems to indicate neither of these have been fixed in the latest version of the engine…
As this is only used in ModuleManager, we’re opting to make ModuleManager use a FCriticalSection for now instead, but having a Multi-Reader, Single Writer lock would be useful in other scenarios.
Thanks.