Queue Lua MESSAGEMAN:Broadcast to be ran on main thread#2
Open
quvide wants to merge 1 commit intoAlhetus:mckyla-1.0.0from
Open
Queue Lua MESSAGEMAN:Broadcast to be ran on main thread#2quvide wants to merge 1 commit intoAlhetus:mckyla-1.0.0from
quvide wants to merge 1 commit intoAlhetus:mckyla-1.0.0from
Conversation
Works around a potential deadlock: T1 = Thread 1 (main thread) T2 = Thread 2 (background thread) M = MessageManager mutex L = Lua mutex 1. MessageManager::Broadcast is looping subscribers on T1, while keeping M locked. Subscribers might lock L. 2. A network request completes on T2, obtains lock on L before M is released. Lua code wants to run MessageManager::Broadcast, which waits for M to be released. We are now in a deadlock as T1 is waiting for L while holding M and T2 is waiting for M while holding L. This commit changes the Lua API to never run MessageManager::Broadcast from a non-main thread. Instead, a Message is allocated and stored in a queue, which the main thread checks in the main GameLoop. Access to the queue is guarded with a separate mutex. No other mutexes are obtained while this new mutex is locked. With this change, it should no longer be possible for M to be waited on while L is locked from a non-main thread and when attempting to broadcast. (Potentially, it could be possible for MessageManager::Broadcast to lock M and L on the main thread and run Lua which attempts to Broadcast again, that would try to obtain M which is already locked... I did not investigate whether there are some safeguards preventing this.)
3f2c8c2 to
f2a51bb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Works around a potential deadlock:
T1 = Thread 1 (main thread)
T2 = Thread 2 (background thread)
M = MessageManager mutex
L = Lua mutex
We are now in a deadlock as T1 is waiting for L while holding M and T2 is waiting for M while holding L.
This commit changes the Lua API to never run MessageManager::Broadcast from a non-main thread. Instead, a Message is allocated and stored in a queue, which the main thread checks in the main GameLoop.
Access to the queue is guarded with a separate mutex. No other mutexes are obtained while this new mutex is locked.
With this change, it should no longer be possible for M to be waited on while L is locked from a non-main thread and when attempting to broadcast.
(Potentially, it could be possible for MessageManager::Broadcast to lock M and L on the main thread and run Lua which attempts to Broadcast again, that would try to obtain M which is already locked... I did not investigate whether there are some safeguards preventing this.)