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:
Eugene Kabanov 2023-08-01 12:56:08 +03:00 committed by GitHub
parent 5c39bf47be
commit 6b4f5a1d23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 146 additions and 76 deletions

View File

@ -5,6 +5,5 @@
# Licensed under either of
# Apache License, version 2.0, (LICENSE-APACHEv2)
# MIT license (LICENSE-MIT)
import chronos/[asyncloop, asyncsync, handles, transport, timer,
asyncproc, debugutils]
export asyncloop, asyncsync, handles, transport, timer, asyncproc, debugutils
import chronos/[asyncloop, asyncsync, handles, transport, timer, debugutils]
export asyncloop, asyncsync, handles, transport, timer, debugutils

View File

@ -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 flags = getEnv("NIMFLAGS", "") # Extra flags for the compiler
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 cfg =
@ -31,12 +47,7 @@ proc run(args, path: string) =
build args & " -r", path
task test, "Run all tests":
for args in [
"-d:debug -d:chronosDebug",
"-d:debug -d:chronosPreviewV4",
"-d:debug -d:chronosDebug -d:useSysAssert -d:useGcAssert",
"-d:release",
"-d:release -d:chronosPreviewV4"]:
for args in testArguments:
run args, "tests/testall"
if (NimMajor, NimMinor) > (1, 6):
run args & " --mm:refc", "tests/testall"

View File

@ -825,9 +825,9 @@ elif defined(macosx) or defined(freebsd) or defined(netbsd) or
var res = PDispatcher(
selector: selector,
timers: initHeapQueue[TimerCallback](),
callbacks: initDeque[AsyncCallback](asyncEventsCount),
callbacks: initDeque[AsyncCallback](chronosEventsCount),
idlers: initDeque[AsyncCallback](),
keys: newSeq[ReadyKey](asyncEventsCount),
keys: newSeq[ReadyKey](chronosEventsCount),
trackers: initTable[string, TrackerBase](),
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.
closeSocket(fd, aftercb)
when asyncEventEngine in ["epoll", "kqueue"]:
when chronosEventEngine in ["epoll", "kqueue"]:
type
ProcessHandle* = 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):
loop.callbacks.addLast(adata.reader)
when asyncEventEngine in ["epoll", "kqueue"]:
when chronosEventEngine in ["epoll", "kqueue"]:
let customSet = {Event.Timer, Event.Signal, Event.Process,
Event.Vnode}
if customSet * events != {}:
@ -1257,10 +1257,7 @@ proc callIdle*(cbproc: CallbackFunc) =
include asyncfutures2
when defined(macosx) or defined(macos) or defined(freebsd) or
defined(netbsd) or defined(openbsd) or defined(dragonfly) or
defined(linux) or defined(windows):
when (chronosEventEngine in ["epoll", "kqueue"]) or defined(windows):
proc waitSignal*(signal: int): Future[void] {.raises: [].} =
var retFuture = newFuture[void]("chronos.waitSignal()")

View File

@ -49,6 +49,27 @@ when (NimMajor, NimMinor) >= (1, 4):
## using `AsyncProcessOption.EvalCommand` and API calls such as
## ``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:
# 1.2 doesn't support `booldefine` in `when` properly
const
@ -69,6 +90,21 @@ else:
"/system/bin/sh"
else:
"/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):
import std/macros
@ -83,3 +119,6 @@ when defined(debug) or defined(chronosConfig):
printOption("chronosFutureTracking", chronosFutureTracking)
printOption("chronosDumpAsync", chronosDumpAsync)
printOption("chronosProcShell", chronosProcShell)
printOption("chronosEventEngine", chronosEventEngine)
printOption("chronosEventsCount", chronosEventsCount)
printOption("chronosInitialSize", chronosInitialSize)

View File

@ -97,12 +97,12 @@ proc new*(t: typedesc[Selector], T: typedesc): SelectResult[Selector[T]] =
var nmask: Sigset
if sigemptyset(nmask) < 0:
return err(osLastError())
let epollFd = epoll_create(asyncEventsCount)
let epollFd = epoll_create(chronosEventsCount)
if epollFd < 0:
return err(osLastError())
let selector = Selector[T](
epollFd: epollFd,
fds: initTable[int32, SelectorKey[T]](asyncInitialSize),
fds: initTable[int32, SelectorKey[T]](chronosInitialSize),
signalMask: nmask,
virtualId: -1'i32, # Should start with -1, because `InvalidIdent` == -1
childrenExited: false,
@ -627,7 +627,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
readyKeys: var openArray[ReadyKey]
): SelectResult[int] =
var
queueEvents: array[asyncEventsCount, EpollEvent]
queueEvents: array[chronosEventsCount, EpollEvent]
k: int = 0
verifySelectParams(timeout, -1, int(high(cint)))
@ -668,7 +668,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
ok(k)
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)
res.setLen(count)
ok(res)

View File

@ -110,7 +110,7 @@ proc new*(t: typedesc[Selector], T: typedesc): SelectResult[Selector[T]] =
let selector = Selector[T](
kqFd: kqFd,
fds: initTable[int32, SelectorKey[T]](asyncInitialSize),
fds: initTable[int32, SelectorKey[T]](chronosInitialSize),
virtualId: -1'i32, # Should start with -1, because `InvalidIdent` == -1
virtualHoles: initDeque[int32]()
)
@ -559,7 +559,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
): SelectResult[int] =
var
tv: Timespec
queueEvents: array[asyncEventsCount, KEvent]
queueEvents: array[chronosEventsCount, KEvent]
verifySelectParams(timeout, -1, high(int))
@ -575,7 +575,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
addr tv
else:
nil
maxEventsCount = cint(min(asyncEventsCount, len(readyKeys)))
maxEventsCount = cint(min(chronosEventsCount, len(readyKeys)))
eventsCount =
block:
var res = 0
@ -601,7 +601,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
proc select2*[T](s: Selector[T],
timeout: int): Result[seq[ReadyKey], OSErrorCode] =
var res = newSeq[ReadyKey](asyncEventsCount)
var res = newSeq[ReadyKey](chronosEventsCount)
let count = ? selectInto2(s, timeout, res)
res.setLen(count)
ok(res)

View File

@ -16,7 +16,7 @@ import stew/base10
type
SelectorImpl[T] = object
fds: Table[int32, SelectorKey[T]]
pollfds: seq[TPollFd]
pollfds: seq[TPollfd]
Selector*[T] = ref SelectorImpl[T]
type
@ -50,7 +50,7 @@ proc freeKey[T](s: Selector[T], key: int32) =
proc new*(t: typedesc[Selector], T: typedesc): SelectResult[Selector[T]] =
let selector = Selector[T](
fds: initTable[int32, SelectorKey[T]](asyncInitialSize)
fds: initTable[int32, SelectorKey[T]](chronosInitialSize)
)
ok(selector)
@ -72,7 +72,7 @@ proc trigger2*(event: SelectEvent): SelectResult[void] =
if res == -1:
err(osLastError())
elif res != sizeof(uint64):
err(OSErrorCode(osdefs.EINVAL))
err(osdefs.EINVAL)
else:
ok()
@ -98,13 +98,14 @@ template toPollEvents(events: set[Event]): cshort =
res
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]) =
var updated = false
for mitem in s.pollfds.mitems():
if mitem.fd == sock:
mitem.events = toPollEvents(events)
updated = true
break
if not(updated):
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] =
let
defaultKey = SelectorKey[T](ident: InvalidIdent)
fdi32 = int32(event.fd)
revents = event.revents
@ -224,7 +224,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
eventsCount =
if maxEventsCount > 0:
let res = handleEintr(poll(addr(s.pollfds[0]), Tnfds(maxEventsCount),
timeout))
cint(timeout)))
if res < 0:
return err(osLastError())
res
@ -241,7 +241,7 @@ proc selectInto2*[T](s: Selector[T], timeout: int,
ok(k)
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)
res.setLen(count)
ok(res)

View File

@ -880,7 +880,7 @@ elif defined(macos) or defined(macosx):
sigemptyset, sigaddset, sigismember, fcntl, accept,
pipe, write, signal, read, setsockopt, getsockopt,
getcwd, chdir, waitpid, kill, select, pselect,
socketpair, freeAddrInfo,
socketpair, poll, freeAddrInfo,
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
@ -905,7 +905,7 @@ elif defined(macos) or defined(macosx):
sigemptyset, sigaddset, sigismember, fcntl, accept,
pipe, write, signal, read, setsockopt, getsockopt,
getcwd, chdir, waitpid, kill, select, pselect,
socketpair, freeAddrInfo,
socketpair, poll, freeAddrInfo,
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
@ -929,6 +929,21 @@ elif defined(macos) or defined(macosx):
numer*: 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) {.
importc: "gettimeofday", header: "<sys/time.h>".}
@ -938,6 +953,9 @@ elif defined(macos) or defined(macosx):
proc mach_absolute_time*(): uint64 {.
importc, header: "<mach/mach_time.h>".}
proc poll*(a1: ptr TPollfd, a2: Tnfds, a3: cint): cint {.
importc, header: "<poll.h>", sideEffect.}
elif defined(linux):
from std/posix import close, shutdown, sigemptyset, sigaddset, sigismember,
sigdelset, write, read, waitid, getaddrinfo,
@ -947,12 +965,12 @@ elif defined(linux):
unlink, listen, sendmsg, recvmsg, getpid, fcntl,
pthread_sigmask, sigprocmask, clock_gettime, signal,
getcwd, chdir, waitpid, kill, select, pselect,
socketpair, freeAddrInfo,
socketpair, poll, freeAddrInfo,
ClockId, Itimerspec, Timespec, Sigset, Time, Pid, Mode,
SigInfo, Id, Tmsghdr, IOVec, RLimit, Timeval, TFdSet,
SockAddr, SockLen, Sockaddr_storage, Sockaddr_in,
Sockaddr_in6, Sockaddr_un, AddrInfo, SocketHandle,
Suseconds,
Suseconds, TPollfd, Tnfds,
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
CLOCK_MONOTONIC, F_GETFL, F_SETFL, F_GETFD, F_SETFD,
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,
SO_BROADCAST, IPPROTO_IP, IPV6_MULTICAST_HOPS,
SOCK_DGRAM, SOCK_STREAM, SHUT_RD, SHUT_WR, SHUT_RDWR,
POLLIN, POLLOUT, POLLERR, POLLHUP, POLLNVAL,
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE, SIGCHLD, SIGSTOP,
@ -974,12 +993,12 @@ elif defined(linux):
unlink, listen, sendmsg, recvmsg, getpid, fcntl,
pthread_sigmask, sigprocmask, clock_gettime, signal,
getcwd, chdir, waitpid, kill, select, pselect,
socketpair, freeAddrInfo,
socketpair, poll, freeAddrInfo,
ClockId, Itimerspec, Timespec, Sigset, Time, Pid, Mode,
SigInfo, Id, Tmsghdr, IOVec, RLimit, TFdSet, Timeval,
SockAddr, SockLen, Sockaddr_storage, Sockaddr_in,
Sockaddr_in6, Sockaddr_un, AddrInfo, SocketHandle,
Suseconds,
Suseconds, TPollfd, Tnfds,
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
CLOCK_MONOTONIC, F_GETFL, F_SETFL, F_GETFD, F_SETFD,
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,
SO_BROADCAST, IPPROTO_IP, IPV6_MULTICAST_HOPS,
SOCK_DGRAM, SOCK_STREAM, SHUT_RD, SHUT_WR, SHUT_RDWR,
POLLIN, POLLOUT, POLLERR, POLLHUP, POLLNVAL,
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
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,
signal, read, setsockopt, getsockopt, clock_gettime,
getcwd, chdir, waitpid, kill, select, pselect,
socketpair, freeAddrInfo,
socketpair, poll, freeAddrInfo,
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
Suseconds,
Suseconds, TPollfd, Tnfds,
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
F_GETFL, F_SETFL, F_GETFD, F_SETFD, FD_CLOEXEC,
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,
SIG_BLOCK, SIG_UNBLOCK, CLOCK_MONOTONIC,
SHUT_RD, SHUT_WR, SHUT_RDWR,
POLLIN, POLLOUT, POLLERR, POLLHUP, POLLNVAL,
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
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,
signal, read, setsockopt, getsockopt, clock_gettime,
getcwd, chdir, waitpid, kill, select, pselect,
socketpair, freeAddrInfo,
socketpair, poll, freeAddrInfo,
Timeval, Timespec, Pid, Mode, Time, Sigset, SockAddr,
SockLen, Sockaddr_storage, Sockaddr_in, Sockaddr_in6,
Sockaddr_un, SocketHandle, AddrInfo, RLimit, TFdSet,
Suseconds,
Suseconds, TPollfd, Tnfds,
FD_CLR, FD_ISSET, FD_SET, FD_ZERO,
F_GETFL, F_SETFL, F_GETFD, F_SETFD, FD_CLOEXEC,
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,
SIG_BLOCK, SIG_UNBLOCK, CLOCK_MONOTONIC,
SHUT_RD, SHUT_WR, SHUT_RDWR,
POLLIN, POLLOUT, POLLERR, POLLHUP, POLLNVAL,
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
SIGPIPE, SIGALRM, SIGTERM, SIGPIPE, SIGCHLD, SIGSTOP,

View File

@ -32,29 +32,9 @@
# backwards-compatible.
import stew/results
import osdefs, osutils, oserrno
import config, osdefs, osutils, 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):
type
@ -281,7 +261,9 @@ else:
var err = newException(IOSelectorsException, msg)
raise err
when asyncEventEngine in ["epoll", "kqueue"]:
when chronosEventEngine in ["epoll", "kqueue"]:
const hasThreadSupport = compileOption("threads")
proc blockSignals(newmask: Sigset,
oldmask: var Sigset): Result[void, OSErrorCode] =
var nmask = newmask
@ -324,11 +306,11 @@ else:
doAssert((timeout >= min) and (timeout <= max),
"Cannot select with incorrect timeout value, got " & $timeout)
when asyncEventEngine == "epoll":
when chronosEventEngine == "epoll":
include ./ioselects/ioselectors_epoll
elif asyncEventEngine == "kqueue":
elif chronosEventEngine == "kqueue":
include ./ioselects/ioselectors_kqueue
elif asyncEventEngine == "poll":
elif chronosEventEngine == "poll":
include ./ioselects/ioselectors_poll
else:
{.fatal: "Event engine `" & asyncEventEngine & "` is not supported!".}
{.fatal: "Event engine `" & chronosEventEngine & "` is not supported!".}

View File

@ -38,8 +38,12 @@ when defined(nimdoc):
## be prepared to retry the call if there were unsent bytes.
##
## 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
{.importc: "sendfile", header: "<sys/sendfile.h>".}

View File

@ -5,10 +5,22 @@
# Licensed under either of
# Apache License, version 2.0, (LICENSE-APACHEv2)
# MIT license (LICENSE-MIT)
import testmacro, testsync, testsoon, testtime, testfut, testsignal,
testaddress, testdatagram, teststream, testserver, testbugs, testnet,
testasyncstream, testhttpserver, testshttpserver, testhttpclient,
testproc, testratelimit, testfutures, testthreadsync
import ".."/chronos/config
# Must be imported last to check for Pending futures
import testutils
when (chronosEventEngine in ["epoll", "kqueue"]) or defined(windows):
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

View File

@ -8,6 +8,7 @@
import std/os
import stew/[base10, byteutils]
import ".."/chronos/unittest2/asynctests
import ".."/chronos/asyncproc
when defined(posix):
from ".."/chronos/osdefs import SIGKILL

View File

@ -1339,7 +1339,10 @@ suite "Stream Transport test suite":
else:
skip()
else:
check waitFor(testSendFile(addresses[i])) == FilesCount
if defined(emscripten):
skip()
else:
check waitFor(testSendFile(addresses[i])) == FilesCount
test prefixes[i] & "Connection refused test":
var address: TransportAddress
if addresses[i].family == AddressFamily.Unix: