Added exception detection to ThreadFinish() #2205
Merged
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.
This sort of fixes one half of issue #2203.
Issue #2203 had two halves to it:
part 1 - When the problem happened, the exception got re-thrown
in a loop forever, never relinquishing control. Regardless
of the cause of the exception, throwing an exception shouldn't
cause kOS to get stuck in a loop like that. Something is wrong
with the error handling system.
part 2 - The problem that threw the exception shouldn't have
happened in the first place.
This PR fixes just part 1. Part 2 is in a separate PR. That is
deliberate because you cannot test the exception message
handling if the bug that caused the exception is fixed. That bug
needs to still be present to prove that the error message system
is handling it better.
The cause of the exception looping:
Compiling happens in a thread, using the YieldFinishedDetector system.
When the CPU wakes up each tick to see if a YieldFinishDetector thread
is done, it calls IsFinished() to do so. If IsFinished() notices that
ThreadExecute()
is done, then it callsThreadFinish()
to do any cleanup theclass wants to do, and after that sets some flags that tells it the
thread is done and IsFinished() no longer has to be called.
Compiling consists of 2 steps, Compile and BuildProgram, and only
Compile was put under the
ThreadExecute()
control. The BuildProgramstep was being done inside
ThreadFinish()
.The problem is that if ThreadFinish() aborts with an exception, then IsFinished
aborts, never reaching the code that sets flags telling the CPU the thread is done.
So on the next tick, the CPU tries calling IsFinished() again, which notices
that ThreadExecute() is done (still) so it tries calling ThreadFinish(), and
triggers the whole thing again.
The fix: there are two possible fixes, and I chose the one that didn't
involve touching code I didn't write.
possible fix 1 - move the BuildProgram step inside the
ThreadExecute()
.This is more in keeping with the design intent of ThreadExecute(), but would
have involved touching code I don't want to touch.
possible fix 2 - Give
ThreadFinish()
the same exception checking thatThreadExecute()
has so an exception in ThreadFinished() won't prevent thesystem from noticing that the thread indeed has finished.
I chose fix 2.