diff options
author | Dominik Picheta <dominikpicheta@gmail.com> | 2017-11-24 16:25:03 +0000 |
---|---|---|
committer | Dominik Picheta <dominikpicheta@gmail.com> | 2017-11-24 16:25:03 +0000 |
commit | d6870f2e8957b88e0ebc6b4e3308361862b48524 (patch) | |
tree | dd11a4f30f459c4f637cdb5def08efe1c353e84b /lib/pure/ioselects/ioselectors_epoll.nim | |
parent | 3db460f5045e790b54ea3825713c87e92679e8ab (diff) | |
download | Nim-d6870f2e8957b88e0ebc6b4e3308361862b48524.tar.gz |
Multiple improvements to selectors.
* Added ``getFd`` procedure for retrieving the underlying selector's FD. * Selectors module's procedures now accept an ``int`` as well as a ``SocketHandle``. * ReadyKey now contains the error code for Event.Error events.
Diffstat (limited to 'lib/pure/ioselects/ioselectors_epoll.nim')
-rw-r--r-- | lib/pure/ioselects/ioselectors_epoll.nim | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/pure/ioselects/ioselectors_epoll.nim b/lib/pure/ioselects/ioselectors_epoll.nim index 35cdace09..144b4ce8d 100644 --- a/lib/pure/ioselects/ioselectors_epoll.nim +++ b/lib/pure/ioselects/ioselectors_epoll.nim @@ -141,7 +141,7 @@ template checkFd(s, f) = if f >= s.maxFD: raiseIOSelectorsError("Maximum number of descriptors is exhausted!") -proc registerHandle*[T](s: Selector[T], fd: SocketHandle, +proc registerHandle*[T](s: Selector[T], fd: int | SocketHandle, events: set[Event], data: T) = let fdi = int(fd) s.checkFd(fdi) @@ -156,7 +156,7 @@ proc registerHandle*[T](s: Selector[T], fd: SocketHandle, raiseIOSelectorsError(osLastError()) inc(s.count) -proc updateHandle*[T](s: Selector[T], fd: SocketHandle, events: set[Event]) = +proc updateHandle*[T](s: Selector[T], fd: int | SocketHandle, events: set[Event]) = let maskEvents = {Event.Timer, Event.Signal, Event.Process, Event.Vnode, Event.User, Event.Oneshot, Event.Error} let fdi = int(fd) @@ -391,9 +391,19 @@ proc selectInto*[T](s: Selector[T], timeout: int, let pevents = resTable[i].events var pkey = addr(s.fds[fdi]) doAssert(pkey.ident != 0) - var rkey = ReadyKey(fd: int(fdi), events: {}) + var rkey = ReadyKey(fd: fdi, events: {}) if (pevents and EPOLLERR) != 0 or (pevents and EPOLLHUP) != 0: + if (pevents and EPOLLHUP) != 0: + rkey.errorCode = ECONNRESET.OSErrorCode + else: + # Try reading SO_ERROR from fd. + var error: cint + var size = sizeof(error).SockLen + if getsockopt(fdi.SocketHandle, SOL_SOCKET, SO_ERROR, addr(error), + addr(size)) == 0'i32: + rkey.errorCode = error.OSErrorCode + rkey.events.incl(Event.Error) if (pevents and EPOLLOUT) != 0: rkey.events.incl(Event.Write) @@ -481,7 +491,7 @@ template isEmpty*[T](s: Selector[T]): bool = (s.count == 0) proc contains*[T](s: Selector[T], fd: SocketHandle|int): bool {.inline.} = - return s.fds[fd].ident != 0 + return s.fds[fd.int].ident != 0 proc getData*[T](s: Selector[T], fd: SocketHandle|int): var T = let fdi = int(fd) @@ -515,3 +525,6 @@ template withData*[T](s: Selector[T], fd: SocketHandle|int, value, body1, body1 else: body2 + +proc getFd*[T](s: Selector[T]): int = + return s.epollFd.int \ No newline at end of file |