diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2022-08-24 00:58:08 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-23 18:58:08 +0200 |
commit | 2b8f0a797149329158f8874067e18badd54dd76a (patch) | |
tree | ad159aef7370a29843a4b53f8eb75b7332f3b766 | |
parent | 9753dd0a1bd4a9993941dcd1e39d930bd2bb8bf0 (diff) | |
download | Nim-2b8f0a797149329158f8874067e18badd54dd76a.tar.gz |
fixes #19973; switch to poll on posix (#20212)
* fixes #19973; switch to poll on posix * it is fd * exclude lwip * fixes lwip * rename select to timeoutRead * refactor into timeoutRead/timeoutWrite * refactor common parts Co-authored-by: xflywind <43030857+xflywind@users.noreply.github.com>
-rw-r--r-- | lib/pure/net.nim | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 7b50b8ba6..f18e64463 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -203,6 +203,30 @@ type when defined(nimHasStyleChecks): {.pop.} + +when defined(posix) and not defined(lwip): + from posix import TPollfd, POLLIN, POLLPRI, POLLOUT, POLLWRBAND, Tnfds + + template monitorPollEvent(x: var SocketHandle, y: cint, timeout: int): int = + var tpollfd: TPollfd + tpollfd.fd = cast[cint](x) + tpollfd.events = y + posix.poll(addr(tpollfd), Tnfds(1), timeout) + +proc timeoutRead(fd: var SocketHandle, timeout = 500): int = + when defined(windows) or defined(lwip): + var fds = @[fd] + selectRead(fds, timeout) + else: + monitorPollEvent(fd, POLLIN or POLLPRI, timeout) + +proc timeoutWrite(fd: var SocketHandle, timeout = 500): int = + when defined(windows) or defined(lwip): + var fds = @[fd] + selectWrite(fds, timeout) + else: + monitorPollEvent(fd, POLLOUT or POLLWRBAND, timeout) + proc socketError*(socket: Socket, err: int = -1, async = false, lastError = (-1).OSErrorCode, flags: set[SocketFlag] = {}) {.gcsafe.} @@ -1308,14 +1332,6 @@ proc hasDataBuffered*(s: Socket): bool = if s.isSsl and not result: result = s.sslHasPeekChar -proc select(readfd: Socket, timeout = 500): int = - ## Used for socket operation timeouts. - if readfd.hasDataBuffered: - return 1 - - var fds = @[readfd.fd] - result = selectRead(fds, timeout) - proc isClosed(socket: Socket): bool = socket.fd == osInvalidSocket @@ -1429,7 +1445,9 @@ proc waitFor(socket: Socket, waited: var Duration, timeout, size: int, return min(sslPending, size) var startTime = getMonoTime() - let selRet = select(socket, (timeout - waited.inMilliseconds).int) + let selRet = if socket.hasDataBuffered: 1 + else: + timeoutRead(socket.fd, (timeout - waited.inMilliseconds).int) if selRet < 0: raiseOSError(osLastError()) if selRet != 1: raise newException(TimeoutError, "Call to '" & funcName & "' timed out.") @@ -2063,8 +2081,7 @@ proc connect*(socket: Socket, address: string, port = Port(0), socket.fd.setBlocking(false) socket.connectAsync(address, port, socket.domain) - var s = @[socket.fd] - if selectWrite(s, timeout) != 1: + if timeoutWrite(socket.fd, timeout) != 1: raise newException(TimeoutError, "Call to 'connect' timed out.") else: let res = getSockOptInt(socket.fd, SOL_SOCKET, SO_ERROR) |