From 1a75b17cd03caac6b26588a0572c1032b024f1c8 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Fri, 14 Mar 2014 18:46:08 +0000 Subject: File descriptors are now removed from fds list explicitly in close(). Fixes tasyncawait on linux. --- lib/pure/asyncio2.nim | 6 +++++- lib/pure/selectors.nim | 36 +++++++++++++++++------------------- tests/async/tasyncawait.nim | 6 +++--- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/lib/pure/asyncio2.nim b/lib/pure/asyncio2.nim index c37370b7b..0ea4d7e79 100644 --- a/lib/pure/asyncio2.nim +++ b/lib/pure/asyncio2.nim @@ -508,6 +508,10 @@ else: result = socket(domain, typ, protocol) disp.register(result) + proc close*(disp: PDispatcher, sock: TSocketHandle) = + sock.close() + disp.selector.unregister(sock) + proc addRead(p: PDispatcher, sock: TSocketHandle, cb: TCallback) = if sock notin p.selector: raise newException(EInvalidValue, "File descriptor not registered.") @@ -892,7 +896,7 @@ proc recvLine*(p: PDispatcher, socket: TSocketHandle): PFuture[string] {.async.} when isMainModule: var p = newDispatcher() - var sock = socket() + var sock = p.socket() sock.setBlocking false diff --git a/lib/pure/selectors.nim b/lib/pure/selectors.nim index a113e3362..085344e3e 100644 --- a/lib/pure/selectors.nim +++ b/lib/pure/selectors.nim @@ -60,7 +60,6 @@ when defined(linux) or defined(nimdoc): events: set[TEvent]): PSelectorKey {.discardable.} = ## Updates the events which ``fd`` wants notifications for. if s.fds[fd].events != events: - echo("Update ", fd.cint, " to ", events) var event = createEventStruct(events, fd) s.fds[fd].events = events @@ -70,7 +69,9 @@ when defined(linux) or defined(nimdoc): proc unregister*(s: PSelector, fd: TSocketHandle): PSelectorKey {.discardable.} = if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fd, nil) != 0: - OSError(OSLastError()) + let err = OSLastError() + if err.cint notin {ENOENT, EBADF}: # TODO: Why do we sometimes get an EBADF? Is this normal? + OSError(err) result = s.fds[fd] s.fds.del(fd) @@ -78,6 +79,15 @@ when defined(linux) or defined(nimdoc): if s.epollFD.close() != 0: OSError(OSLastError()) dealloc(addr s.events) # TODO: Test this + proc epollHasFd(s: PSelector, fd: TSocketHandle): bool = + result = true + var event = createEventStruct(s.fds[fd].events, fd) + if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fd, addr(event)) != 0: + let err = osLastError() + if err.cint in {ENOENT, EBADF}: + return false + OSError(OSLastError()) + proc select*(s: PSelector, timeout: int): seq[TReadyInfo] = ## ## The ``events`` field of the returned ``key`` contains the original events @@ -85,24 +95,19 @@ when defined(linux) or defined(nimdoc): ## of the ``TReadyInfo`` tuple which determines which events are ready ## on the ``fd``. result = @[] - let evNum = epoll_wait(s.epollFD, addr s.events[0], 64.cint, timeout.cint) if evNum < 0: OSError(OSLastError()) if evNum == 0: return @[] for i in 0 ..