2424import com .redhat .devtools .intellij .lsp4ij .internal .SupportedFeatures ;
2525import com .redhat .devtools .intellij .lsp4ij .server .ProcessStreamConnectionProvider ;
2626import com .redhat .devtools .intellij .lsp4ij .server .StreamConnectionProvider ;
27- import com .redhat .devtools .intellij .lsp4ij .settings .ServerTrace ;
28- import com .redhat .devtools .intellij .lsp4ij .settings .UserDefinedLanguageServerSettings ;
2927import com .redhat .devtools .intellij .lsp4ij .lifecycle .LanguageServerLifecycleManager ;
3028import com .redhat .devtools .intellij .lsp4ij .lifecycle .NullLanguageServerLifecycleManager ;
3129import org .eclipse .lsp4j .*;
@@ -114,7 +112,11 @@ public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile f
114112 private LanguageServer languageServer ;
115113 private LanguageClientImpl languageClient ;
116114 private ServerCapabilities serverCapabilities ;
117- private Timer timer ;
115+
116+ private final Timer timer = new Timer ("Stop Language Server Task Processor" ); //$NON-NLS-1$
117+
118+ private TimerTask stopTimerTask ;
119+
118120 private final AtomicBoolean stopping = new AtomicBoolean (false );
119121
120122 private final ExecutorService dispatcher ;
@@ -295,7 +297,7 @@ public synchronized void start() throws IOException {
295297 messageBusConnection = ApplicationManager .getApplication ().getMessageBus ().connect ();
296298 messageBusConnection .subscribe (AppTopics .FILE_DOCUMENT_SYNC , fileBufferListener );
297299 messageBusConnection .subscribe (FileEditorManagerListener .FILE_EDITOR_MANAGER , fileBufferListener );
298- getLanguageServerLifecycleManager ().onStartedLanguageServer (this , null );
300+ getLanguageServerLifecycleManager ().onStartedLanguageServer (this , null );
299301 }).exceptionally (e -> {
300302 LOGGER .error ("Error while starting language server '" + serverDefinition .id + "'" , e );
301303 initializeFuture .completeExceptionally (e );
@@ -372,23 +374,36 @@ private void logMessage(Message message, MessageConsumer consumer) {
372374 getLanguageServerLifecycleManager ().logLSPMessage (message , consumer , this );
373375 }
374376
375- private void removeStopTimer () {
376- if (timer != null ) {
377- timer .cancel ();
378- timer = null ;
379- getLanguageServerLifecycleManager ().onStartedLanguageServer (this , null );
377+ private void removeStopTimerTask () {
378+ if (!shouldUseStopTimer ()) {
379+ return ;
380+ }
381+ synchronized (timer ) {
382+ if (stopTimerTask != null ) {
383+ stopTimerTask .cancel ();
384+ stopTimerTask = null ;
385+ getLanguageServerLifecycleManager ().onStartedLanguageServer (this , null );
386+ }
380387 }
381388 }
382389
383- private void startStopTimer () {
384- timer = new Timer ( "Stop Language Server Timer" ); //$NON-NLS-1$
385- getLanguageServerLifecycleManager (). onStoppingLanguageServer ( this ) ;
386- timer . schedule ( new TimerTask () {
387- @ Override
388- public void run ( ) {
389- stop ();
390+ private void startStopTimerTask () {
391+ if (! shouldUseStopTimer ()) {
392+ return ;
393+ }
394+ synchronized ( timer ) {
395+ if ( stopTimerTask != null ) {
396+ stopTimerTask . cancel ();
390397 }
391- }, TimeUnit .SECONDS .toMillis (this .serverDefinition .lastDocumentDisconnectedTimeout ));
398+ getLanguageServerLifecycleManager ().onStoppingLanguageServer (this );
399+ stopTimerTask = new TimerTask () {
400+ @ Override
401+ public void run () {
402+ stop ();
403+ }
404+ };
405+ timer .schedule (stopTimerTask , TimeUnit .SECONDS .toMillis (this .serverDefinition .lastDocumentDisconnectedTimeout ));
406+ }
392407 }
393408
394409 /**
@@ -413,7 +428,7 @@ public synchronized void stop() {
413428 return ;
414429 }
415430 getLanguageServerLifecycleManager ().onStoppingLanguageServer (this );
416- removeStopTimer ();
431+ removeStopTimerTask ();
417432 if (this .languageClient != null ) {
418433 this .languageClient .dispose ();
419434 }
@@ -619,7 +634,7 @@ private boolean supportsWorkspaceFolderCapability() {
619634 * @noreference internal so far
620635 */
621636 private CompletableFuture <LanguageServer > connect (@ Nonnull URI absolutePath , Document document ) throws IOException {
622- removeStopTimer ();
637+ removeStopTimerTask ();
623638 final URI thePath = absolutePath ; // should be useless
624639
625640 VirtualFile file = FileDocumentManager .getInstance ().getFile (document );
@@ -676,9 +691,8 @@ private void disconnect(URI path, boolean stopping) {
676691 documentListener .documentClosed ();
677692 }
678693 if (!stopping && this .connectedDocuments .isEmpty ()) {
679- if (this .serverDefinition .lastDocumentDisconnectedTimeout != 0 && !ApplicationManager .getApplication ().isUnitTestMode ()) {
680- removeStopTimer ();
681- startStopTimer ();
694+ if (shouldUseStopTimer ()) {
695+ startStopTimerTask ();
682696 } else {
683697 stop ();
684698 }
@@ -980,4 +994,8 @@ private static int getParentProcessId() {
980994 public Long getCurrentProcessId () {
981995 return lspStreamProvider instanceof ProcessStreamConnectionProvider ? ((ProcessStreamConnectionProvider ) lspStreamProvider ).getPid () : null ;
982996 }
997+
998+ private boolean shouldUseStopTimer () {
999+ return this .serverDefinition .lastDocumentDisconnectedTimeout != 0 && !ApplicationManager .getApplication ().isUnitTestMode ();
1000+ }
9831001}
0 commit comments