diff options
-rw-r--r-- | lib/pure/nativesockets.nim | 25 | ||||
-rw-r--r-- | lib/pure/net.nim | 25 | ||||
-rw-r--r-- | tests/async/tacceptcloserace.nim | 7 |
3 files changed, 32 insertions, 25 deletions
diff --git a/lib/pure/nativesockets.nim b/lib/pure/nativesockets.nim index d51dbd475..17e23c8e0 100644 --- a/lib/pure/nativesockets.nim +++ b/lib/pure/nativesockets.nim @@ -620,3 +620,28 @@ proc selectWrite*(writefds: var seq[SocketHandle], when defined(Windows): var wsa: WSAData if wsaStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError()) + +proc checkCloseError*(ret: cint) = + ## Asserts that the return value of close() or closeSocket() syscall + ## does not indicate a programming error (such as invalid descriptor). + ## This must only be used when an error has already occurred and + ## you are performing a cleanup. + ## Otherwise, error handling must be performed as usual. + ## + ## This procedure must be called right after performing the syscall. Example: + ## + ## .. code-block:: nim + ## + ## let ret = someSysCall() + ## if ret != 0: + ## let errcode = osLastError() + ## checkCloseError sock.closeSocket() + ## raise newException(OSError, osErrorMsg(errcode)) + + if ret != 0: + let errcode = osLastError() + when useWinVersion: + doAssert(errcode.int32 notin {WSANOTINITIALISED, WSAENOTSOCK, + WSAEINPROGRESS, WSAEINTR, WSAEWOULDBLOCK}) + else: + doAssert(errcode.int32 notin {EBADF}) diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 3699835c2..7f6783358 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -191,31 +191,6 @@ proc isDisconnectionError*(flags: set[SocketFlag], SocketFlag.SafeDisconn in flags and lastError.int32 in {ECONNRESET, EPIPE, ENETRESET} -proc checkCloseError*(ret: cint) = - ## Asserts that the return value of close() or closeSocket() syscall - ## does not indicate a programming error (such as invalid descriptor). - ## This must only be used when an error has already occurred and - ## you are performing a cleanup. - ## Otherwise, error handling must be performed as usual. - ## - ## This procedure must be called right after perfoming the syscall. Example: - ## - ## .. code-block:: nim - ## - ## let ret = someSysCall() - ## if ret != 0: - ## let errcode = osLastError() - ## checkCloseError sock.closeSocket() - ## raise newException(OSError, osErrorMsg(errcode)) - - if ret != 0: - let errcode = osLastError() - when useWinVersion: - doAssert(errcode.int32 notin {WSANOTINITIALISED, WSAENOTSOCK, - WSAEINPROGRESS, WSAEINTR, WSAEWOULDBLOCK}) - else: - doAssert(errcode.int32 notin {EBADF}) - proc toOSFlags*(socketFlags: set[SocketFlag]): cint = ## Converts the flags into the underlying OS representation. for f in socketFlags: diff --git a/tests/async/tacceptcloserace.nim b/tests/async/tacceptcloserace.nim index 899136b42..cbb5b5098 100644 --- a/tests/async/tacceptcloserace.nim +++ b/tests/async/tacceptcloserace.nim @@ -1,9 +1,16 @@ +discard """ + exitcode: 0 + output: "" +""" + import asyncdispatch, net, os, nativesockets # bug: https://github.com/nim-lang/Nim/issues/5279 proc setupServerSocket(hostname: string, port: Port): AsyncFD = let fd = newNativeSocket() + if fd == osInvalidSocket: + raiseOSError(osLastError()) setSockOptInt(fd, SOL_SOCKET, SO_REUSEADDR, 1) var aiList = getAddrInfo(hostname, port) if bindAddr(fd, aiList.ai_addr, aiList.ai_addrlen.Socklen) < 0'i32: |