stop() does a synchronization point by stopping the activity, but
then starts it right away. Given that the EE was not checking against
mTargetState when deciding to call errorHook(), there was a chance
that errorHook was called during or after stopHook.
Moreover, while error() was checking that mTargetState was a runtime
state, recover() was not, which could lead to a call to recover()
overriding mTargetState during the stop, leaving the task stopped
but in an inconsistent state.
The tests loop because of the racy nature of the problem. On my machine,
with the timing setup and 100 tries, I was getting more than 50% hits.
stop() does a synchronization point by stopping the activity, but then starts it right away. Given that the EE was not checking against mTargetState when deciding to call errorHook(), there was a chance that errorHook was called during or after stopHook.
Moreover, while error() was checking that mTargetState was a runtime state, recover() was not, which could lead to a call to recover() overriding mTargetState during the stop, leaving the task stopped but in an inconsistent state.
The tests loop because of the racy nature of the problem. On my machine, with the timing setup and 100 tries, I was getting more than 50% hits.