Merge branch 'l04m33-async_callback_issue_0412-2' into devel

This commit is contained in:
Dominik Picheta
2015-07-26 22:04:01 +01:00
3 changed files with 112 additions and 6 deletions

View File

@@ -972,9 +972,9 @@ else:
let data = PData(info.key.data)
assert data.fd == info.key.fd.AsyncFD
#echo("In poll ", data.fd.cint)
if EvError in info.events:
closeSocket(data.fd)
continue
# There may be EvError here, but we handle them in callbacks,
# so that exceptions can be raised from `send(...)` and
# `recv(...)` routines.
if EvRead in info.events:
# Callback may add items to ``data.readCBs`` which causes issues if
@@ -1013,9 +1013,17 @@ else:
var retFuture = newFuture[void]("connect")
proc cb(fd: AsyncFD): bool =
# We have connected.
retFuture.complete()
return true
var ret = SocketHandle(fd).getSockOptInt(cint(SOL_SOCKET), cint(SO_ERROR))
if ret == 0:
# We have connected.
retFuture.complete()
return true
elif ret == EINTR:
# interrupted, keep waiting
return false
else:
retFuture.fail(newException(OSError, osErrorMsg(OSErrorCode(ret))))
return true
assert getSockDomain(socket.SocketHandle) == domain
var aiList = getAddrInfo(address, port, domain)

View File

@@ -0,0 +1,33 @@
discard """
file: "tasyncconnect.nim"
exitcode: 1
outputsub: "Error: unhandled exception: Connection refused [Exception]"
"""
import
asyncdispatch,
posix
const
testHost = "127.0.0.1"
testPort = Port(17357)
when defined(windows) or defined(nimdoc):
discard
else:
proc testAsyncConnect() {.async.} =
var s = newAsyncRawSocket()
await s.connect(testHost, testPort)
var peerAddr: SockAddr
var addrSize = Socklen(sizeof(peerAddr))
var ret = SocketHandle(s).getpeername(addr(peerAddr), addr(addrSize))
if ret < 0:
echo("`connect(...)` failed but no exception was raised.")
quit(2)
waitFor(testAsyncConnect())

View File

@@ -0,0 +1,65 @@
discard """
file: "tasynceverror.nim"
exitcode: 1
outputsub: "Error: unhandled exception: Connection reset by peer [Exception]"
"""
import
asyncdispatch,
asyncnet,
rawsockets,
os
const
testHost = "127.0.0.1"
testPort = Port(17357)
when defined(windows) or defined(nimdoc):
discard
else:
proc createListenSocket(host: string, port: Port): TAsyncFD =
result = newAsyncRawSocket()
SocketHandle(result).setSockOptInt(SOL_SOCKET, SO_REUSEADDR, 1)
var aiList = getAddrInfo(host, port, AF_INET)
if SocketHandle(result).bindAddr(aiList.ai_addr, aiList.ai_addrlen.Socklen) < 0'i32:
dealloc(aiList)
raiseOSError(osLastError())
dealloc(aiList)
if SocketHandle(result).listen(1) < 0'i32:
raiseOSError(osLastError())
proc testAsyncSend() {.async.} =
var
ls = createListenSocket(testHost, testPort)
s = newAsyncSocket()
await s.connect(testHost, testPort)
var ps = await ls.accept()
SocketHandle(ls).close()
await ps.send("test 1", flags={})
s.close()
# This send should raise EPIPE
await ps.send("test 2", flags={})
SocketHandle(ps).close()
# The bug was, when the poll function handled EvError for us,
# our callbacks may never get executed, thus making the event
# loop block indefinitely. This is a timer to keep everything
# rolling. 400 ms is an arbitrary value, should be enough though.
proc timer() {.async.} =
await sleepAsync(400)
echo("Timer expired.")
quit(2)
asyncCheck(testAsyncSend())
waitFor(timer())