99import edu .wpi .grip .core .Palette ;
1010import edu .wpi .grip .core .events .UnexpectedThrowableEvent ;
1111import edu .wpi .grip .core .operations .Operations ;
12+ import edu .wpi .grip .core .util .SafeShutdown ;
1213import edu .wpi .grip .generated .CVOperations ;
1314import edu .wpi .grip .ui .util .DPIUtility ;
1415import javafx .application .Application ;
@@ -32,9 +33,6 @@ public class Main extends Application {
3233 @ Inject
3334 private Logger logger ;
3435
35- private volatile boolean stopping = false ;
36-
37-
3836 protected final Injector injector = Guice .createInjector (new GRIPCoreModule (), new GRIPUIModule ());
3937
4038 private final Object dialogLock = new Object ();
@@ -62,8 +60,9 @@ public void start(Stage stage) throws Exception {
6260 CVOperations .addOperations (eventBus );
6361
6462 stage .setOnCloseRequest ((event ) -> {
65- Platform .exit ();
66- System .exit (0 );
63+ // If this isn't here this can cause a deadlock on windows
64+ // See issue #297
65+ SafeShutdown .exit (0 , Platform ::exit );
6766 });
6867
6968 stage .setTitle ("GRIP Computer Vision Engine" );
@@ -74,30 +73,35 @@ public void start(Stage stage) throws Exception {
7473 }
7574
7675 public void stop () {
77- stopping = true ;
76+ SafeShutdown . flagStopping () ;
7877 }
7978
8079 @ Subscribe
8180 @ SuppressWarnings ("PMD.AvoidCatchingThrowable" )
8281 public final void onUnexpectedThrowableEvent (UnexpectedThrowableEvent event ) {
8382 event .handleSafely ((throwable , message , isFatal ) -> {
84- // This should still use PlatformImpl
85- if (!stopping ) {
83+ // Check this so we can avoid entering the the platform wait
84+ // if the program is shutting down.
85+ if (!SafeShutdown .isStopping ()) {
86+ // This should still use PlatformImpl
8687 PlatformImpl .runAndWait (() -> {
8788 // WARNING! Do not post any events from within this! It could result in a deadlock!
8889 synchronized (this .dialogLock ) {
89- try {
90- // Don't create more than one exception dialog at the same time
91- final ExceptionAlert exceptionAlert = new ExceptionAlert (root , throwable , message , isFatal , getHostServices ());
92- exceptionAlert .setInitialFocus ();
93- exceptionAlert .showAndWait ();
94- } catch (Throwable e ) {
95- // Well in this case something has gone very, very wrong
96- // We don't want to create a feedback loop either.
90+ // Check again because the value could have been changed while waiting for the javafx thread to run.
91+ if (!SafeShutdown .isStopping ()) {
9792 try {
98- logger .log (Level .SEVERE , "Failed to show exception alert" , e );
99- } finally {
100- System .exit (1 ); // Ensure we shut down the application if we get an exception
93+ // Don't create more than one exception dialog at the same time
94+ final ExceptionAlert exceptionAlert = new ExceptionAlert (root , throwable , message , isFatal , getHostServices ());
95+ exceptionAlert .setInitialFocus ();
96+ exceptionAlert .showAndWait ();
97+ } catch (Throwable e ) {
98+ // Well in this case something has gone very, very wrong
99+ // We don't want to create a feedback loop either.
100+ try {
101+ logger .log (Level .SEVERE , "Failed to show exception alert" , e );
102+ } finally {
103+ SafeShutdown .exit (1 ); // Ensure we shut down the application if we get an exception
104+ }
101105 }
102106 }
103107 }
0 commit comments