mirror of
https://github.com/status-im/nim-chronos.git
synced 2025-02-03 23:14:33 +00:00
Add asynchronous posix signal handling.
Add signal tests.
This commit is contained in:
parent
d75487948b
commit
a4528ab705
@ -26,6 +26,10 @@ task test, "Run all tests":
|
||||
exec "nim c -r tests/testfut"
|
||||
exec "nim c -r -d:release tests/testfut"
|
||||
|
||||
exec "nim c -r -d:useSysAssert -d:useGcAssert tests/testsignal"
|
||||
exec "nim c -r tests/testsignal"
|
||||
exec "nim c -r -d:release tests/testsignal"
|
||||
|
||||
exec "nim c -r -d:useSysAssert -d:useGcAssert tests/testdatagram"
|
||||
exec "nim c -r tests/testdatagram"
|
||||
exec "nim c -r -d:release tests/testdatagram"
|
||||
|
@ -185,6 +185,7 @@ proc initCallSoonProc() =
|
||||
|
||||
when defined(windows) or defined(nimdoc):
|
||||
import winlean, sets, hashes
|
||||
|
||||
type
|
||||
WSAPROC_TRANSMITFILE = proc(hSocket: SocketHandle, hFile: Handle,
|
||||
nNumberOfBytesToWrite: DWORD,
|
||||
@ -203,6 +204,9 @@ when defined(windows) or defined(nimdoc):
|
||||
bytesCount*: int32
|
||||
udata*: pointer
|
||||
|
||||
CustomOverlapped* = object of OVERLAPPED
|
||||
data*: CompletionData
|
||||
|
||||
PDispatcher* = ref object of PDispatcherBase
|
||||
ioPort: Handle
|
||||
handles: HashSet[AsyncFD]
|
||||
@ -211,9 +215,6 @@ when defined(windows) or defined(nimdoc):
|
||||
getAcceptExSockAddrs*: WSAPROC_GETACCEPTEXSOCKADDRS
|
||||
transmitFile*: WSAPROC_TRANSMITFILE
|
||||
|
||||
CustomOverlapped* = object of OVERLAPPED
|
||||
data*: CompletionData
|
||||
|
||||
PtrCustomOverlapped* = ptr CustomOverlapped
|
||||
|
||||
RefCustomOverlapped* = ref CustomOverlapped
|
||||
@ -324,12 +325,6 @@ when defined(windows) or defined(nimdoc):
|
||||
var callable = loop.callbacks.popFirst()
|
||||
callable.function(callable.udata)
|
||||
|
||||
template getUdata*(u: untyped) =
|
||||
if isNil(u):
|
||||
nil
|
||||
else:
|
||||
cast[ptr CustomOverlapped](u).data.udata
|
||||
|
||||
proc getFunc(s: SocketHandle, fun: var pointer, guid: var GUID): bool =
|
||||
var bytesRet: Dword
|
||||
fun = nil
|
||||
@ -497,6 +492,27 @@ else:
|
||||
raise newException(ValueError, "File descriptor not registered.")
|
||||
p.selector.updateHandle(int(fd), newEvents)
|
||||
|
||||
when ioselSupportedPlatform:
|
||||
proc addSignal*(signal: int, cb: CallbackFunc,
|
||||
udata: pointer = nil): int =
|
||||
## Start watching signal ``signal``, and when signal appears, call the
|
||||
## callback ``cb``. Returns signal identifier code, which can be used
|
||||
## to remove signal callback via ``removeSignal``.
|
||||
let p = getGlobalDispatcher()
|
||||
var data: SelectorData
|
||||
result = p.selector.registerSignal(signal, data)
|
||||
withData(p.selector, result, adata) do:
|
||||
adata.reader = AsyncCallback(function: cb, udata: addr adata.rdata)
|
||||
adata.rdata.fd = AsyncFD(result)
|
||||
adata.rdata.udata = udata
|
||||
do:
|
||||
raise newException(ValueError, "File descriptor not registered.")
|
||||
|
||||
proc removeSignal*(sigfd: int) =
|
||||
## Remove watching signal ``signal``.
|
||||
let p = getGlobalDispatcher()
|
||||
p.selector.unregister(sigfd)
|
||||
|
||||
proc poll*() =
|
||||
let loop = getGlobalDispatcher()
|
||||
var curTime = fastEpochTime()
|
||||
|
43
tests/testsignal.nim
Normal file
43
tests/testsignal.nim
Normal file
@ -0,0 +1,43 @@
|
||||
# Asyncdispatch2 Test Suite
|
||||
# (c) Copyright 2018
|
||||
# Status Research & Development GmbH
|
||||
#
|
||||
# Licensed under either of
|
||||
# Apache License, version 2.0, (LICENSE-APACHEv2)
|
||||
# MIT license (LICENSE-MIT)
|
||||
|
||||
import unittest, strutils
|
||||
import ../asyncdispatch2
|
||||
|
||||
when not defined(windows):
|
||||
import posix
|
||||
|
||||
var signalCounter = 0
|
||||
|
||||
proc signalProc(udata: pointer) =
|
||||
var cdata = cast[ptr CompletionData](udata)
|
||||
signalCounter = cast[int](cdata.udata)
|
||||
removeSignal(int(cdata.fd))
|
||||
|
||||
proc asyncProc() {.async.} =
|
||||
await sleepAsync(500)
|
||||
|
||||
proc test(signal, value: int): bool =
|
||||
discard addSignal(signal, signalProc, cast[pointer](value))
|
||||
var fut = asyncProc()
|
||||
discard posix.kill(posix.getpid(), cint(signal))
|
||||
waitFor(fut)
|
||||
signalCounter == value
|
||||
|
||||
else:
|
||||
const
|
||||
SIGINT = 0
|
||||
SIGTERM = 0
|
||||
proc test(signal, value: int): bool = true
|
||||
|
||||
when isMainModule:
|
||||
suite "Signal handling test suite":
|
||||
test "SIGINT test":
|
||||
check test(SIGINT, 31337) == true
|
||||
test "SIGTERM test":
|
||||
check test(SIGTERM, 65537) == true
|
Loading…
x
Reference in New Issue
Block a user