waitSignal() helper and tests for it. (#289)
* Add waitForSignal() implementation and tests. * Fix compilation issues. * Fix mistype. * Rename to waitSignal(). * Fix Windows compilation issue. * Re-export posix signals. * Remove signal handler on continuation too.
This commit is contained in:
parent
84e32a3b69
commit
377e197417
|
@ -174,7 +174,13 @@ when defined(windows):
|
|||
elif unixPlatform:
|
||||
import ./selectors2
|
||||
from posix import EINTR, EAGAIN, EINPROGRESS, EWOULDBLOCK, MSG_PEEK,
|
||||
MSG_NOSIGNAL, SIGPIPE
|
||||
MSG_NOSIGNAL
|
||||
from posix import SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
|
||||
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
||||
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE
|
||||
export SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
|
||||
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
||||
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE
|
||||
|
||||
type
|
||||
CallbackFunc* = proc (arg: pointer) {.gcsafe, raises: [Defect].}
|
||||
|
@ -851,6 +857,50 @@ proc callIdle*(cbproc: CallbackFunc) {.gcsafe, raises: [Defect].} =
|
|||
|
||||
include asyncfutures2
|
||||
|
||||
when not(defined(windows)):
|
||||
when ioselSupportedPlatform:
|
||||
proc waitSignal*(signal: int): Future[void] {.
|
||||
raises: [Defect].} =
|
||||
var retFuture = newFuture[void]("chronos.waitSignal()")
|
||||
var sigfd: int = -1
|
||||
|
||||
template getSignalException(e: untyped): untyped =
|
||||
newException(AsyncError, "Could not manipulate signal handler, " &
|
||||
"reason [" & $e.name & "]: " & $e.msg)
|
||||
|
||||
proc continuation(udata: pointer) {.gcsafe.} =
|
||||
if not(retFuture.finished()):
|
||||
if sigfd != -1:
|
||||
try:
|
||||
removeSignal(sigfd)
|
||||
retFuture.complete()
|
||||
except IOSelectorsException as exc:
|
||||
retFuture.fail(getSignalException(exc))
|
||||
|
||||
proc cancellation(udata: pointer) {.gcsafe.} =
|
||||
if not(retFuture.finished()):
|
||||
if sigfd != -1:
|
||||
try:
|
||||
removeSignal(sigfd)
|
||||
except IOSelectorsException as exc:
|
||||
retFuture.fail(getSignalException(exc))
|
||||
|
||||
sigfd =
|
||||
try:
|
||||
addSignal(signal, continuation)
|
||||
except IOSelectorsException as exc:
|
||||
retFuture.fail(getSignalException(exc))
|
||||
return retFuture
|
||||
except ValueError as exc:
|
||||
retFuture.fail(getSignalException(exc))
|
||||
return retFuture
|
||||
except OSError as exc:
|
||||
retFuture.fail(getSignalException(exc))
|
||||
return retFuture
|
||||
|
||||
retFuture.cancelCallback = cancellation
|
||||
retFuture
|
||||
|
||||
proc sleepAsync*(duration: Duration): Future[void] =
|
||||
## Suspends the execution of the current async procedure for the next
|
||||
## ``duration`` time.
|
||||
|
|
|
@ -38,13 +38,33 @@ suite "Signal handling test suite":
|
|||
discard posix.kill(posix.getpid(), cint(signal))
|
||||
waitFor(fut)
|
||||
signalCounter == value
|
||||
else:
|
||||
const
|
||||
SIGINT = 0
|
||||
SIGTERM = 0
|
||||
proc test(signal, value: int): bool = true
|
||||
|
||||
proc testWait(signal: int): bool =
|
||||
var fut = waitSignal(signal)
|
||||
discard posix.kill(posix.getpid(), cint(signal))
|
||||
waitFor(fut)
|
||||
true
|
||||
|
||||
test "SIGINT test":
|
||||
check test(SIGINT, 31337) == true
|
||||
when not defined(windows):
|
||||
check test(SIGINT, 31337) == true
|
||||
else:
|
||||
skip()
|
||||
|
||||
test "SIGTERM test":
|
||||
check test(SIGTERM, 65537) == true
|
||||
when defined(windows):
|
||||
skip()
|
||||
else:
|
||||
check test(SIGTERM, 65537) == true
|
||||
|
||||
test "waitSignal(SIGINT) test":
|
||||
when defined(windows):
|
||||
skip()
|
||||
else:
|
||||
check testWait(SIGINT) == true
|
||||
|
||||
test "waitSignal(SIGTERM) test":
|
||||
when defined(windows):
|
||||
skip()
|
||||
else:
|
||||
check testWait(SIGTERM) == true
|
||||
|
|
Loading…
Reference in New Issue