Recover `poll` engine and add tests. (#421)
* Initial commit. * Fix one more place with deprecated constant. * Fix testall and nimble file. * Fix poll issue. * Workaround Nim's faulty declaration of `poll()` and types on MacOS. * Fix syntax errors. * Fix MacOS post-rebase issue. * Add more conditionals. * Address review comments. * Fix Nim 1.2 configuration defaults.
This commit is contained in:
parent
5c39bf47be
commit
6b4f5a1d23
|
@ -5,6 +5,5 @@
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# Apache License, version 2.0, (LICENSE-APACHEv2)
|
# Apache License, version 2.0, (LICENSE-APACHEv2)
|
||||||
# MIT license (LICENSE-MIT)
|
# MIT license (LICENSE-MIT)
|
||||||
import chronos/[asyncloop, asyncsync, handles, transport, timer,
|
import chronos/[asyncloop, asyncsync, handles, transport, timer, debugutils]
|
||||||
asyncproc, debugutils]
|
export asyncloop, asyncsync, handles, transport, timer, debugutils
|
||||||
export asyncloop, asyncsync, handles, transport, timer, asyncproc, debugutils
|
|
||||||
|
|
|
@ -17,6 +17,22 @@ let nimc = getEnv("NIMC", "nim") # Which nim compiler to use
|
||||||
let lang = getEnv("NIMLANG", "c") # Which backend (c/cpp/js)
|
let lang = getEnv("NIMLANG", "c") # Which backend (c/cpp/js)
|
||||||
let flags = getEnv("NIMFLAGS", "") # Extra flags for the compiler
|
let flags = getEnv("NIMFLAGS", "") # Extra flags for the compiler
|
||||||
let verbose = getEnv("V", "") notin ["", "0"]
|
let verbose = getEnv("V", "") notin ["", "0"]
|
||||||
|
let testArguments =
|
||||||
|
when defined(windows):
|
||||||
|
[
|
||||||
|
"-d:debug -d:chronosDebug -d:useSysAssert -d:useGcAssert",
|
||||||
|
"-d:debug -d:chronosPreviewV4",
|
||||||
|
"-d:release",
|
||||||
|
"-d:release -d:chronosPreviewV4"
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
[
|
||||||
|
"-d:debug -d:chronosDebug -d:useSysAssert -d:useGcAssert",
|
||||||
|
"-d:debug -d:chronosPreviewV4",
|
||||||
|
"-d:debug -d:chronosDebug -d:chronosEventEngine=poll -d:useSysAssert -d:useGcAssert",
|
||||||
|
"-d:release",
|
||||||
|
"-d:release -d:chronosPreviewV4"
|
||||||
|
]
|
||||||
|
|
||||||
let styleCheckStyle = if (NimMajor, NimMinor) < (1, 6): "hint" else: "error"
|
let styleCheckStyle = if (NimMajor, NimMinor) < (1, 6): "hint" else: "error"
|
||||||
let cfg =
|
let cfg =
|
||||||
|
@ -31,12 +47,7 @@ proc run(args, path: string) =
|
||||||
build args & " -r", path
|
build args & " -r", path
|
||||||
|
|
||||||
task test, "Run all tests":
|
task test, "Run all tests":
|
||||||
for args in [
|
for args in testArguments:
|
||||||
"-d:debug -d:chronosDebug",
|
|
||||||
"-d:debug -d:chronosPreviewV4",
|
|
||||||
"-d:debug -d:chronosDebug -d:useSysAssert -d:useGcAssert",
|
|
||||||
"-d:release",
|
|
||||||
"-d:release -d:chronosPreviewV4"]:
|
|
||||||
run args, "tests/testall"
|
run args, "tests/testall"
|
||||||
if (NimMajor, NimMinor) > (1, 6):
|
if (NimMajor, NimMinor) > (1, 6):
|
||||||
run args & " --mm:refc", "tests/testall"
|
run args & " --mm:refc", "tests/testall"
|
||||||
|
|
|
@ -825,9 +825,9 @@ elif defined(macosx) or defined(freebsd) or defined(netbsd) or
|
||||||
var res = PDispatcher(
|
var res = PDispatcher(
|
||||||
selector: selector,
|
selector: selector,
|
||||||
timers: initHeapQueue[TimerCallback](),
|
timers: initHeapQueue[TimerCallback](),
|
||||||
callbacks: initDeque[AsyncCallback](asyncEventsCount),
|
callbacks: initDeque[AsyncCallback](chronosEventsCount),
|
||||||
idlers: initDeque[AsyncCallback](),
|
idlers: initDeque[AsyncCallback](),
|
||||||
keys: newSeq[ReadyKey](asyncEventsCount),
|
keys: newSeq[ReadyKey](chronosEventsCount),
|
||||||
trackers: initTable[string, TrackerBase](),
|
trackers: initTable[string, TrackerBase](),
|
||||||
counters: initTable[string, TrackerCounter]()
|
counters: initTable[string, TrackerCounter]()
|
||||||
)
|
)
|
||||||
|
@ -1009,7 +1009,7 @@ elif defined(macosx) or defined(freebsd) or defined(netbsd) or
|
||||||
## You can execute ``aftercb`` before actual socket close operation.
|
## You can execute ``aftercb`` before actual socket close operation.
|
||||||
closeSocket(fd, aftercb)
|
closeSocket(fd, aftercb)
|
||||||
|
|
||||||
when asyncEventEngine in ["epoll", "kqueue"]:
|
when chronosEventEngine in ["epoll", "kqueue"]:
|
||||||
type
|
type
|
||||||
ProcessHandle* = distinct int
|
ProcessHandle* = distinct int
|
||||||
SignalHandle* = distinct int
|
SignalHandle* = distinct int
|
||||||
|
@ -1123,7 +1123,7 @@ elif defined(macosx) or defined(freebsd) or defined(netbsd) or
|
||||||
if not isNil(adata.reader.function):
|
if not isNil(adata.reader.function):
|
||||||
loop.callbacks.addLast(adata.reader)
|
loop.callbacks.addLast(adata.reader)
|
||||||
|
|
||||||
when asyncEventEngine in ["epoll", "kqueue"]:
|
when chronosEventEngine in ["epoll", "kqueue"]:
|
||||||
let customSet = {Event.Timer, Event.Signal, Event.Process,
|
let customSet = {Event.Timer, Event.Signal, Event.Process,
|
||||||
Event.Vnode}
|
Event.Vnode}
|
||||||
if customSet * events != {}:
|
if customSet * events != {}:
|
||||||
|
@ -1257,10 +1257,7 @@ proc callIdle*(cbproc: CallbackFunc) =
|
||||||
|
|
||||||
include asyncfutures2
|
include asyncfutures2
|
||||||
|
|
||||||
|
when (chronosEventEngine in ["epoll", "kqueue"]) or defined(windows):
|
||||||
when defined(macosx) or defined(macos) or defined(freebsd) or
|
|
||||||
defined(netbsd) or defined(openbsd) or defined(dragonfly) or
|
|
||||||
defined(linux) or defined(windows):
|
|
||||||
|
|
||||||
proc waitSignal*(signal: int): Future[void] {.raises: [].} =
|
proc waitSignal*(signal: int): Future[void] {.raises: [].} =
|
||||||
var retFuture = newFuture[void]("chronos.waitSignal()")
|
var retFuture = newFuture[void]("chronos.waitSignal()")
|
||||||
|
|
|
@ -49,6 +49,27 @@ when (NimMajor, NimMinor) >= (1, 4):
|
||||||
## using `AsyncProcessOption.EvalCommand` and API calls such as
|
## using `AsyncProcessOption.EvalCommand` and API calls such as
|
||||||
## ``execCommand(command)`` and ``execCommandEx(command)``.
|
## ``execCommand(command)`` and ``execCommandEx(command)``.
|
||||||
|
|
||||||
|
chronosEventsCount* {.intdefine.} = 64
|
||||||
|
## Number of OS poll events retrieved by syscall (epoll, kqueue, poll).
|
||||||
|
|
||||||
|
chronosInitialSize* {.intdefine.} = 64
|
||||||
|
## Initial size of Selector[T]'s array of file descriptors.
|
||||||
|
|
||||||
|
chronosEventEngine* {.strdefine.}: string =
|
||||||
|
when defined(linux) and not(defined(android) or defined(emscripten)):
|
||||||
|
"epoll"
|
||||||
|
elif defined(macosx) or defined(macos) or defined(ios) or
|
||||||
|
defined(freebsd) or defined(netbsd) or defined(openbsd) or
|
||||||
|
defined(dragonfly):
|
||||||
|
"kqueue"
|
||||||
|
elif defined(android) or defined(emscripten):
|
||||||
|
"poll"
|
||||||
|
elif defined(posix):
|
||||||
|
"poll"
|
||||||
|
else:
|
||||||
|
""
|
||||||
|
## OS polling engine type which is going to be used by chronos.
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# 1.2 doesn't support `booldefine` in `when` properly
|
# 1.2 doesn't support `booldefine` in `when` properly
|
||||||
const
|
const
|
||||||
|
@ -69,6 +90,21 @@ else:
|
||||||
"/system/bin/sh"
|
"/system/bin/sh"
|
||||||
else:
|
else:
|
||||||
"/bin/sh"
|
"/bin/sh"
|
||||||
|
chronosEventsCount*: int = 64
|
||||||
|
chronosInitialSize*: int = 64
|
||||||
|
chronosEventEngine* {.strdefine.}: string =
|
||||||
|
when defined(linux) and not(defined(android) or defined(emscripten)):
|
||||||
|
"epoll"
|
||||||
|
elif defined(macosx) or defined(macos) or defined(ios) or
|
||||||
|
defined(freebsd) or defined(netbsd) or defined(openbsd) or
|
||||||
|
defined(dragonfly):
|
||||||
|
"kqueue"
|
||||||
|
elif defined(android) or defined(emscripten):
|
||||||
|
"poll"
|
||||||
|
elif defined(posix):
|
||||||
|
"poll"
|
||||||
|
else:
|
||||||
|
""
|
||||||
|
|
||||||
when defined(debug) or defined(chronosConfig):
|
when defined(debug) or defined(chronosConfig):
|
||||||
import std/macros
|
import std/macros
|
||||||
|
@ -83,3 +119,6 @@ when defined(debug) or defined(chronosConfig):
|
||||||
printOption("chronosFutureTracking", chronosFutureTracking)
|
printOption("chronosFutureTracking", chronosFutureTracking)
|
||||||
printOption("chronosDumpAsync", chronosDumpAsync)
|
printOption("chronosDumpAsync", chronosDumpAsync)
|
||||||
printOption("chronosProcShell", chronosProcShell)
|
printOption("chronosProcShell", chronosProcShell)
|
||||||
|
printOption("chronosEventEngine", chronosEventEngine)
|
||||||
|
printOption("chronosEventsCount", chronosEventsCount)
|
||||||
|
printOption("chronosInitialSize", chronosInitialSize)
|
||||||
|
|
|
@ -97,12 +97,12 @@ proc new*(t: typedesc[Selector], T: typedesc): SelectResult[Selector[T]] =
|
||||||
var nmask: Sigset
|
var nmask: Sigset
|
||||||
if sigemptyset(nmask) < 0:
|
if sigemptyset(nmask) < 0:
|
||||||
return err(osLastError())
|
return err(osLastError())
|
||||||
let epollFd = epoll_create(asyncEventsCount)
|
let epollFd = epoll_create(chronosEventsCount)
|
||||||
if epollFd < 0:
|
if epollFd < 0:
|
||||||
return err(osLastError())
|
return err(osLastError())
|
||||||
let selector = Selector[T](
|
let selector = Selector[T](
|
||||||
epollFd: epollFd,
|
epollFd: epollFd,
|
||||||
fds: initTable[int32, SelectorKey[T]](asyncInitialSize),
|
fds: initTable[int32, SelectorKey[T]](chronosInitialSize),
|
||||||
signalMask: nmask,
|
signalMask: nmask,
|
||||||
virtualId: -1'i32, # Should start with -1, because `InvalidIdent` == -1
|
virtualId: -1'i32, # Should start with -1, because `InvalidIdent` == -1
|
||||||
childrenExited: false,
|
childrenExited: false,
|
||||||
|
@ -627,7 +627,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
|
||||||
readyKeys: var openArray[ReadyKey]
|
readyKeys: var openArray[ReadyKey]
|
||||||
): SelectResult[int] =
|
): SelectResult[int] =
|
||||||
var
|
var
|
||||||
queueEvents: array[asyncEventsCount, EpollEvent]
|
queueEvents: array[chronosEventsCount, EpollEvent]
|
||||||
k: int = 0
|
k: int = 0
|
||||||
|
|
||||||
verifySelectParams(timeout, -1, int(high(cint)))
|
verifySelectParams(timeout, -1, int(high(cint)))
|
||||||
|
@ -668,7 +668,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
|
||||||
ok(k)
|
ok(k)
|
||||||
|
|
||||||
proc select2*[T](s: Selector[T], timeout: int): SelectResult[seq[ReadyKey]] =
|
proc select2*[T](s: Selector[T], timeout: int): SelectResult[seq[ReadyKey]] =
|
||||||
var res = newSeq[ReadyKey](asyncEventsCount)
|
var res = newSeq[ReadyKey](chronosEventsCount)
|
||||||
let count = ? selectInto2(s, timeout, res)
|
let count = ? selectInto2(s, timeout, res)
|
||||||
res.setLen(count)
|
res.setLen(count)
|
||||||
ok(res)
|
ok(res)
|
||||||
|
|
|
@ -110,7 +110,7 @@ proc new*(t: typedesc[Selector], T: typedesc): SelectResult[Selector[T]] =
|
||||||
|
|
||||||
let selector = Selector[T](
|
let selector = Selector[T](
|
||||||
kqFd: kqFd,
|
kqFd: kqFd,
|
||||||
fds: initTable[int32, SelectorKey[T]](asyncInitialSize),
|
fds: initTable[int32, SelectorKey[T]](chronosInitialSize),
|
||||||
virtualId: -1'i32, # Should start with -1, because `InvalidIdent` == -1
|
virtualId: -1'i32, # Should start with -1, because `InvalidIdent` == -1
|
||||||
virtualHoles: initDeque[int32]()
|
virtualHoles: initDeque[int32]()
|
||||||
)
|
)
|
||||||
|
@ -559,7 +559,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
|
||||||
): SelectResult[int] =
|
): SelectResult[int] =
|
||||||
var
|
var
|
||||||
tv: Timespec
|
tv: Timespec
|
||||||
queueEvents: array[asyncEventsCount, KEvent]
|
queueEvents: array[chronosEventsCount, KEvent]
|
||||||
|
|
||||||
verifySelectParams(timeout, -1, high(int))
|
verifySelectParams(timeout, -1, high(int))
|
||||||
|
|
||||||
|
@ -575,7 +575,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
|
||||||
addr tv
|
addr tv
|
||||||
else:
|
else:
|
||||||
nil
|
nil
|
||||||
maxEventsCount = cint(min(asyncEventsCount, len(readyKeys)))
|
maxEventsCount = cint(min(chronosEventsCount, len(readyKeys)))
|
||||||
eventsCount =
|
eventsCount =
|
||||||
block:
|
block:
|
||||||
var res = 0
|
var res = 0
|
||||||
|
@ -601,7 +601,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
|
||||||
|
|
||||||
proc select2*[T](s: Selector[T],
|
proc select2*[T](s: Selector[T],
|
||||||
timeout: int): Result[seq[ReadyKey], OSErrorCode] =
|
timeout: int): Result[seq[ReadyKey], OSErrorCode] =
|
||||||
var res = newSeq[ReadyKey](asyncEventsCount)
|
var res = newSeq[ReadyKey](chronosEventsCount)
|
||||||
let count = ? selectInto2(s, timeout, res)
|
let count = ? selectInto2(s, timeout, res)
|
||||||
res.setLen(count)
|
res.setLen(count)
|
||||||
ok(res)
|
ok(res)
|
||||||
|
|
|
@ -16,7 +16,7 @@ import stew/base10
|
||||||
type
|
type
|
||||||
SelectorImpl[T] = object
|
SelectorImpl[T] = object
|
||||||
fds: Table[int32, SelectorKey[T]]
|
fds: Table[int32, SelectorKey[T]]
|
||||||
pollfds: seq[TPollFd]
|
pollfds: seq[TPollfd]
|
||||||
Selector*[T] = ref SelectorImpl[T]
|
Selector*[T] = ref SelectorImpl[T]
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -50,7 +50,7 @@ proc freeKey[T](s: Selector[T], key: int32) =
|
||||||
|
|
||||||
proc new*(t: typedesc[Selector], T: typedesc): SelectResult[Selector[T]] =
|
proc new*(t: typedesc[Selector], T: typedesc): SelectResult[Selector[T]] =
|
||||||
let selector = Selector[T](
|
let selector = Selector[T](
|
||||||
fds: initTable[int32, SelectorKey[T]](asyncInitialSize)
|
fds: initTable[int32, SelectorKey[T]](chronosInitialSize)
|
||||||
)
|
)
|
||||||
ok(selector)
|
ok(selector)
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ proc trigger2*(event: SelectEvent): SelectResult[void] =
|
||||||
if res == -1:
|
if res == -1:
|
||||||
err(osLastError())
|
err(osLastError())
|
||||||
elif res != sizeof(uint64):
|
elif res != sizeof(uint64):
|
||||||
err(OSErrorCode(osdefs.EINVAL))
|
err(osdefs.EINVAL)
|
||||||
else:
|
else:
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
|
@ -98,13 +98,14 @@ template toPollEvents(events: set[Event]): cshort =
|
||||||
res
|
res
|
||||||
|
|
||||||
template pollAdd[T](s: Selector[T], sock: cint, events: set[Event]) =
|
template pollAdd[T](s: Selector[T], sock: cint, events: set[Event]) =
|
||||||
s.pollfds.add(TPollFd(fd: sock, events: toPollEvents(events), revents: 0))
|
s.pollfds.add(TPollfd(fd: sock, events: toPollEvents(events), revents: 0))
|
||||||
|
|
||||||
template pollUpdate[T](s: Selector[T], sock: cint, events: set[Event]) =
|
template pollUpdate[T](s: Selector[T], sock: cint, events: set[Event]) =
|
||||||
var updated = false
|
var updated = false
|
||||||
for mitem in s.pollfds.mitems():
|
for mitem in s.pollfds.mitems():
|
||||||
if mitem.fd == sock:
|
if mitem.fd == sock:
|
||||||
mitem.events = toPollEvents(events)
|
mitem.events = toPollEvents(events)
|
||||||
|
updated = true
|
||||||
break
|
break
|
||||||
if not(updated):
|
if not(updated):
|
||||||
raiseAssert "Descriptor [" & $sock & "] is not registered in the queue!"
|
raiseAssert "Descriptor [" & $sock & "] is not registered in the queue!"
|
||||||
|
@ -177,7 +178,6 @@ proc unregister2*[T](s: Selector[T], event: SelectEvent): SelectResult[void] =
|
||||||
|
|
||||||
proc prepareKey[T](s: Selector[T], event: var TPollfd): Opt[ReadyKey] =
|
proc prepareKey[T](s: Selector[T], event: var TPollfd): Opt[ReadyKey] =
|
||||||
let
|
let
|
||||||
defaultKey = SelectorKey[T](ident: InvalidIdent)
|
|
||||||
fdi32 = int32(event.fd)
|
fdi32 = int32(event.fd)
|
||||||
revents = event.revents
|
revents = event.revents
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
|
||||||
eventsCount =
|
eventsCount =
|
||||||
if maxEventsCount > 0:
|
if maxEventsCount > 0:
|
||||||
let res = handleEintr(poll(addr(s.pollfds[0]), Tnfds(maxEventsCount),
|
let res = handleEintr(poll(addr(s.pollfds[0]), Tnfds(maxEventsCount),
|
||||||
timeout))
|
cint(timeout)))
|
||||||
if res < 0:
|
if res < 0:
|
||||||
return err(osLastError())
|
return err(osLastError())
|
||||||
res
|
res
|
||||||
|
@ -241,7 +241,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
|
||||||
ok(k)
|
ok(k)
|
||||||
|
|
||||||
proc select2*[T](s: Selector[T], timeout: int): SelectResult[seq[ReadyKey]] =
|
proc select2*[T](s: Selector[T], timeout: int): SelectResult[seq[ReadyKey]] =
|
||||||
var res = newSeq[ReadyKey](asyncEventsCount)
|
var res = newSeq[ReadyKey](chronosEventsCount)
|
||||||
let count = ? selectInto2(s, timeout, res)
|
let count = ? selectInto2(s, timeout, res)
|
||||||
res.setLen(count)
|
res.setLen(count)
|
||||||
ok(res)
|
ok(res)
|
||||||
|
|
|
@ -880,7 +880,7 @@ elif defined(macos) or defined(macosx):
|
||||||
sigemptyset, sigaddset, sigismember, fcntl, accept,
|
sigemptyset, sigaddset, sigismember, fcntl, accept,
|
||||||
pipe, write, signal, read, setsockopt, getsockopt,
|
pipe, write, signal, read, setsockopt, getsockopt,
|
||||||
getcwd, chdir, waitpid, kill, select, pselect,
|
getcwd, chdir, waitpid, kill, select, pselect,
|
||||||
socketpair, freeAddrInfo,
|
socketpair, poll, freeAddrInfo,
|
||||||
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
|
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
|
||||||
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
|
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
|
||||||
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
|
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
|
||||||
|
@ -905,7 +905,7 @@ elif defined(macos) or defined(macosx):
|
||||||
sigemptyset, sigaddset, sigismember, fcntl, accept,
|
sigemptyset, sigaddset, sigismember, fcntl, accept,
|
||||||
pipe, write, signal, read, setsockopt, getsockopt,
|
pipe, write, signal, read, setsockopt, getsockopt,
|
||||||
getcwd, chdir, waitpid, kill, select, pselect,
|
getcwd, chdir, waitpid, kill, select, pselect,
|
||||||
socketpair, freeAddrInfo,
|
socketpair, poll, freeAddrInfo,
|
||||||
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
|
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
|
||||||
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
|
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
|
||||||
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
|
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
|
||||||
|
@ -929,6 +929,21 @@ elif defined(macos) or defined(macosx):
|
||||||
numer*: uint32
|
numer*: uint32
|
||||||
denom*: uint32
|
denom*: uint32
|
||||||
|
|
||||||
|
TPollfd* {.importc: "struct pollfd", pure, final,
|
||||||
|
header: "<poll.h>".} = object
|
||||||
|
fd*: cint
|
||||||
|
events*: cshort
|
||||||
|
revents*: cshort
|
||||||
|
|
||||||
|
Tnfds* {.importc: "nfds_t", header: "<poll.h>".} = cuint
|
||||||
|
|
||||||
|
const
|
||||||
|
POLLIN* = 0x0001
|
||||||
|
POLLOUT* = 0x0004
|
||||||
|
POLLERR* = 0x0008
|
||||||
|
POLLHUP* = 0x0010
|
||||||
|
POLLNVAL* = 0x0020
|
||||||
|
|
||||||
proc posix_gettimeofday*(tp: var Timeval, unused: pointer = nil) {.
|
proc posix_gettimeofday*(tp: var Timeval, unused: pointer = nil) {.
|
||||||
importc: "gettimeofday", header: "<sys/time.h>".}
|
importc: "gettimeofday", header: "<sys/time.h>".}
|
||||||
|
|
||||||
|
@ -938,6 +953,9 @@ elif defined(macos) or defined(macosx):
|
||||||
proc mach_absolute_time*(): uint64 {.
|
proc mach_absolute_time*(): uint64 {.
|
||||||
importc, header: "<mach/mach_time.h>".}
|
importc, header: "<mach/mach_time.h>".}
|
||||||
|
|
||||||
|
proc poll*(a1: ptr TPollfd, a2: Tnfds, a3: cint): cint {.
|
||||||
|
importc, header: "<poll.h>", sideEffect.}
|
||||||
|
|
||||||
elif defined(linux):
|
elif defined(linux):
|
||||||
from std/posix import close, shutdown, sigemptyset, sigaddset, sigismember,
|
from std/posix import close, shutdown, sigemptyset, sigaddset, sigismember,
|
||||||
sigdelset, write, read, waitid, getaddrinfo,
|
sigdelset, write, read, waitid, getaddrinfo,
|
||||||
|
@ -947,12 +965,12 @@ elif defined(linux):
|
||||||
unlink, listen, sendmsg, recvmsg, getpid, fcntl,
|
unlink, listen, sendmsg, recvmsg, getpid, fcntl,
|
||||||
pthread_sigmask, sigprocmask, clock_gettime, signal,
|
pthread_sigmask, sigprocmask, clock_gettime, signal,
|
||||||
getcwd, chdir, waitpid, kill, select, pselect,
|
getcwd, chdir, waitpid, kill, select, pselect,
|
||||||
socketpair, freeAddrInfo,
|
socketpair, poll, freeAddrInfo,
|
||||||
ClockId, Itimerspec, Timespec, Sigset, Time, Pid, Mode,
|
ClockId, Itimerspec, Timespec, Sigset, Time, Pid, Mode,
|
||||||
SigInfo, Id, Tmsghdr, IOVec, RLimit, Timeval, TFdSet,
|
SigInfo, Id, Tmsghdr, IOVec, RLimit, Timeval, TFdSet,
|
||||||
SockAddr, SockLen, Sockaddr_storage, Sockaddr_in,
|
SockAddr, SockLen, Sockaddr_storage, Sockaddr_in,
|
||||||
Sockaddr_in6, Sockaddr_un, AddrInfo, SocketHandle,
|
Sockaddr_in6, Sockaddr_un, AddrInfo, SocketHandle,
|
||||||
Suseconds,
|
Suseconds, TPollfd, Tnfds,
|
||||||
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
|
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
|
||||||
CLOCK_MONOTONIC, F_GETFL, F_SETFL, F_GETFD, F_SETFD,
|
CLOCK_MONOTONIC, F_GETFL, F_SETFL, F_GETFD, F_SETFD,
|
||||||
FD_CLOEXEC, O_NONBLOCK, SIG_BLOCK, SIG_UNBLOCK,
|
FD_CLOEXEC, O_NONBLOCK, SIG_BLOCK, SIG_UNBLOCK,
|
||||||
|
@ -961,6 +979,7 @@ elif defined(linux):
|
||||||
AF_INET, AF_INET6, AF_UNIX, SO_REUSEADDR, SO_REUSEPORT,
|
AF_INET, AF_INET6, AF_UNIX, SO_REUSEADDR, SO_REUSEPORT,
|
||||||
SO_BROADCAST, IPPROTO_IP, IPV6_MULTICAST_HOPS,
|
SO_BROADCAST, IPPROTO_IP, IPV6_MULTICAST_HOPS,
|
||||||
SOCK_DGRAM, SOCK_STREAM, SHUT_RD, SHUT_WR, SHUT_RDWR,
|
SOCK_DGRAM, SOCK_STREAM, SHUT_RD, SHUT_WR, SHUT_RDWR,
|
||||||
|
POLLIN, POLLOUT, POLLERR, POLLHUP, POLLNVAL,
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
|
||||||
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
||||||
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE, SIGCHLD, SIGSTOP,
|
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE, SIGCHLD, SIGSTOP,
|
||||||
|
@ -974,12 +993,12 @@ elif defined(linux):
|
||||||
unlink, listen, sendmsg, recvmsg, getpid, fcntl,
|
unlink, listen, sendmsg, recvmsg, getpid, fcntl,
|
||||||
pthread_sigmask, sigprocmask, clock_gettime, signal,
|
pthread_sigmask, sigprocmask, clock_gettime, signal,
|
||||||
getcwd, chdir, waitpid, kill, select, pselect,
|
getcwd, chdir, waitpid, kill, select, pselect,
|
||||||
socketpair, freeAddrInfo,
|
socketpair, poll, freeAddrInfo,
|
||||||
ClockId, Itimerspec, Timespec, Sigset, Time, Pid, Mode,
|
ClockId, Itimerspec, Timespec, Sigset, Time, Pid, Mode,
|
||||||
SigInfo, Id, Tmsghdr, IOVec, RLimit, TFdSet, Timeval,
|
SigInfo, Id, Tmsghdr, IOVec, RLimit, TFdSet, Timeval,
|
||||||
SockAddr, SockLen, Sockaddr_storage, Sockaddr_in,
|
SockAddr, SockLen, Sockaddr_storage, Sockaddr_in,
|
||||||
Sockaddr_in6, Sockaddr_un, AddrInfo, SocketHandle,
|
Sockaddr_in6, Sockaddr_un, AddrInfo, SocketHandle,
|
||||||
Suseconds,
|
Suseconds, TPollfd, Tnfds,
|
||||||
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
|
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
|
||||||
CLOCK_MONOTONIC, F_GETFL, F_SETFL, F_GETFD, F_SETFD,
|
CLOCK_MONOTONIC, F_GETFL, F_SETFL, F_GETFD, F_SETFD,
|
||||||
FD_CLOEXEC, O_NONBLOCK, SIG_BLOCK, SIG_UNBLOCK,
|
FD_CLOEXEC, O_NONBLOCK, SIG_BLOCK, SIG_UNBLOCK,
|
||||||
|
@ -988,6 +1007,7 @@ elif defined(linux):
|
||||||
AF_INET, AF_INET6, AF_UNIX, SO_REUSEADDR, SO_REUSEPORT,
|
AF_INET, AF_INET6, AF_UNIX, SO_REUSEADDR, SO_REUSEPORT,
|
||||||
SO_BROADCAST, IPPROTO_IP, IPV6_MULTICAST_HOPS,
|
SO_BROADCAST, IPPROTO_IP, IPV6_MULTICAST_HOPS,
|
||||||
SOCK_DGRAM, SOCK_STREAM, SHUT_RD, SHUT_WR, SHUT_RDWR,
|
SOCK_DGRAM, SOCK_STREAM, SHUT_RD, SHUT_WR, SHUT_RDWR,
|
||||||
|
POLLIN, POLLOUT, POLLERR, POLLHUP, POLLNVAL,
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
|
||||||
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
||||||
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE, SIGCHLD, SIGSTOP,
|
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE, SIGCHLD, SIGSTOP,
|
||||||
|
@ -1097,11 +1117,11 @@ elif defined(freebsd) or defined(openbsd) or defined(netbsd) or
|
||||||
sigaddset, sigismember, fcntl, accept, pipe, write,
|
sigaddset, sigismember, fcntl, accept, pipe, write,
|
||||||
signal, read, setsockopt, getsockopt, clock_gettime,
|
signal, read, setsockopt, getsockopt, clock_gettime,
|
||||||
getcwd, chdir, waitpid, kill, select, pselect,
|
getcwd, chdir, waitpid, kill, select, pselect,
|
||||||
socketpair, freeAddrInfo,
|
socketpair, poll, freeAddrInfo,
|
||||||
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
|
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
|
||||||
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
|
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
|
||||||
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
|
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
|
||||||
Suseconds,
|
Suseconds, TPollfd, Tnfds,
|
||||||
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
|
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
|
||||||
F_GETFL, F_SETFL, F_GETFD, F_SETFD, FD_CLOEXEC,
|
F_GETFL, F_SETFL, F_GETFD, F_SETFD, FD_CLOEXEC,
|
||||||
O_NONBLOCK, SOL_SOCKET, SOCK_RAW, SOCK_DGRAM,
|
O_NONBLOCK, SOL_SOCKET, SOCK_RAW, SOCK_DGRAM,
|
||||||
|
@ -1111,6 +1131,7 @@ elif defined(freebsd) or defined(openbsd) or defined(netbsd) or
|
||||||
IPV6_MULTICAST_HOPS, SOCK_DGRAM, RLIMIT_NOFILE,
|
IPV6_MULTICAST_HOPS, SOCK_DGRAM, RLIMIT_NOFILE,
|
||||||
SIG_BLOCK, SIG_UNBLOCK, CLOCK_MONOTONIC,
|
SIG_BLOCK, SIG_UNBLOCK, CLOCK_MONOTONIC,
|
||||||
SHUT_RD, SHUT_WR, SHUT_RDWR,
|
SHUT_RD, SHUT_WR, SHUT_RDWR,
|
||||||
|
POLLIN, POLLOUT, POLLERR, POLLHUP, POLLNVAL,
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
|
||||||
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
||||||
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE, SIGCHLD, SIGSTOP,
|
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE, SIGCHLD, SIGSTOP,
|
||||||
|
@ -1123,11 +1144,11 @@ elif defined(freebsd) or defined(openbsd) or defined(netbsd) or
|
||||||
sigaddset, sigismember, fcntl, accept, pipe, write,
|
sigaddset, sigismember, fcntl, accept, pipe, write,
|
||||||
signal, read, setsockopt, getsockopt, clock_gettime,
|
signal, read, setsockopt, getsockopt, clock_gettime,
|
||||||
getcwd, chdir, waitpid, kill, select, pselect,
|
getcwd, chdir, waitpid, kill, select, pselect,
|
||||||
socketpair, freeAddrInfo,
|
socketpair, poll, freeAddrInfo,
|
||||||
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
|
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
|
||||||
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
|
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
|
||||||
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
|
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
|
||||||
Suseconds,
|
Suseconds, TPollfd, Tnfds,
|
||||||
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
|
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
|
||||||
F_GETFL, F_SETFL, F_GETFD, F_SETFD, FD_CLOEXEC,
|
F_GETFL, F_SETFL, F_GETFD, F_SETFD, FD_CLOEXEC,
|
||||||
O_NONBLOCK, SOL_SOCKET, SOCK_RAW, SOCK_DGRAM,
|
O_NONBLOCK, SOL_SOCKET, SOCK_RAW, SOCK_DGRAM,
|
||||||
|
@ -1137,6 +1158,7 @@ elif defined(freebsd) or defined(openbsd) or defined(netbsd) or
|
||||||
IPV6_MULTICAST_HOPS, SOCK_DGRAM, RLIMIT_NOFILE,
|
IPV6_MULTICAST_HOPS, SOCK_DGRAM, RLIMIT_NOFILE,
|
||||||
SIG_BLOCK, SIG_UNBLOCK, CLOCK_MONOTONIC,
|
SIG_BLOCK, SIG_UNBLOCK, CLOCK_MONOTONIC,
|
||||||
SHUT_RD, SHUT_WR, SHUT_RDWR,
|
SHUT_RD, SHUT_WR, SHUT_RDWR,
|
||||||
|
POLLIN, POLLOUT, POLLERR, POLLHUP, POLLNVAL,
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
|
||||||
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
|
||||||
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE, SIGCHLD, SIGSTOP,
|
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE, SIGCHLD, SIGSTOP,
|
||||||
|
|
|
@ -32,29 +32,9 @@
|
||||||
# backwards-compatible.
|
# backwards-compatible.
|
||||||
|
|
||||||
import stew/results
|
import stew/results
|
||||||
import osdefs, osutils, oserrno
|
import config, osdefs, osutils, oserrno
|
||||||
export results, oserrno
|
export results, oserrno
|
||||||
|
|
||||||
const
|
|
||||||
asyncEventsCount* {.intdefine.} = 64
|
|
||||||
## Number of epoll events retrieved by syscall.
|
|
||||||
asyncInitialSize* {.intdefine.} = 64
|
|
||||||
## Initial size of Selector[T]'s array of file descriptors.
|
|
||||||
asyncEventEngine* {.strdefine.} =
|
|
||||||
when defined(linux):
|
|
||||||
"epoll"
|
|
||||||
elif defined(macosx) or defined(macos) or defined(ios) or
|
|
||||||
defined(freebsd) or defined(netbsd) or defined(openbsd) or
|
|
||||||
defined(dragonfly):
|
|
||||||
"kqueue"
|
|
||||||
elif defined(posix):
|
|
||||||
"poll"
|
|
||||||
else:
|
|
||||||
""
|
|
||||||
## Engine type which is going to be used by module.
|
|
||||||
|
|
||||||
hasThreadSupport = compileOption("threads")
|
|
||||||
|
|
||||||
when defined(nimdoc):
|
when defined(nimdoc):
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -281,7 +261,9 @@ else:
|
||||||
var err = newException(IOSelectorsException, msg)
|
var err = newException(IOSelectorsException, msg)
|
||||||
raise err
|
raise err
|
||||||
|
|
||||||
when asyncEventEngine in ["epoll", "kqueue"]:
|
when chronosEventEngine in ["epoll", "kqueue"]:
|
||||||
|
const hasThreadSupport = compileOption("threads")
|
||||||
|
|
||||||
proc blockSignals(newmask: Sigset,
|
proc blockSignals(newmask: Sigset,
|
||||||
oldmask: var Sigset): Result[void, OSErrorCode] =
|
oldmask: var Sigset): Result[void, OSErrorCode] =
|
||||||
var nmask = newmask
|
var nmask = newmask
|
||||||
|
@ -324,11 +306,11 @@ else:
|
||||||
doAssert((timeout >= min) and (timeout <= max),
|
doAssert((timeout >= min) and (timeout <= max),
|
||||||
"Cannot select with incorrect timeout value, got " & $timeout)
|
"Cannot select with incorrect timeout value, got " & $timeout)
|
||||||
|
|
||||||
when asyncEventEngine == "epoll":
|
when chronosEventEngine == "epoll":
|
||||||
include ./ioselects/ioselectors_epoll
|
include ./ioselects/ioselectors_epoll
|
||||||
elif asyncEventEngine == "kqueue":
|
elif chronosEventEngine == "kqueue":
|
||||||
include ./ioselects/ioselectors_kqueue
|
include ./ioselects/ioselectors_kqueue
|
||||||
elif asyncEventEngine == "poll":
|
elif chronosEventEngine == "poll":
|
||||||
include ./ioselects/ioselectors_poll
|
include ./ioselects/ioselectors_poll
|
||||||
else:
|
else:
|
||||||
{.fatal: "Event engine `" & asyncEventEngine & "` is not supported!".}
|
{.fatal: "Event engine `" & chronosEventEngine & "` is not supported!".}
|
||||||
|
|
|
@ -38,8 +38,12 @@ when defined(nimdoc):
|
||||||
## be prepared to retry the call if there were unsent bytes.
|
## be prepared to retry the call if there were unsent bytes.
|
||||||
##
|
##
|
||||||
## On error, ``-1`` is returned.
|
## On error, ``-1`` is returned.
|
||||||
|
elif defined(emscripten):
|
||||||
|
|
||||||
elif defined(linux) or defined(android):
|
proc sendfile*(outfd, infd: int, offset: int, count: var int): int =
|
||||||
|
raiseAssert "sendfile() is not implemented yet"
|
||||||
|
|
||||||
|
elif (defined(linux) or defined(android)) and not(defined(emscripten)):
|
||||||
|
|
||||||
proc osSendFile*(outfd, infd: cint, offset: ptr int, count: int): int
|
proc osSendFile*(outfd, infd: cint, offset: ptr int, count: int): int
|
||||||
{.importc: "sendfile", header: "<sys/sendfile.h>".}
|
{.importc: "sendfile", header: "<sys/sendfile.h>".}
|
||||||
|
|
|
@ -5,10 +5,22 @@
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# Apache License, version 2.0, (LICENSE-APACHEv2)
|
# Apache License, version 2.0, (LICENSE-APACHEv2)
|
||||||
# MIT license (LICENSE-MIT)
|
# MIT license (LICENSE-MIT)
|
||||||
import testmacro, testsync, testsoon, testtime, testfut, testsignal,
|
import ".."/chronos/config
|
||||||
testaddress, testdatagram, teststream, testserver, testbugs, testnet,
|
|
||||||
testasyncstream, testhttpserver, testshttpserver, testhttpclient,
|
|
||||||
testproc, testratelimit, testfutures, testthreadsync
|
|
||||||
|
|
||||||
# Must be imported last to check for Pending futures
|
when (chronosEventEngine in ["epoll", "kqueue"]) or defined(windows):
|
||||||
import testutils
|
import testmacro, testsync, testsoon, testtime, testfut, testsignal,
|
||||||
|
testaddress, testdatagram, teststream, testserver, testbugs, testnet,
|
||||||
|
testasyncstream, testhttpserver, testshttpserver, testhttpclient,
|
||||||
|
testproc, testratelimit, testfutures, testthreadsync
|
||||||
|
|
||||||
|
# Must be imported last to check for Pending futures
|
||||||
|
import testutils
|
||||||
|
elif chronosEventEngine == "poll":
|
||||||
|
# `poll` engine do not support signals and processes
|
||||||
|
import testmacro, testsync, testsoon, testtime, testfut, testaddress,
|
||||||
|
testdatagram, teststream, testserver, testbugs, testnet,
|
||||||
|
testasyncstream, testhttpserver, testshttpserver, testhttpclient,
|
||||||
|
testratelimit, testfutures, testthreadsync
|
||||||
|
|
||||||
|
# Must be imported last to check for Pending futures
|
||||||
|
import testutils
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import std/os
|
import std/os
|
||||||
import stew/[base10, byteutils]
|
import stew/[base10, byteutils]
|
||||||
import ".."/chronos/unittest2/asynctests
|
import ".."/chronos/unittest2/asynctests
|
||||||
|
import ".."/chronos/asyncproc
|
||||||
|
|
||||||
when defined(posix):
|
when defined(posix):
|
||||||
from ".."/chronos/osdefs import SIGKILL
|
from ".."/chronos/osdefs import SIGKILL
|
||||||
|
|
|
@ -1339,7 +1339,10 @@ suite "Stream Transport test suite":
|
||||||
else:
|
else:
|
||||||
skip()
|
skip()
|
||||||
else:
|
else:
|
||||||
check waitFor(testSendFile(addresses[i])) == FilesCount
|
if defined(emscripten):
|
||||||
|
skip()
|
||||||
|
else:
|
||||||
|
check waitFor(testSendFile(addresses[i])) == FilesCount
|
||||||
test prefixes[i] & "Connection refused test":
|
test prefixes[i] & "Connection refused test":
|
||||||
var address: TransportAddress
|
var address: TransportAddress
|
||||||
if addresses[i].family == AddressFamily.Unix:
|
if addresses[i].family == AddressFamily.Unix:
|
||||||
|
|
Loading…
Reference in New Issue