fix: crash on exit when a thread is blocked in a queue being destroyed - #156
Open
HopeSuffers wants to merge 1 commit into
Open
HopeSuffers wants to merge 1 commit into
HopeSuffers wants to merge 1 commit into
Conversation
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.
Quitting the game sometimes segfaults. It's always a null deref in LightweightSemaphore::tryWait(), on whatever thread happened to be waiting on a queue, while the main thread is busy running static destructors.
What's going on is that recomp::start() joins the game thread, the event threads, the thread cleaner and the saving thread on the way out, but two things never get stopped at all:
Those are the two that crash. The other queues survive because their threads are gone by the time exit() gets around to destroying anything. These two are still parked inside theirs.
For the timer thread I drop a stop action in the queue and add a join_timer_thread() next to the other join_* calls. Pretty much the same as the null OSTask that already stops the SP task thread.
The game threads pause_self() is a while (true) with no way out, so I left them alone and made external_messages a leaked function-local static instead. Nothing destroys it any more and they just stay parked until the process goes away.