diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java index 2802b7873..acfce09e8 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java @@ -24,8 +24,6 @@ import com.redhat.devtools.intellij.lsp4ij.internal.SupportedFeatures; import com.redhat.devtools.intellij.lsp4ij.server.ProcessStreamConnectionProvider; import com.redhat.devtools.intellij.lsp4ij.server.StreamConnectionProvider; -import com.redhat.devtools.intellij.lsp4ij.settings.ServerTrace; -import com.redhat.devtools.intellij.lsp4ij.settings.UserDefinedLanguageServerSettings; import com.redhat.devtools.intellij.lsp4ij.lifecycle.LanguageServerLifecycleManager; import com.redhat.devtools.intellij.lsp4ij.lifecycle.NullLanguageServerLifecycleManager; import org.eclipse.lsp4j.*; @@ -114,7 +112,11 @@ public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile f private LanguageServer languageServer; private LanguageClientImpl languageClient; private ServerCapabilities serverCapabilities; - private Timer timer; + + private final Timer timer = new Timer("Stop Language Server Task Processor"); //$NON-NLS-1$ + + private TimerTask stopTimerTask; + private final AtomicBoolean stopping = new AtomicBoolean(false); private final ExecutorService dispatcher; @@ -295,7 +297,7 @@ public synchronized void start() throws IOException { messageBusConnection = ApplicationManager.getApplication().getMessageBus().connect(); messageBusConnection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, fileBufferListener); messageBusConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, fileBufferListener); - getLanguageServerLifecycleManager().onStartedLanguageServer(this, null); + getLanguageServerLifecycleManager().onStartedLanguageServer(this, null); }).exceptionally(e -> { LOGGER.error("Error while starting language server '" + serverDefinition.id + "'", e); initializeFuture.completeExceptionally(e); @@ -372,23 +374,30 @@ private void logMessage(Message message, MessageConsumer consumer) { getLanguageServerLifecycleManager().logLSPMessage(message, consumer, this); } - private void removeStopTimer() { - if (timer != null) { - timer.cancel(); - timer = null; - getLanguageServerLifecycleManager().onStartedLanguageServer(this, null); + private void removeStopTimerTask() { + synchronized (timer) { + if (stopTimerTask != null) { + stopTimerTask.cancel(); + stopTimerTask = null; + getLanguageServerLifecycleManager().onStartedLanguageServer(this, null); + } } } - private void startStopTimer() { - timer = new Timer("Stop Language Server Timer"); //$NON-NLS-1$ - getLanguageServerLifecycleManager().onStoppingLanguageServer(this); - timer.schedule(new TimerTask() { - @Override - public void run() { - stop(); + private void startStopTimerTask() { + synchronized (timer) { + if (stopTimerTask != null) { + stopTimerTask.cancel(); } - }, TimeUnit.SECONDS.toMillis(this.serverDefinition.lastDocumentDisconnectedTimeout)); + getLanguageServerLifecycleManager().onStoppingLanguageServer(this); + stopTimerTask = new TimerTask() { + @Override + public void run() { + stop(); + } + }; + timer.schedule(stopTimerTask, TimeUnit.SECONDS.toMillis(this.serverDefinition.lastDocumentDisconnectedTimeout)); + } } /** @@ -413,7 +422,7 @@ public synchronized void stop() { return; } getLanguageServerLifecycleManager().onStoppingLanguageServer(this); - removeStopTimer(); + removeStopTimerTask(); if (this.languageClient != null) { this.languageClient.dispose(); } @@ -619,7 +628,7 @@ private boolean supportsWorkspaceFolderCapability() { * @noreference internal so far */ private CompletableFuture connect(@Nonnull URI absolutePath, Document document) throws IOException { - removeStopTimer(); + removeStopTimerTask(); final URI thePath = absolutePath; // should be useless VirtualFile file = FileDocumentManager.getInstance().getFile(document); @@ -677,8 +686,7 @@ private void disconnect(URI path, boolean stopping) { } if (!stopping && this.connectedDocuments.isEmpty()) { if (this.serverDefinition.lastDocumentDisconnectedTimeout != 0 && !ApplicationManager.getApplication().isUnitTestMode()) { - removeStopTimer(); - startStopTimer(); + startStopTimerTask(); } else { stop(); }