void quitR(final boolean saveChanges) { final ProgressDelayer progress = new ProgressDelayer("Quitting R Session..."); // Use a barrier and LastChanceSaveEvent to allow source documents // and client state to be synchronized before quitting. Barrier barrier = new Barrier(); barrier.addBarrierReleasedHandler( new BarrierReleasedHandler() { public void onBarrierReleased(BarrierReleasedEvent event) { // All last chance save operations have completed (or possibly // failed). Now do the real quit. server_.quitSession( saveChanges, new VoidServerRequestCallback( globalDisplay_.getProgressIndicator("Error Quitting R")) { @Override public void onResponseReceived(org.rstudio.studio.client.server.Void response) { progress.dismiss(); super.onResponseReceived(response); } @Override public void onError(ServerError error) { progress.dismiss(); super.onError(error); } }); } }); // We acquire a token to make sure that the barrier doesn't fire before // all the LastChanceSaveEvent listeners get a chance to acquire their // own tokens. Token token = barrier.acquire(); try { events_.fireEvent(new LastChanceSaveEvent(barrier)); } finally { token.release(); } }
public void execute() { // show delayed progress String msg = progressMessage_; if (msg == null) { msg = switchToProject_ != null ? buildSwitchMessage(switchToProject_) : "Quitting R Session..."; } final GlobalProgressDelayer progress = new GlobalProgressDelayer(globalDisplay_, 250, msg); // Use a barrier and LastChanceSaveEvent to allow source documents // and client state to be synchronized before quitting. Barrier barrier = new Barrier(); barrier.addBarrierReleasedHandler( new BarrierReleasedHandler() { public void onBarrierReleased(BarrierReleasedEvent event) { // All last chance save operations have completed (or possibly // failed). Now do the real quit. // notify the desktop frame that we are about to quit String switchToProject = new String(switchToProject_); if (Desktop.isDesktop()) { if (Desktop.getFrame().isCocoa() && switchToProject_ != null) { // on Cocoa there's an ugly intermittent crash that occurs // when we reload, so exit this instance and start a new // one when switching projects Desktop.getFrame().setPendingProject(switchToProject_); // Since we're going to be starting a new process we don't // want to pass a switchToProject argument to quitSession switchToProject = null; } else { Desktop.getFrame() .setPendingQuit( switchToProject_ != null ? DesktopFrame.PENDING_QUIT_RESTART_AND_RELOAD : DesktopFrame.PENDING_QUIT_AND_EXIT); } } server_.quitSession( saveChanges_, switchToProject, switchToRVersion_, GWT.getHostPageBaseURL(), new ServerRequestCallback<Boolean>() { @Override public void onResponseReceived(Boolean response) { if (response) { // clear progress only if we aren't switching projects // (otherwise we want to leave progress up until // the app reloads) if (switchToProject_ == null) progress.dismiss(); // fire onQuitAcknowledged if (onQuitAcknowledged_ != null) onQuitAcknowledged_.execute(); } else { onFailedToQuit(); } } @Override public void onError(ServerError error) { onFailedToQuit(); } private void onFailedToQuit() { progress.dismiss(); if (Desktop.isDesktop()) { Desktop.getFrame().setPendingQuit(DesktopFrame.PENDING_QUIT_NONE); } } }); } }); // We acquire a token to make sure that the barrier doesn't fire before // all the LastChanceSaveEvent listeners get a chance to acquire their // own tokens. Token token = barrier.acquire(); try { eventBus_.fireEvent(new LastChanceSaveEvent(barrier)); } finally { token.release(); } }