Skip to content

Commit 923dbd5

Browse files
committed
Create a detached process to clean up tmp dirs on closing
The temp dir cleanup is done on the "exit" notification. BTW, if the OS/system is too slow, the language server may be killed by the IDE if it takes too long to clean up temporary build directories. To avoid it a new detached process is created with the only purpose to remove the temporary directories. Since it's detached it will run even after the parent process exits.
1 parent 6c64232 commit 923dbd5

File tree

2 files changed

+49
-8
lines changed

2 files changed

+49
-8
lines changed

Diff for: ls/ls.go

+42-8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"io"
2323
"log"
2424
"os"
25+
"os/exec"
2526
"strconv"
2627
"strings"
2728
"sync"
@@ -50,6 +51,7 @@ type INOLanguageServer struct {
5051

5152
progressHandler *progressProxyHandler
5253
closing chan bool
54+
removeTempMutex sync.Mutex
5355
clangdStarted *sync.Cond
5456
dataMux sync.RWMutex
5557
buildPath *paths.Path
@@ -387,6 +389,7 @@ func (ls *INOLanguageServer) shutdownReqFromIDE(ctx context.Context, logger json
387389
close(done)
388390
}()
389391
_, _ = ls.Clangd.conn.Shutdown(context.Background())
392+
ls.removeTemporaryFiles(logger)
390393
<-done
391394
return nil
392395
}
@@ -1371,6 +1374,45 @@ func (ls *INOLanguageServer) setTraceNotifFromIDE(logger jsonrpc.FunctionLogger,
13711374
ls.Clangd.conn.SetTrace(params)
13721375
}
13731376

1377+
func (ls *INOLanguageServer) removeTemporaryFiles(logger jsonrpc.FunctionLogger) {
1378+
ls.removeTempMutex.Lock()
1379+
defer ls.removeTempMutex.Unlock()
1380+
1381+
args := []string{"remove-temp-files"}
1382+
if ls.buildPath != nil {
1383+
args = append(args, ls.buildPath.String())
1384+
}
1385+
if ls.fullBuildPath != nil {
1386+
args = append(args, ls.fullBuildPath.String())
1387+
}
1388+
if len(args) == 1 {
1389+
// Nothing to remove
1390+
return
1391+
}
1392+
1393+
// Start a detached process to remove the temp files
1394+
cwd, err := os.Getwd()
1395+
if err != nil {
1396+
logger.Logf("Error getting current working directory: %s", err)
1397+
return
1398+
}
1399+
cmd := exec.Command(os.Args[0], args...)
1400+
cmd.Dir = cwd
1401+
if err := cmd.Start(); err != nil {
1402+
logger.Logf("Error starting remove-temp-files process: %s", err)
1403+
return
1404+
}
1405+
1406+
// The process is now started, we can reset the paths
1407+
ls.buildPath, ls.fullBuildPath = nil, nil
1408+
1409+
// Detach the process so it can continue running even if the parent process exits
1410+
if err := cmd.Process.Release(); err != nil {
1411+
logger.Logf("Error detaching remove-temp-files process: %s", err)
1412+
return
1413+
}
1414+
}
1415+
13741416
// Close closes all the json-rpc connections and clean-up temp folders.
13751417
func (ls *INOLanguageServer) Close() {
13761418
if ls.Clangd != nil {
@@ -1381,14 +1423,6 @@ func (ls *INOLanguageServer) Close() {
13811423
close(ls.closing)
13821424
ls.closing = nil
13831425
}
1384-
if ls.buildPath != nil {
1385-
ls.buildPath.RemoveAll()
1386-
ls.buildPath = nil
1387-
}
1388-
if ls.fullBuildPath != nil {
1389-
ls.fullBuildPath.RemoveAll()
1390-
ls.fullBuildPath = nil
1391-
}
13921426
}
13931427

13941428
// CloseNotify returns a channel that is closed when the InoHandler is closed

Diff for: main.go

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ import (
2020
)
2121

2222
func main() {
23+
if len(os.Args) > 1 && os.Args[1] == "remove-temp-files" {
24+
for _, tmpFile := range os.Args[2:] {
25+
paths.New(tmpFile).RemoveAll()
26+
}
27+
return
28+
}
29+
2330
clangdPath := flag.String(
2431
"clangd", "",
2532
"Path to clangd executable")

0 commit comments

Comments
 (0)