osproc: added a better version of waitForExit for Haiku (#13938)

Also modified tosprocterminate to verify waitForExit implementations.
This commit is contained in:
alaviss 2020-04-10 07:34:52 +00:00 • committed by GitHub
commit 5f6962337d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 6 deletions

View file

@ -1167,6 +1167,67 @@ elif not defined(useNimRtl):
discard posix.close(kqFD)
result = exitStatusLikeShell(p.exitStatus)
elif defined(haiku):
const
B_OBJECT_TYPE_THREAD = 3
B_EVENT_INVALID = 0x1000
B_RELATIVE_TIMEOUT = 0x8
type
ObjectWaitInfo {.importc: "object_wait_info", header: "OS.h".} = object
obj {.importc: "object".}: int32
typ {.importc: "type".}: uint16
events: uint16
proc waitForObjects(infos: ptr ObjectWaitInfo, numInfos: cint, flags: uint32,
timeout: int64): clong
{.importc: "wait_for_objects_etc", header: "OS.h".}
proc waitForExit(p: Process, timeout: int = -1): int =
if p.exitFlag:
return exitStatusLikeShell(p.exitStatus)
if timeout == -1:
var status: cint = 1
if waitpid(p.id, status, 0) < 0:
raiseOSError(osLastError())
p.exitFlag = true
p.exitStatus = status
else:
var info = ObjectWaitInfo(
obj: p.id, # Haiku's PID is actually the main thread ID.
typ: B_OBJECT_TYPE_THREAD,
events: B_EVENT_INVALID # notify when the thread die.
)
while true:
var status: cint = 1
let count = waitForObjects(addr info, 1, B_RELATIVE_TIMEOUT, timeout)
if count < 0:
let err = count.cint
if err == ETIMEDOUT:
# timeout expired, so we try to kill the process
if posix.kill(p.id, SIGKILL) == -1:
raiseOSError(osLastError())
if waitpid(p.id, status, 0) < 0:
raiseOSError(osLastError())
p.exitFlag = true
p.exitStatus = status
break
elif err != EINTR:
raiseOSError(err.OSErrorCode)
elif count > 0:
if waitpid(p.id, status, 0) < 0:
raiseOSError(osLastError())
p.exitFlag = true
p.exitStatus = status
break
else:
doAssert false, "unreachable!"
result = exitStatusLikeShell(p.exitStatus)
else:
import times