diff --git a/compiler/options.nim b/compiler/options.nim index d3a96301ac..ea3b71a568 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -432,6 +432,8 @@ type expandNodeResult*: string expandPosition*: TLineInfo + clientProcessId*: int + proc parseNimVersion*(a: string): NimVer = # could be moved somewhere reusable diff --git a/nimsuggest/nimsuggest.nim b/nimsuggest/nimsuggest.nim index 36fa9c7287..2ffe06c8f6 100644 --- a/nimsuggest/nimsuggest.nim +++ b/nimsuggest/nimsuggest.nim @@ -12,6 +12,7 @@ import strformat import algorithm import tables import times +import procmonitor template tryImport(module) = import module @@ -56,6 +57,7 @@ Options: --address:HOST binds to that address, by default "" --stdin read commands from stdin and write results to stdout instead of using sockets + --clientProcessId:PID shutdown nimsuggest in case this process dies --epc use emacs epc mode --debug enable debug output --log enable verbose logging to nimsuggest.log file @@ -605,6 +607,9 @@ proc mainCommand(graph: ModuleGraph) = open(requests) open(results) + if graph.config.clientProcessId != 0: + hookProcMonitor(graph.config.clientProcessId) + case gMode of mstdin: createThread(inputThread, replStdin, (gPort, gAddress)) of mtcp: createThread(inputThread, replTcp, (gPort, gAddress)) @@ -680,6 +685,8 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string; conf: ConfigRef) = conf.suggestMaxResults = parseInt(p.val) of "find": findProject = true + of "clientprocessid": + conf.clientProcessId = parseInt(p.val) else: processSwitch(pass, p, conf) of cmdArgument: let a = unixToNativePath(p.key) diff --git a/nimsuggest/procmonitor.nim b/nimsuggest/procmonitor.nim new file mode 100644 index 0000000000..0f1ba1e0d3 --- /dev/null +++ b/nimsuggest/procmonitor.nim @@ -0,0 +1,34 @@ +# Monitor a client process and shutdown the current process, if the client +# process is found to be dead + +import os + +when defined(posix): + import posix_utils + import posix + +when defined(windows): + import winlean + +when defined(posix): + proc monitorClientProcessIdThreadProc(pid: int) {.thread.} = + while true: + sleep(1000) + try: + sendSignal(Pid(pid), 0) + except: + discard kill(Pid(getCurrentProcessId()), cint(SIGTERM)) + +when defined(windows): + proc monitorClientProcessIdThreadProc(pid: int) {.thread.} = + var process = openProcess(SYNCHRONIZE, 0, DWORD(pid)) + if process != 0: + discard waitForSingleObject(process, INFINITE) + discard closeHandle(process) + quit(0) + +var tid: Thread[int] + +proc hookProcMonitor*(pid: int) = + when defined(posix) or defined(windows): + createThread(tid, monitorClientProcessIdThreadProc, pid)