Skip to content

Commit

Permalink
Merge pull request #4122 from stejbac/make-UserThread-runAfter-thread…
Browse files Browse the repository at this point in the history
…-safe

Make UserThread::run* methods thread safe
  • Loading branch information
ripcurlx authored Apr 10, 2020
2 parents 062dc6e + a71f1e7 commit 34734c6
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 19 deletions.
9 changes: 5 additions & 4 deletions core/src/main/java/bisq/core/offer/OpenOfferManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,8 @@ public OpenOfferManager(CreateOfferService createOfferService,
openOfferTradableListStorage = storage;

// In case the app did get killed the shutDown from the modules is not called, so we use a shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
UserThread.execute(OpenOfferManager.this::shutDown);
}, "OpenOfferManager.ShutDownHook"));
Runtime.getRuntime().addShutdownHook(new Thread(() ->
UserThread.execute(OpenOfferManager.this::shutDown), "OpenOfferManager.ShutDownHook"));
}

@Override
Expand Down Expand Up @@ -221,7 +220,9 @@ public void shutDown(@Nullable Runnable completeHandler) {
int size = openOffers != null ? openOffers.size() : 0;
log.info("Remove open offers at shutDown. Number of open offers: {}", size);
if (offerBookService.isBootstrapped() && size > 0) {
openOffers.forEach(openOffer -> offerBookService.removeOfferAtShutDown(openOffer.getOffer().getOfferPayload()));
UserThread.execute(() -> openOffers.forEach(
openOffer -> offerBookService.removeOfferAtShutDown(openOffer.getOffer().getOfferPayload())
));
if (completeHandler != null)
UserThread.runAfter(completeHandler, size * 200 + 500, TimeUnit.MILLISECONDS);
} else {
Expand Down
47 changes: 32 additions & 15 deletions desktop/src/main/java/bisq/desktop/common/UITimer.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
package bisq.desktop.common;

import bisq.common.Timer;
import bisq.common.UserThread;
import bisq.common.reactfx.FxTimer;

import javafx.application.Platform;

import java.time.Duration;

import org.slf4j.Logger;
Expand All @@ -34,31 +37,45 @@ public UITimer() {

@Override
public Timer runLater(Duration delay, Runnable runnable) {
if (timer == null) {
timer = FxTimer.create(delay, runnable);
timer.restart();
} else {
log.warn("runLater called on an already running timer.");
}
executeDirectlyIfPossible(() -> {
if (timer == null) {
timer = FxTimer.create(delay, runnable);
timer.restart();
} else {
log.warn("runLater called on an already running timer.");
}
});
return this;
}

@Override
public Timer runPeriodically(Duration interval, Runnable runnable) {
if (timer == null) {
timer = FxTimer.createPeriodic(interval, runnable);
timer.restart();
} else {
log.warn("runPeriodically called on an already running timer.");
}
executeDirectlyIfPossible(() -> {
if (timer == null) {
timer = FxTimer.createPeriodic(interval, runnable);
timer.restart();
} else {
log.warn("runPeriodically called on an already running timer.");
}
});
return this;
}

@Override
public void stop() {
if (timer != null) {
timer.stop();
timer = null;
executeDirectlyIfPossible(() -> {
if (timer != null) {
timer.stop();
timer = null;
}
});
}

private void executeDirectlyIfPossible(Runnable runnable) {
if (Platform.isFxApplicationThread()) {
runnable.run();
} else {
UserThread.execute(runnable);
}
}
}

0 comments on commit 34734c6

Please sign in to comment.