asyncnet: don't try to close the socket again [backport] (#15174)

The closed flag isn't a good design by any means, but let's have this
working first before I get rid of the flag and potentially create a
non-backportable commit.
This commit is contained in:
alaviss 2020-08-12 06:04:54 +00:00 • committed by GitHub
commit 957bf15a08
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -713,8 +713,12 @@ elif defined(nimdoc):
proc close*(socket: AsyncSocket) = proc close*(socket: AsyncSocket) =
## Closes the socket. ## Closes the socket.
if socket.closed: return
defer: defer:
socket.fd.AsyncFD.closeSocket() socket.fd.AsyncFD.closeSocket()
socket.closed = true # TODO: Add extra debugging checks for this.
when defineSsl: when defineSsl:
if socket.isSsl: if socket.isSsl:
let res = let res =
@ -731,7 +735,6 @@ proc close*(socket: AsyncSocket) =
discard discard
elif res != 1: elif res != 1:
raiseSSLError() raiseSSLError()
socket.closed = true # TODO: Add extra debugging checks for this.
when defineSsl: when defineSsl:
proc wrapSocket*(ctx: SslContext, socket: AsyncSocket) = proc wrapSocket*(ctx: SslContext, socket: AsyncSocket) =
@ -819,9 +822,9 @@ proc sendTo*(socket: AsyncSocket, address: string, port: Port, data: string,
## address or a hostname. If a hostname is specified this function will try ## address or a hostname. If a hostname is specified this function will try
## each IP of that hostname. The returned future will complete once all data ## each IP of that hostname. The returned future will complete once all data
## has been sent. ## has been sent.
## ##
## If an error occurs an OSError exception will be raised. ## If an error occurs an OSError exception will be raised.
## ##
## This proc is normally used with connectionless sockets (UDP sockets). ## This proc is normally used with connectionless sockets (UDP sockets).
assert(socket.protocol != IPPROTO_TCP, assert(socket.protocol != IPPROTO_TCP,
"Cannot `sendTo` on a TCP socket. Use `send` instead") "Cannot `sendTo` on a TCP socket. Use `send` instead")
@ -834,22 +837,22 @@ proc sendTo*(socket: AsyncSocket, address: string, port: Port, data: string,
it = aiList it = aiList
success = false success = false
lastException: ref Exception lastException: ref Exception
while it != nil: while it != nil:
let fut = sendTo(socket.fd.AsyncFD, cstring(data), len(data), it.ai_addr, let fut = sendTo(socket.fd.AsyncFD, cstring(data), len(data), it.ai_addr,
it.ai_addrlen.SockLen, flags) it.ai_addrlen.SockLen, flags)
yield fut yield fut
if not fut.failed: if not fut.failed:
success = true success = true
break break
lastException = fut.readError() lastException = fut.readError()
it = it.ai_next it = it.ai_next
freeaddrinfo(aiList) freeaddrinfo(aiList)
if not success: if not success:
@ -869,24 +872,24 @@ proc recvFrom*(socket: AsyncSocket, data: FutureVar[string], size: int,
## packet received. ## packet received.
## ##
## If an error occurs an OSError exception will be raised. ## If an error occurs an OSError exception will be raised.
## ##
## This proc is normally used with connectionless sockets (UDP sockets). ## This proc is normally used with connectionless sockets (UDP sockets).
## ##
## **Notes** ## **Notes**
## * ``data`` must be initialized to the length of ``size``. ## * ``data`` must be initialized to the length of ``size``.
## * ``address`` must be initialized to 46 in length. ## * ``address`` must be initialized to 46 in length.
template adaptRecvFromToDomain(domain: Domain) = template adaptRecvFromToDomain(domain: Domain) =
var lAddr = sizeof(sAddr).SockLen var lAddr = sizeof(sAddr).SockLen
result = await recvFromInto(AsyncFD(getFd(socket)), cstring(data.mget()), size, result = await recvFromInto(AsyncFD(getFd(socket)), cstring(data.mget()), size,
cast[ptr SockAddr](addr sAddr), addr lAddr, cast[ptr SockAddr](addr sAddr), addr lAddr,
flags) flags)
data.mget().setLen(result) data.mget().setLen(result)
data.complete() data.complete()
getAddrString(cast[ptr SockAddr](addr sAddr), address.mget()) getAddrString(cast[ptr SockAddr](addr sAddr), address.mget())
address.complete() address.complete()
when domain == AF_INET6: when domain == AF_INET6:
@ -901,7 +904,7 @@ proc recvFrom*(socket: AsyncSocket, data: FutureVar[string], size: int,
"`date` was not initialized correctly. `size` != `len(data.mget())`") "`date` was not initialized correctly. `size` != `len(data.mget())`")
assert(46 == len(address.mget()), assert(46 == len(address.mget()),
"`address` was not initialized correctly. 46 != `len(address.mget())`") "`address` was not initialized correctly. 46 != `len(address.mget())`")
case socket.domain case socket.domain
of AF_INET6: of AF_INET6:
var sAddr: Sockaddr_in6 var sAddr: Sockaddr_in6
@ -920,18 +923,18 @@ proc recvFrom*(socket: AsyncSocket, size: int,
## ``size``. Returned future will complete once one datagram has been received ## ``size``. Returned future will complete once one datagram has been received
## and will return tuple with: data of packet received; and address and port ## and will return tuple with: data of packet received; and address and port
## of datagram's sender. ## of datagram's sender.
## ##
## If an error occurs an OSError exception will be raised. ## If an error occurs an OSError exception will be raised.
## ##
## This proc is normally used with connectionless sockets (UDP sockets). ## This proc is normally used with connectionless sockets (UDP sockets).
var var
data = newFutureVar[string]() data = newFutureVar[string]()
address = newFutureVar[string]() address = newFutureVar[string]()
port = newFutureVar[Port]() port = newFutureVar[Port]()
data.mget().setLen(size) data.mget().setLen(size)
address.mget().setLen(46) address.mget().setLen(46)
let read = await recvFrom(socket, data, size, address, port, flags) let read = await recvFrom(socket, data, size, address, port, flags)
result = (data.mget(), address.mget(), port.mget()) result = (data.mget(), address.mget(), port.mget())