diff --git a/cmd/tsgo/isprocessalive_other.go b/cmd/tsgo/isprocessalive_other.go deleted file mode 100644 index e847d9a43ce..00000000000 --- a/cmd/tsgo/isprocessalive_other.go +++ /dev/null @@ -1,9 +0,0 @@ -//go:build !unix && !windows - -package main - -const processAliveSupported = false - -func isProcessAlive(pid int) bool { - panic("isProcessAlive is not supported on this platform") -} diff --git a/cmd/tsgo/isprocessalive_unix.go b/cmd/tsgo/isprocessalive_unix.go deleted file mode 100644 index 0517d37c019..00000000000 --- a/cmd/tsgo/isprocessalive_unix.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build unix - -package main - -import ( - "errors" - "os" - "syscall" -) - -const processAliveSupported = true - -// isProcessAlive checks if a process with the given PID is still running. -// On Unix, FindProcess always succeeds, so we send signal 0 to probe the -// process. If the signal returns nil or EPERM, the process exists (EPERM -// means it exists but we lack permission to signal it). ESRCH or any -// other error indicates the process is gone. -func isProcessAlive(pid int) bool { - proc, err := os.FindProcess(pid) - if err != nil { - return false - } - err = proc.Signal(syscall.Signal(0)) - return err == nil || errors.Is(err, syscall.EPERM) -} diff --git a/cmd/tsgo/isprocessalive_windows.go b/cmd/tsgo/isprocessalive_windows.go deleted file mode 100644 index 3f0a81c6a75..00000000000 --- a/cmd/tsgo/isprocessalive_windows.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:build windows - -package main - -import "syscall" - -const processAliveSupported = true - -// isProcessAlive checks if a process with the given PID is still running. -// On Windows, we open the process with SYNCHRONIZE access and use -// WaitForSingleObject with a zero timeout. If the wait times out, the -// process is still running. If the object is signaled, it has exited. -func isProcessAlive(pid int) bool { - const SYNCHRONIZE = 0x00100000 - handle, err := syscall.OpenProcess(SYNCHRONIZE, false, uint32(pid)) - if err != nil { - return false - } - defer func() { _ = syscall.CloseHandle(handle) }() - ret, err := syscall.WaitForSingleObject(handle, 0) - if err != nil { - return false - } - const WAIT_TIMEOUT = 258 - return ret == WAIT_TIMEOUT -} diff --git a/cmd/tsgo/lsp.go b/cmd/tsgo/lsp.go index bc1a63b6d9a..267992dcefb 100644 --- a/cmd/tsgo/lsp.go +++ b/cmd/tsgo/lsp.go @@ -60,8 +60,7 @@ func runLSP(args []string) int { cmd.Dir = cwd return cmd.Output() }, - ProgressDelay: 250 * time.Millisecond, - SetParentProcessID: newParentProcessWatchdog(ctx, stop), + ProgressDelay: 250 * time.Millisecond, }) if err := s.Run(ctx); err != nil { @@ -70,39 +69,3 @@ func runLSP(args []string) int { } return 0 } - -// newParentProcessWatchdog returns a SetParentProcessID callback if the platform -// supports process-alive checking, or nil otherwise. -func newParentProcessWatchdog(ctx context.Context, stop context.CancelFunc) func(int) { - if !processAliveSupported { - return nil - } - return func(parentPID int) { - startParentProcessWatchdog(ctx, stop, parentPID) - } -} - -// startParentProcessWatchdog starts a goroutine that monitors the parent process -// and cancels the context if the parent dies. This prevents orphaned language -// server processes when the editor crashes or is killed. -func startParentProcessWatchdog(ctx context.Context, stop context.CancelFunc, parentPID int) { - if parentPID <= 0 { - return - } - go func() { - ticker := time.NewTicker(5 * time.Second) - defer ticker.Stop() - for { - select { - case <-ctx.Done(): - return - case <-ticker.C: - if !isProcessAlive(parentPID) { - fmt.Fprintf(os.Stderr, "Parent process %d has exited, shutting down.\n", parentPID) - stop() - return - } - } - } - }() -} diff --git a/internal/lsp/server.go b/internal/lsp/server.go index 5ba37e85880..9307a66f3de 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -48,7 +48,6 @@ type ServerOptions struct { ParseCache *project.ParseCache NpmInstall func(cwd string, args []string) ([]byte, error) ProgressDelay time.Duration // delay before showing progress UI; 0 means no delay - SetParentProcessID func(parentPID int) } func NewServer(opts *ServerOptions) *Server { @@ -70,7 +69,6 @@ func NewServer(opts *ServerOptions) *Server { typingsLocation: opts.TypingsLocation, parseCache: opts.ParseCache, npmInstall: opts.NpmInstall, - startWatchdog: opts.SetParentProcessID, initComplete: make(chan struct{}), progressDelay: opts.ProgressDelay, } @@ -221,8 +219,6 @@ type Server struct { progressDelay time.Duration projectProgress *projectLoadingProgress - startWatchdog func(parentPID int) - flakeLogging lsproto.DiagnosticFlakeLogLevel } @@ -1091,10 +1087,6 @@ func (s *Server) handleInitialize(ctx context.Context, params *lsproto.Initializ } s.initLocale = s.locale - if s.startWatchdog != nil && params.ProcessId.Integer != nil { - s.startWatchdog(int(*params.ProcessId.Integer)) - } - response := &lsproto.InitializeResult{ ServerInfo: &lsproto.ServerInfo{ Name: "typescript-go",