]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.workbench/src/org/simantics/workbench/internal/SimanticsWorkbenchApplication.java
Use Runtime.halt instead of System.exit in delayed shutdown
[simantics/platform.git] / bundles / org.simantics.workbench / src / org / simantics / workbench / internal / SimanticsWorkbenchApplication.java
index 8b0431f38e9cde7d6236b146ab5d239034eca37a..50e8aada7b3f4cd3c14acdeee796427123db7dab 100644 (file)
@@ -56,6 +56,8 @@ import org.simantics.db.management.SessionContextProvider;
 import org.simantics.db.management.SingleSessionContextProviderSource;
 import org.simantics.ui.SimanticsUI;
 import org.simantics.utils.ui.BundleUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -65,6 +67,7 @@ import org.simantics.utils.ui.BundleUtils;
  */
 public class SimanticsWorkbenchApplication implements IApplication, IExecutableExtension {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(SimanticsWorkbenchApplication.class);
     /**
      * The name of the folder containing metadata information for the workspace.
      */
@@ -77,6 +80,9 @@ public class SimanticsWorkbenchApplication implements IApplication, IExecutableE
     private static final String WORKSPACE_VERSION_VALUE = "1"; //$NON-NLS-1$
 
     private static final String PROP_EXIT_CODE = "eclipse.exitcode"; //$NON-NLS-1$
+    
+    private static final String PROP_SHUTDOWN_GRACE_PERIOD = "simantics.shutdownGracePeriod"; //$NON-NLS-1$
+    private static final long DEFAULT_SHUTDOWN_GRACE_PERIOD = 5000L;
 
     /**
      * A special return code that will be recognized by the launcher and used to
@@ -149,18 +155,26 @@ public class SimanticsWorkbenchApplication implements IApplication, IExecutableE
             // PlatformUI.getWorkbench() or AbstractUIPlugin.getWorkbench()
             int returnCode = PlatformUI.createAndRunWorkbench(display,
                     createWorkbenchAdvisor(args, processor));
+            
+            Long shutdownGracePeriodPropValue = Long.getLong(PROP_SHUTDOWN_GRACE_PERIOD);
+            long shutdownGracePeriod = shutdownGracePeriodPropValue == null 
+                    ? DEFAULT_SHUTDOWN_GRACE_PERIOD
+                    : shutdownGracePeriodPropValue;
 
             // the workbench doesn't support relaunch yet (bug 61809) so
             // for now restart is used, and exit data properties are checked
             // here to substitute in the relaunch return code if needed
             if (returnCode != PlatformUI.RETURN_RESTART) {
+                delayedShutdown(EXIT_OK, shutdownGracePeriod);
                 return EXIT_OK;
             }
 
             // if the exit code property has been set to the relaunch code, then
             // return that code now, otherwise this is a normal restart
-            return EXIT_RELAUNCH.equals(Integer.getInteger(PROP_EXIT_CODE)) ? EXIT_RELAUNCH
+            int exitCode = EXIT_RELAUNCH.equals(Integer.getInteger(PROP_EXIT_CODE)) ? EXIT_RELAUNCH
                     : EXIT_RESTART;
+            delayedShutdown(exitCode, shutdownGracePeriod);
+            return exitCode;
         } finally {
             if (display != null) {
                 display.dispose();
@@ -171,6 +185,27 @@ public class SimanticsWorkbenchApplication implements IApplication, IExecutableE
         }
     }
 
+    private void delayedShutdown(int exitCode, long delayMs) {
+        LOGGER.info("Started delayed shutdown with delay {} ms.", delayMs);
+        Thread shutdownThread = new Thread() {
+            @Override
+            public void run() {
+                try {
+                    Thread.sleep(delayMs);
+                    LOGGER.warn("Delayed shutdown forced the application to exit with code {}.", exitCode);
+                    // Method halt is used instead of System.exit, because running
+                    // of shutdown hooks hangs the application in some cases.
+                    Runtime.getRuntime().halt(exitCode);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        };
+        shutdownThread.setDaemon(true);
+        shutdownThread.setName("delayed-shutdown");
+        shutdownThread.start();
+    }
+
     /*************************************************************************/
 
     private IArguments parseArguments(String[] args) {
@@ -373,6 +408,20 @@ public class SimanticsWorkbenchApplication implements IApplication, IExecutableE
         return args.containsKey("-pdelaunch"); //$NON-NLS-1$
     }
 
+    private static class ChooseSimanticsWorkspaceDialog extends ChooseWorkspaceDialog {
+
+        public ChooseSimanticsWorkspaceDialog(Shell parentShell, ChooseWorkspaceData launchData, boolean suppressAskAgain, boolean centerOnMonitor) {
+            super(parentShell, launchData, suppressAskAgain, centerOnMonitor);
+        }
+        
+        @Override
+        protected void configureShell(Shell shell) {
+            super.configureShell(shell);
+            // Use product name in shell title instead of generic "Eclipse Launcher"
+            shell.setText(getWindowTitle());
+        }
+    }
+
     /**
      * Open a workspace selection dialog on the argument shell, populating the
      * argument data with the user's selection. Perform first level validation
@@ -392,7 +441,8 @@ public class SimanticsWorkbenchApplication implements IApplication, IExecutableE
         URL url = null;
         do {
             // okay to use the shell now - this is the splash shell
-            new ChooseWorkspaceDialog(shell, launchData, suppressAskAgain, true).prompt(force);
+            new ChooseSimanticsWorkspaceDialog(shell, launchData, suppressAskAgain, true).prompt(force); 
+            
             String instancePath = launchData.getSelection();
             if (instancePath == null) {
                 return null;