Make UserThread::run* methods thread safe #4122
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.
The
UserThread::run*
methods delegate toUITimer::run(Later|Periodically)
in the case of the desktop application. These use the JavaFXTimeLine
API (viabisq.common.reactfx.FXTimer
) to schedule future events. However, this API isn't thread safe and isn't meant to be called outside the FX application thread. This causes occasional task misfires and out-of-order scheduling whenUserThread::runAfter
is called outside the user thread.Make the
UITimer::run*
methods safe to call from any thread by checking we are in the application thread and delegating toUserThread::execute
otherwise. This also improves consistency between the contracts of therun*
andexecute
methods. As the former has many call sites, this is safer than trying to track down all the non-thread-safe uses.(The
Timer
used in the headless app already appears to be thread-safe.)This fixes #4055, caused by out-of-order scheduling of the
execute
andrunAfter
tasks in theWalletConfig.onSetupCompleted
anonymous class method inbisq.core.btc.setup.WalletsSetup.initialize
.Also prevent an exception caused by non-thread-safe calls into JavaFX during the shutdown of
OpenOfferManager
, which was uncovered by the above, by adding a missingUserThread::execute
call.