Open PhilippMDoerner opened 1 year ago
it does work on linux on a child process. i.e.
import std/[asyncdispatch,cmdline,strutils,osproc]
proc cb(fd:AsyncFD):bool =
echo "DONE"
let p = startProcess("echo 10",options={poEvalCommand,poParentStreams})
addProcess(p.processID,cb)
poll()
p.close()
prints
10
DONE
addProcess uses signalfd, which is never going to access signals directed at an unrelated process. you'd have to create the signalfd in that process, and then pass it over a socket or something to the awaiting process.
However, as a workaround you can leverage this stackoverflow answer
import std/[asyncdispatch,cmdline,strutils,strformat,osproc]
proc cb(fd:AsyncFD):bool =
echo "DONE"
proc addProcessExternal(pid:int; cb: Callback ) =
let p = startProcess(&"tail --pid={pid} -f /dev/null",options={poEvalCommand,poParentStreams})
addProcess(p.processId,proc(fd:AsyncFD):bool =
result = cb(fd)
p.close()
)
addProcessExternal(parseInt(commandLineParams()[0]),cb)
runForever()
try with
$ sleep 10& ./process2 $!
❯ sleep 10& ./process2 $!
[1] 222998
[1] + 222998 done sleep 10
DONE
/tmp/process2.nim(12) process2
/home/bwsq/.choosenim/toolchains/nim-#devel/lib/pure/asyncdispatch.nim(2017) runForever
/home/bwsq/.choosenim/toolchains/nim-#devel/lib/pure/asyncdispatch.nim(1711) poll
/home/bwsq/.choosenim/toolchains/nim-#devel/lib/pure/asyncdispatch.nim(1401) runOnce
Error: unhandled exception: No handles or timers registered in dispatcher. [ValueError]
from that answer it seems that tail
works by calling kill(pid,SIG_0)
repeatedly
hang on. ignore me. waitpid works with external processes. and it does so by
❯ sleep 10& strace waitpid $!
[1] 223810
...
pidfd_open(223810, 0) = 3
epoll_create(1) = 4
epoll_ctl(4, EPOLL_CTL_ADD, 3, {events=EPOLLIN, data={u32=0, u64=0}}) = 0
epoll_wait(4, [1] + 223810 done sleep 10
[{events=EPOLLIN, data={u32=0, u64=0}}], 1, -1) = 1
epoll_ctl(4, EPOLL_CTL_DEL, 3, NULL) = 0
exit_group(0) = ?
so this could work if addProcess used pidfd instead of signalfd
ref: pidfd_open.2
Description
addProcess
seems to not trigger on Linux when the process exits thataddProcess
is supposed to listen to.Step 1: Have a nim file with this code, compile and run it
Step 2: Execute
killall firefox
in a shell Step 3: Observe the shell in which you compiled and ran Step 1 - Nothing will have happenedFurther, if you set
firefoxProcessId
to a processId that currently is not in use by any process (e.g. 2) then the program will just run as normal. Which might be erroneous behaviour, I'm not entirely sure, just thought it worth mentioning.Nim Version
Nim Compiler Version 2.0.0 [Linux: amd64] Compiled at 2023-08-01 Copyright (c) 2006-2023 by Andreas Rumpf
git hash: a488067a4130f029000be4550a0fb1b39e0e9e7c active boot switches: -d:release
Current Output
Expected Output
Possible Solution
No response
Additional Information
This also occurs on nim 1.6.12. Both issues (no triggering of the callback and no error for registering for an unused PID) are not a problem on windows. https://discord.com/channels/371759389889003530/371759389889003532/1156172175846408242