diff options
author | cheatfate <ka@hardcore.kiev.ua> | 2016-06-26 09:51:01 +0300 |
---|---|---|
committer | cheatfate <ka@hardcore.kiev.ua> | 2016-06-26 09:51:01 +0300 |
commit | 2eb34a8129aa82ab74035886881c84b8f0489c56 (patch) | |
tree | 40b442581654ed6828b5dd68565961849d65ba3e | |
parent | ee6257b9923f83335a598da27aa54527dcb43145 (diff) | |
download | Nim-2eb34a8129aa82ab74035886881c84b8f0489c56.tar.gz |
Event enum is now .pure.
Modified getMaxFds() to work more properly. Removed seqs from code Some exceptions replaced with doAssert
-rw-r--r-- | lib/pure/ioselectors.nim | 801 | ||||
-rw-r--r-- | tests/async/tioselectors.nim | 22 |
2 files changed, 377 insertions, 446 deletions
diff --git a/lib/pure/ioselectors.nim b/lib/pure/ioselectors.nim index b77ab9295..65e549b19 100644 --- a/lib/pure/ioselectors.nim +++ b/lib/pure/ioselectors.nim @@ -50,16 +50,16 @@ when defined(nimdoc): Selector*[T] = ref object ## An object which holds descriptors to be checked for read/write status - Event* = enum + Event* {.pure.} = enum ## An enum which hold event types - eventRead, ## Descriptor is available for read - eventWrite, ## Descriptor is available for write - eventTimer, ## Timer descriptor is completed - eventSignal, ## Signal is raised - eventProcess, ## Process is finished - eventVnode, ## Currently not supported - eventUser, ## User event is raised - eventError ## Error happens while waiting, for descriptor + Read, ## Descriptor is available for read + Write, ## Descriptor is available for write + Timer, ## Timer descriptor is completed + Signal, ## Signal is raised + Process, ## Process is finished + Vnode, ## Currently not supported + User, ## User event is raised + Error ## Error happens while waiting, for descriptor ReadyKey*[T] = object ## An object which holds result for descriptor @@ -189,36 +189,68 @@ when defined(nimdoc): ## else: - when not defined(windows): + when defined(macosx) or defined(freebsd): when defined(macosx): - var - OPEN_MAX {.importc: "OPEN_MAX", header: "<sys/resource.h>".}: cint + const maxDescriptors = 29 # KERN_MAXFILESPERPROC (MacOS) + else: + const maxDescriptors = 27 # KERN_MAXFILESPERPROC (FreeBSD) + proc sysctl(name: ptr cint, namelen: cuint, oldp: pointer, oldplen: ptr int, + newp: pointer, newplen: int): cint + {.importc: "sysctl",header: """#include <sys/types.h> + #include <sys/sysctl.h>"""} + elif defined(netbsd) or defined(openbsd): + # OpenBSD and NetBSD don't have KERN_MAXFILESPERPROC, so we are using + # KERN_MAXFILES, because KERN_MAXFILES is always bigger, + # than KERN_MAXFILESPERPROC + const maxDescriptors = 7 # KERN_MAXFILES + proc sysctl(name: ptr cint, namelen: cuint, oldp: pointer, oldplen: ptr int, + newp: pointer, newplen: int): cint + {.importc: "sysctl",header: """#include <sys/param.h> + #include <sys/sysctl.h>"""} + elif defined(linux) or defined(solaris): + proc ulimit(cmd: cint): clong + {.importc: "ulimit", header: "<ulimit.h>", varargs.} + elif defined(windows): + discard + else: var RLIMIT_NOFILE {.importc: "RLIMIT_NOFILE", header: "<sys/resource.h>".}: cint type rlimit {.importc: "struct rlimit", - header: "<sys/resource.h>", pure, final.} = object + header: "<sys/resource.h>", pure, final.} = object rlim_cur: int rlim_max: int - proc getrlimit(resource: cint, rlp: var rlimit): cint {. - importc: "getrlimit",header: "<sys/resource.h>"} - proc getMaxFds*(): int = + proc getrlimit(resource: cint, rlp: var rlimit): cint + {.importc: "getrlimit",header: "<sys/resource.h>".} + + proc getMaxFds*(): int = + when defined(macosx) or defined(freebsd) or defined(netbsd) or + defined(openbsd): + var count = cint(0) + var size = sizeof(count) + var namearr = [cint(1), cint(maxDescriptors)] + + if sysctl(addr namearr[0], 2, cast[pointer](addr count), addr size, + nil, 0) != 0: + raiseOsError(osLastError()) + result = count + elif defined(linux) or defined(solaris): + result = int(ulimit(4, 0)) + elif defined(windows): + result = FD_SETSIZE + else: var a = rlimit() if getrlimit(RLIMIT_NOFILE, a) != 0: raiseOsError(osLastError()) result = a.rlim_max - when defined(macosx): - if a.rlim_max > OPEN_MAX: - result = OPEN_MAX when hasThreadSupport: import locks type - Event* = enum - eventRead, eventWrite, eventTimer, eventSignal, eventProcess, - eventVnode, eventUser, eventError, + Event* {.pure.} = enum + Read, Write, Timer, Signal, Process, Vnode, User, Error, flagHandle, flagTimer, flagSignal, flagProcess, flagVnode, flagUser, flagOneshot @@ -234,20 +266,19 @@ else: key : ReadyKey[T] when not defined(windows): - when hasThreadSupport: - type - SharedArrayHolder[T] = object - part: array[16, T] - SharedArray {.unchecked.}[T] = array[0..100_000_000, T] + type + SharedArrayHolder[T] = object + part: array[16, T] + SharedArray {.unchecked.}[T] = array[0..100_000_000, T] - proc allocSharedArray[T](nsize: int): ptr SharedArray[T] = - let holder = cast[ptr SharedArrayHolder[T]]( - allocShared0(sizeof(T) * nsize) - ) - result = cast[ptr SharedArray[T]](addr(holder.part[0])) + proc allocSharedArray[T](nsize: int): ptr SharedArray[T] = + let holder = cast[ptr SharedArrayHolder[T]]( + allocShared0(sizeof(T) * nsize) + ) + result = cast[ptr SharedArray[T]](addr(holder.part[0])) - proc deallocSharedArray[T](sa: ptr SharedArray[T]) = - deallocShared(cast[pointer](sa)) + proc deallocSharedArray[T](sa: ptr SharedArray[T]) = + deallocShared(cast[pointer](sa)) template setNonBlocking(fd) = var x: int = fcntl(fd, F_GETFL, 0) @@ -298,30 +329,17 @@ else: MAX_KQUEUE_CHANGE_EVENTS = 64 MAX_KQUEUE_RESULT_EVENTS = 64 - when hasThreadSupport: - type - SelectorImpl[T] = object - kqFD : cint - maxFD : uint - changesTable: array[MAX_KQUEUE_CHANGE_EVENTS, KEvent] - changesCount: int - fds: ptr SharedArray[SelectorKey[T]] - count: int + type + SelectorImpl[T] = object + kqFD : cint + maxFD : uint + changesTable: array[MAX_KQUEUE_CHANGE_EVENTS, KEvent] + changesCount: int + fds: ptr SharedArray[SelectorKey[T]] + count: int + when hasThreadSupport: changesLock: Lock - else: - type - SelectorImpl[T] = object - kqFD : cint - maxFD : uint - changesTable: array[MAX_KQUEUE_CHANGE_EVENTS, KEvent] - changesCount: int - fds: seq[SelectorKey[T]] - count: int - - when hasThreadSupport: - type Selector*[T] = ptr SelectorImpl[T] - else: - type Selector*[T] = ref SelectorImpl[T] + Selector*[T] = ptr SelectorImpl[T] type SelectEventImpl = object @@ -336,23 +354,21 @@ else: var kqFD = kqueue() if kqFD < 0: raiseOsError(osLastError()) + + result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T]))) + result.kqFD = kqFD + result.maxFD = maxFD.uint + result.fds = allocSharedArray[SelectorKey[T]](maxFD) when hasThreadSupport: - result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T]))) - result.kqFD = kqFD - result.maxFD = maxFD.uint - result.fds = allocSharedArray[SelectorKey[T]](maxFD) initLock(result.changesLock) - else: - result = Selector[T](kqFD: kqFD, maxFD: maxFD.uint) - result.fds = newSeq[SelectorKey[T]](maxFD) proc close*[T](s: Selector[T]) = if posix.close(s.kqFD) != 0: raiseOSError(osLastError()) when hasThreadSupport: deinitLock(s.changesLock) - deallocSharedArray(s.fds) - deallocShared(cast[pointer](s)) + deallocSharedArray(s.fds) + deallocShared(cast[pointer](s)) when hasThreadSupport: template withChangeLock[T](s: Selector[T], body: untyped) = @@ -386,17 +402,15 @@ else: events: set[Event], data: T) = var fdi = int(fd) if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0: - setKey(s, fdi, fdi, {flagHandle} + events, 0, data) - if events != {}: - if eventRead in events: - modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil) - inc(s.count) - if eventWrite in events: - modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_ADD, 0, 0, nil) - inc(s.count) - else: - raise newException(ValueError, "Re-use of non-closed descriptor") + doAssert(s.fds[fdi].ident == 0) + setKey(s, fdi, fdi, {Event.flagHandle} + events, 0, data) + if events != {}: + if Event.Read in events: + modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil) + inc(s.count) + if Event.Write in events: + modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_ADD, 0, 0, nil) + inc(s.count) else: raise newException(ValueError, "Maximum file descriptors exceeded") @@ -404,30 +418,24 @@ else: events: set[Event]) = var fdi = int(fd) if fdi.uint < s.maxFD: - if s.fds[fdi].ident != 0: - if flagHandle in s.fds[fdi].flags: - var ne = events + {flagHandle} - var oe = s.fds[fdi].flags - if oe != ne: - if (eventRead in oe) and (eventRead notin ne): - modifyKQueue(s, fdi.uint, EVFILT_READ, EV_DELETE, 0, 0, nil) - dec(s.count) - if (eventWrite in oe) and (eventWrite notin ne): - modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_DELETE, 0, 0, nil) - dec(s.count) - if (eventRead notin oe) and (eventRead in ne): - modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil) - inc(s.count) - if (eventWrite notin oe) and (eventWrite in ne): - modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_ADD, 0, 0, nil) - inc(s.count) - s.fds[fdi].flags = ne - else: - raise newException(ValueError, - "Could not update non-handle descriptor") - else: - raise newException(ValueError, - "Descriptor is not registered in queue") + doAssert(s.fds[fdi].ident != 0) + doAssert(Event.flagHandle in s.fds[fdi].flags) + var ne = events + {Event.flagHandle} + var oe = s.fds[fdi].flags + if oe != ne: + if (Event.Read in oe) and (Event.Read notin ne): + modifyKQueue(s, fdi.uint, EVFILT_READ, EV_DELETE, 0, 0, nil) + dec(s.count) + if (Event.Write in oe) and (Event.Write notin ne): + modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_DELETE, 0, 0, nil) + dec(s.count) + if (Event.Read notin oe) and (Event.Read in ne): + modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil) + inc(s.count) + if (Event.Write notin oe) and (Event.Write in ne): + modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_ADD, 0, 0, nil) + inc(s.count) + s.fds[fdi].flags = ne else: raise newException(ValueError, "Maximum file descriptors exceeded") @@ -438,20 +446,18 @@ else: if fdi == -1: raiseOsError(osLastError()) if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0: - var mflags = if oneshot: {flagTimer, flagOneshot} - else: {flagTimer} - var kflags: cushort = if oneshot: EV_ONESHOT or EV_ADD - else: EV_ADD - setKey(s, fdi, fdi, mflags, 0, data) - # EVFILT_TIMER on Open/Net(BSD) has granularity of only milliseconds, - # but MacOS and FreeBSD allow use `0` as `fflags` to use milliseconds - # too - modifyKQueue(s, fdi.uint, EVFILT_TIMER, kflags, 0, cint(timeout), nil) - inc(s.count) - result = fdi - else: - raise newException(ValueError, "Re-use of non-closed descriptor") + doAssert(s.fds[fdi].ident == 0) + var mflags = if oneshot: {Event.flagTimer, Event.flagOneshot} + else: {Event.flagTimer} + var kflags: cushort = if oneshot: EV_ONESHOT or EV_ADD + else: EV_ADD + setKey(s, fdi, fdi, mflags, 0, data) + # EVFILT_TIMER on Open/Net(BSD) has granularity of only milliseconds, + # but MacOS and FreeBSD allow use `0` as `fflags` to use milliseconds + # too + modifyKQueue(s, fdi.uint, EVFILT_TIMER, kflags, 0, cint(timeout), nil) + inc(s.count) + result = fdi else: raise newException(ValueError, "Maximum file descriptors exceeded") @@ -463,23 +469,21 @@ else: raiseOsError(osLastError()) if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0: - setKey(s, fdi, signal, {flagSignal}, signal, data) - # block signal `signal` - var nmask: Sigset - var omask: Sigset - discard sigemptyset(nmask) - discard sigemptyset(omask) - discard sigaddset(nmask, cint(signal)) - blockSignals(nmask, omask) - # to be compatible with linux semantic we need to "eat" signals - posix.signal(cint(signal), SIG_IGN) - modifyKQueue(s, signal.uint, EVFILT_SIGNAL, EV_ADD, 0, 0, - cast[pointer](fdi)) - inc(s.count) - result = fdi - else: - raise newException(ValueError, "Re-use of non-closed descriptor") + doAssert(s.fds[fdi].ident == 0) + setKey(s, fdi, signal, {Event.flagSignal}, signal, data) + # block signal `signal` + var nmask: Sigset + var omask: Sigset + discard sigemptyset(nmask) + discard sigemptyset(omask) + discard sigaddset(nmask, cint(signal)) + blockSignals(nmask, omask) + # to be compatible with linux semantic we need to "eat" signals + posix.signal(cint(signal), SIG_IGN) + modifyKQueue(s, signal.uint, EVFILT_SIGNAL, EV_ADD, 0, 0, + cast[pointer](fdi)) + inc(s.count) + result = fdi else: raise newException(ValueError, "Maximum file descriptors exceeded") @@ -491,15 +495,13 @@ else: raiseOsError(osLastError()) if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0: - var kflags: cushort = EV_ONESHOT or EV_ADD - setKey(s, fdi, pid, {flagProcess, flagOneshot}, pid, data) - modifyKQueue(s, pid.uint, EVFILT_PROC, kflags, NOTE_EXIT, 0, - cast[pointer](fdi)) - inc(s.count) - result = fdi - else: - raise newException(ValueError, "Re-use of non-closed descriptor") + doAssert(s.fds[fdi].ident == 0) + var kflags: cushort = EV_ONESHOT or EV_ADD + setKey(s, fdi, pid, {Event.flagProcess, Event.flagOneshot}, pid, data) + modifyKQueue(s, pid.uint, EVFILT_PROC, kflags, NOTE_EXIT, 0, + cast[pointer](fdi)) + inc(s.count) + result = fdi else: raise newException(ValueError, "Maximum file descriptors exceeded") @@ -509,22 +511,22 @@ else: var flags = s.fds[fdi].flags var filter: cshort = 0 if s.fds[fdi].ident != 0 and flags != {}: - if flagHandle in flags: + if Event.flagHandle in flags: # if events == 0, than descriptor was modified with # updateHandle(fd, 0), so it was already deleted from kqueue. - if flags != {flagHandle}: - if eventRead in flags: + if flags != {Event.flagHandle}: + if Event.Read in flags: modifyKQueue(s, fdi.uint, EVFILT_READ, EV_DELETE, 0, 0, nil) dec(s.count) - if eventWrite in flags: + if Event.Write in flags: modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_DELETE, 0, 0, nil) dec(s.count) - elif flagTimer in flags: + elif Event.flagTimer in flags: filter = EVFILT_TIMER discard posix.close(cint(s.fds[fdi].key.fd)) modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil) dec(s.count) - elif flagSignal in flags: + elif Event.flagSignal in flags: filter = EVFILT_SIGNAL # unblocking signal var nmask = Sigset() @@ -536,12 +538,12 @@ else: discard posix.close(cint(s.fds[fdi].key.fd)) modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil) dec(s.count) - elif flagProcess in flags: + elif Event.flagProcess in flags: filter = EVFILT_PROC discard posix.close(cint(s.fds[fdi].key.fd)) modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil) dec(s.count) - elif flagUser in flags: + elif Event.flagUser in flags: filter = EVFILT_READ modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil) dec(s.count) @@ -583,15 +585,10 @@ else: proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) = let fdi = ev.rfd.int - if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0 and s.fds[fdi].flags == {}: - setKey(s, fdi, fdi, {flagUser}, 0, data) - modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil) - inc(s.count) - else: - raise newException(ValueError, "Re-use of non-closed descriptor") - else: - raise newException(ValueError, "Event wait still pending!") + doAssert(s.fds[fdi].ident == 0) + setKey(s, fdi, fdi, {Event.flagUser}, 0, data) + modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil) + inc(s.count) proc unregister*[T](s: Selector[T], ev: SelectEvent) = let fdi = ev.rfd.int @@ -640,9 +637,9 @@ else: case kevent.filter of EVFILT_READ: skey = addr(s.fds[kevent.ident.int]) - if flagHandle in skey.flags: - events = {eventRead} - elif flagUser in skey.flags: + if Event.flagHandle in skey.flags: + events = {Event.Read} + elif Event.flagUser in skey.flags: var data: int = 0 if posix.read(kevent.ident.cint, addr data, sizeof(int)) != sizeof(int): @@ -653,28 +650,28 @@ else: continue else: raiseOSError(osLastError()) - events = {eventUser} + events = {Event.User} else: - events = {eventRead} + events = {Event.Read} of EVFILT_WRITE: skey = addr(s.fds[kevent.ident.int]) - events = {eventWrite} + events = {Event.Write} of EVFILT_TIMER: skey = addr(s.fds[kevent.ident.int]) - if flagOneshot in skey.flags: + if Event.flagOneshot in skey.flags: if posix.close(skey.ident.cint) == -1: raiseOSError(osLastError()) clearKey(s, skey.ident) # no need to modify kqueue, because EV_ONESHOT is already made # this for us dec(s.count) - events = {eventTimer} + events = {Event.Timer} of EVFILT_VNODE: skey = addr(s.fds[kevent.ident.int]) - events = {eventVnode} + events = {Event.Vnode} of EVFILT_SIGNAL: skey = addr(s.fds[cast[int](kevent.udata)]) - events = {eventSignal} + events = {Event.Signal} of EVFILT_PROC: skey = addr(s.fds[cast[int](kevent.udata)]) if posix.close(skey.ident.cint) == -1: @@ -683,13 +680,13 @@ else: # no need to modify kqueue, because EV_ONESHOT is already made # this for us dec(s.count) - events = {eventProcess} + events = {Event.Process} else: raise newException(ValueError, "Unsupported kqueue filter in queue") if (kevent.flags and EV_EOF) != 0: - events = events + {eventError} + events = events + {Event.Error} results[k].fd = skey.key.fd results[k].events = events results[k].data = skey.key.data @@ -775,72 +772,55 @@ else: proc eventfd(count: cuint, flags: cint): cint {.cdecl, importc: "eventfd", header: "<sys/eventfd.h>".} - when hasThreadSupport: - type - SelectorImpl[T] = object - epollFD : cint - maxFD : uint - fds: ptr SharedArray[SelectorKey[T]] - count: int - else: - type - SelectorImpl[T] = object - epollFD : cint - maxFD : uint - fds: seq[SelectorKey[T]] - count: int - - when hasThreadSupport: - type Selector*[T] = ptr SelectorImpl[T] - else: - type Selector*[T] = ref SelectorImpl[T] type + SelectorImpl[T] = object + epollFD : cint + maxFD : uint + fds: ptr SharedArray[SelectorKey[T]] + count: int + + Selector*[T] = ptr SelectorImpl[T] + SelectEventImpl = object efd: cint - type SelectEvent* = ptr SelectEventImpl + SelectEvent* = ptr SelectEventImpl proc newSelector*[T](): Selector[T] = var maxFD = getMaxFds() var epollFD = epoll_create(MAX_EPOLL_RESULT_EVENTS) if epollFD < 0: raiseOsError(osLastError()) - when hasThreadSupport: - result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T]))) - result.epollFD = epollFD - result.maxFD = maxFD.uint - result.fds = allocSharedArray[SelectorKey[T]](maxFD) - else: - result = Selector[T](epollFD: epollFD, maxFD: maxFD.uint) - result.fds = newSeq[SelectorKey[T]](maxFD) + + result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T]))) + result.epollFD = epollFD + result.maxFD = maxFD.uint + result.fds = allocSharedArray[SelectorKey[T]](maxFD) proc close*[T](s: Selector[T]) = if posix.close(s.epollFD) != 0: raiseOSError(osLastError()) - when hasThreadSupport: - deallocSharedArray(s.fds) - deallocShared(cast[pointer](s)) + deallocSharedArray(s.fds) + deallocShared(cast[pointer](s)) proc registerHandle*[T](s: Selector[T], fd: SocketHandle, events: set[Event], data: T) = var fdi = int(fd) if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0: - setKey(s, fdi, fdi, events + {flagHandle}, 0, data) - if events != {}: - var epv: epoll_event - epv.events = EPOLLRDHUP - epv.data.u64 = fdi.uint - if eventRead in events: - epv.events = epv.events or EPOLLIN - if eventWrite in events: - epv.events = epv.events or EPOLLOUT - if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1: - raiseOSError(osLastError()) - inc(s.count) - else: - raise newException(ValueError, "Re-use of non-closed descriptor") + doAssert(s.fds[fdi].ident == 0) + setKey(s, fdi, fdi, events + {Event.flagHandle}, 0, data) + if events != {}: + var epv: epoll_event + epv.events = EPOLLRDHUP + epv.data.u64 = fdi.uint + if Event.Read in events: + epv.events = epv.events or EPOLLIN + if Event.Write in events: + epv.events = epv.events or EPOLLOUT + if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1: + raiseOSError(osLastError()) + inc(s.count) else: raise newException(ValueError, "Maximum file descriptors exceeded") @@ -848,43 +828,37 @@ else: events: set[Event]) = var fdi = int(fd) if fdi.uint < s.maxFD: - if s.fds[fdi].ident != 0: - var oe = s.fds[fdi].flags - if flagHandle in oe: - var ne = events + {flagHandle} - if oe != ne: - var epv: epoll_event - epv.data.u64 = fdi.uint - epv.events = EPOLLRDHUP - - if eventRead in events: - epv.events = epv.events or EPOLLIN - if eventWrite in events: - epv.events = epv.events or EPOLLOUT - - if oe == {flagHandle}: - if ne != {flagHandle}: - if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, - addr epv) == -1: - raiseOSError(osLastError()) - inc(s.count) - else: - if events != {}: - if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fdi.cint, - addr epv) == -1: - raiseOSError(osLastError()) - else: - if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, - addr epv) == -1: - raiseOSError(osLastError()) - dec(s.count) - s.fds[fdi].flags = ne + var oe = s.fds[fdi].flags + doAssert(s.fds[fdi].ident != 0) + doAssert(Event.flagHandle in oe) + var ne = events + {Event.flagHandle} + if oe != ne: + var epv: epoll_event + epv.data.u64 = fdi.uint + epv.events = EPOLLRDHUP + + if Event.Read in events: + epv.events = epv.events or EPOLLIN + if Event.Write in events: + epv.events = epv.events or EPOLLOUT + + if oe == {Event.flagHandle}: + if ne != {Event.flagHandle}: + if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, + addr epv) == -1: + raiseOSError(osLastError()) + inc(s.count) else: - raise newException(ValueError, - "Could not update non-handle descriptor") - else: - raise newException(ValueError, - "Descriptor is not registered in queue") + if events != {}: + if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fdi.cint, + addr epv) == -1: + raiseOSError(osLastError()) + else: + if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, + addr epv) == -1: + raiseOSError(osLastError()) + dec(s.count) + s.fds[fdi].flags = ne else: raise newException(ValueError, "Maximum file descriptors exceeded") @@ -894,21 +868,21 @@ else: if fdi.uint < s.maxFD: var flags = s.fds[fdi].flags if s.fds[fdi].ident != 0 and flags != {}: - if flagHandle in flags: + if Event.flagHandle in flags: # if events == {flagHandle}, then descriptor was already # unregistered from epoll with updateHandle() call. # This check is done to omit EBADF error. - if flags != {flagHandle}: + if flags != {Event.flagHandle}: if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) == -1: raiseOSError(osLastError()) dec(s.count) - elif flagTimer in flags: + elif Event.flagTimer in flags: if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) == -1: raiseOSError(osLastError()) discard posix.close(fdi.cint) dec(s.count) - elif flagSignal in flags: + elif Event.flagSignal in flags: if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) == -1: raiseOSError(osLastError()) var nmask: Sigset @@ -919,7 +893,7 @@ else: unblockSignals(nmask, omask) discard posix.close(fdi.cint) dec(s.count) - elif flagProcess in flags: + elif Event.flagProcess in flags: if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) == -1: raiseOSError(osLastError()) var nmask: Sigset @@ -935,7 +909,7 @@ else: proc unregister*[T](s: Selector[T], ev: SelectEvent) = let fdi = int(ev.efd) if fdi.uint < s.maxFD: - if s.fds[fdi].ident != 0 and flagUser in s.fds[fdi].flags: + if s.fds[fdi].ident != 0 and (Event.flagUser in s.fds[fdi].flags): clearKey(s, fdi) var epv: epoll_event if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) == -1: @@ -951,33 +925,31 @@ else: if fdi == -1: raiseOSError(osLastError()) if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0: - var flags = {flagTimer} - var epv: epoll_event - epv.data.u64 = fdi.uint - epv.events = EPOLLIN or EPOLLRDHUP - setNonBlocking(fdi.cint) - if oneshot: - new_ts.it_interval.tv_sec = 0.Time - new_ts.it_interval.tv_nsec = 0 - new_ts.it_value.tv_sec = (timeout div 1_000).Time - new_ts.it_value.tv_nsec = (timeout %% 1_000) * 1_000_000 - flags = flags + {flagOneshot} - epv.events = epv.events or EPOLLONESHOT - else: - new_ts.it_interval.tv_sec = (timeout div 1000).Time - new_ts.it_interval.tv_nsec = (timeout %% 1_000) * 1_000_000 - new_ts.it_value.tv_sec = new_ts.it_interval.tv_sec - new_ts.it_value.tv_nsec = new_ts.it_interval.tv_nsec - if timerfd_settime(fdi.cint, cint(0), new_ts, old_ts) == -1: - raiseOSError(osLastError()) - if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1: - raiseOSError(osLastError()) - setKey(s, fdi, fdi, flags, 0, data) - inc(s.count) - result = fdi + doAssert(s.fds[fdi].ident == 0) + var flags = {Event.flagTimer} + var epv: epoll_event + epv.data.u64 = fdi.uint + epv.events = EPOLLIN or EPOLLRDHUP + setNonBlocking(fdi.cint) + if oneshot: + new_ts.it_interval.tv_sec = 0.Time + new_ts.it_interval.tv_nsec = 0 + new_ts.it_value.tv_sec = (timeout div 1_000).Time + new_ts.it_value.tv_nsec = (timeout %% 1_000) * 1_000_000 + flags = flags + {Event.flagOneshot} + epv.events = epv.events or EPOLLONESHOT else: - raise newException(ValueError, "Re-use of non-closed descriptor") + new_ts.it_interval.tv_sec = (timeout div 1000).Time + new_ts.it_interval.tv_nsec = (timeout %% 1_000) * 1_000_000 + new_ts.it_value.tv_sec = new_ts.it_interval.tv_sec + new_ts.it_value.tv_nsec = new_ts.it_interval.tv_nsec + if timerfd_settime(fdi.cint, cint(0), new_ts, old_ts) == -1: + raiseOSError(osLastError()) + if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1: + raiseOSError(osLastError()) + setKey(s, fdi, fdi, flags, 0, data) + inc(s.count) + result = fdi else: raise newException(ValueError, "Maximum file descriptors exceeded") @@ -995,18 +967,16 @@ else: if fdi == -1: raiseOSError(osLastError()) if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0: - setNonBlocking(fdi.cint) - var epv: epoll_event - epv.data.u64 = fdi.uint - epv.events = EPOLLIN or EPOLLRDHUP - if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1: - raiseOSError(osLastError()) - setKey(s, fdi, signal, {flagSignal}, signal, data) - inc(s.count) - result = fdi - else: - raise newException(ValueError, "Re-use of non-closed descriptor") + doAssert(s.fds[fdi].ident == 0) + setNonBlocking(fdi.cint) + var epv: epoll_event + epv.data.u64 = fdi.uint + epv.events = EPOLLIN or EPOLLRDHUP + if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1: + raiseOSError(osLastError()) + setKey(s, fdi, signal, {Event.flagSignal}, signal, data) + inc(s.count) + result = fdi else: raise newException(ValueError, "Maximum file descriptors exceeded") @@ -1020,28 +990,22 @@ else: discard sigemptyset(omask) discard sigaddset(nmask, posix.SIGCHLD) blockSignals(nmask, omask) - try: - var fdi = signalfd(-1, nmask, 0) - if fd == -1: + var fdi = signalfd(-1, nmask, 0) + if fd == -1: + raiseOSError(osLastError()) + if fdi.uint < s.maxFD: + doAssert(s.fds[fdi].ident == 0) + setNonBlocking(fdi.cint) + var epv: epoll_event + epv.data.u64 = fdi.uint + epv.events = EPOLLIN or EPOLLRDHUP + if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1: raiseOSError(osLastError()) - if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0: - setNonBlocking(fdi.cint) - var epv: epoll_event - epv.data.u64 = fdi.uint - epv.events = EPOLLIN or EPOLLRDHUP - if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1: - raiseOSError(osLastError()) - setKey(s, fdi, pid, {flagProcess}, pid, data) - inc(s.count) - result = fdi - else: - raise newException(ValueError, "Re-use of non-closed descriptor") - else: - raise newException(ValueError, "Maximum file descriptors exceeded") - except: - if fd != -1: discard posix.close(fd.cint) - unblockSignals(omask, nmask) + setKey(s, fdi, pid, {Event.flagProcess}, pid, data) + inc(s.count) + result = fdi + else: + raise newException(ValueError, "Maximum file descriptors exceeded") proc flush*[T](s: Selector[T]) = discard @@ -1051,18 +1015,13 @@ else: proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) = let fdi = int(ev.efd) - if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0: - setKey(s, fdi, fdi, {flagUser}, 0, data) - var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP) - epv.data.u64 = ev.efd.uint - if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, ev.efd, addr epv) == -1: - raiseOSError(osLastError()) - inc(s.count) - else: - raise newException(ValueError, "Re-use of non-closed descriptor") - else: - raise newException(ValueError, "Maximum file descriptors exceeded") + doAssert(s.fds[fdi].ident == 0) + setKey(s, fdi, fdi, {Event.flagUser}, 0, data) + var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP) + epv.data.u64 = ev.efd.uint + if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, ev.efd, addr epv) == -1: + raiseOSError(osLastError()) + inc(s.count) proc setEvent*(ev: SelectEvent) = var data : uint64 = 1 @@ -1105,36 +1064,36 @@ else: if skey.ident != 0 and flags != {}: block processItem: if (pevents and EPOLLERR) != 0 or (pevents and EPOLLHUP) != 0: - events = events + {eventError} + events = events + {Event.Error} if (pevents and EPOLLOUT) != 0: - events = events + {eventWrite} + events = events + {Event.Write} if (pevents and EPOLLIN) != 0: - if flagHandle in flags: - events = events + {eventRead} - elif flagTimer in flags: + if Event.flagHandle in flags: + events = events + {Event.Read} + elif Event.flagTimer in flags: var data: uint64 = 0 if posix.read(fdi.cint, addr data, sizeof(uint64)) != sizeof(uint64): raiseOSError(osLastError()) - events = events + {eventTimer} - elif flagSignal in flags: + events = events + {Event.Timer} + elif Event.flagSignal in flags: var data: SignalFdInfo if posix.read(fdi.cint, addr data, sizeof(SignalFdInfo)) != sizeof(SignalFdInfo): raiseOsError(osLastError()) - events = events + {eventSignal} - elif flagProcess in flags: + events = events + {Event.Signal} + elif Event.flagProcess in flags: var data: SignalFdInfo if posix.read(fdi.cint, addr data, sizeof(SignalFdInfo)) != sizeof(SignalFdInfo): raiseOsError(osLastError()) if cast[int](data.ssi_pid) == skey.param: - events = events + {eventProcess} + events = events + {Event.Process} # we want to free resources for this event - flags = flags + {flagOneshot} + flags = flags + {Event.flagOneshot} else: break processItem - elif flagUser in flags: + elif Event.flagUser in flags: var data: uint = 0 if posix.read(fdi.cint, addr data, sizeof(uint)) != sizeof(uint): @@ -1145,7 +1104,7 @@ else: continue else: raiseOSError(err) - events = events + {eventUser} + events = events + {Event.User} else: raise newException(ValueError, "Unsupported epoll event in queue") @@ -1153,7 +1112,7 @@ else: results[k].events = events results[k].data = skey.key.data - if flagOneshot in flags: + if Event.flagOneshot in flags: var epv: epoll_event try: if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, @@ -1305,12 +1264,12 @@ else: events: set[Event]) = mixin withSelectLock s.withSelectLock(): - if eventRead in events: + if Event.Read in events: if s.rSet.fd_count == FD_SETSIZE: raise newException(ValueError, "Maximum numbers of fds exceeded") iFD_SET(fd, s.rSet) inc(s.count) - if eventWrite in events: + if Event.Write in events: if s.wSet.fd_count == FD_SETSIZE: raise newException(ValueError, "Maximum numbers of fds exceeded") iFD_SET(fd, s.wSet) @@ -1320,7 +1279,7 @@ else: proc registerHandle*[T](s: Selector[T], fd: SocketHandle, events: set[Event], data: T) = var fdi = int(fd) - var flags = {flagHandle} + events + var flags = {Event.flagHandle} + events var nkey = SelectorKey[T](ident: fdi, flags: flags) nkey.key.fd = fdi nkey.key.data = data @@ -1333,21 +1292,21 @@ else: events: set[Event]) = s.withSelectLock(): withValue(s.fds, fd, skey) do: - if flagHandle in skey.flags: + if Event.flagHandle in skey.flags: var oe = skey.flags - var ne = events + {flagHandle} + var ne = events + {Event.flagHandle} if oe != ne: - if (eventRead in oe) and (eventRead notin ne): + if (Event.Read in oe) and (Event.Read notin ne): iFD_CLR(fd, s.rSet) dec(s.count) - if (eventWrite in oe) and (eventWrite notin ne): + if (Event.Write in oe) and (Event.Write notin ne): iFD_CLR(fd, s.wSet) iFD_CLR(fd, s.eSet) dec(s.count) - if (eventRead notin oe) and (eventRead in ne): + if (Event.Read notin oe) and (Event.Read in ne): iFD_SET(fd, s.rSet) inc(s.count) - if (eventWrite notin oe) and (eventWrite in ne): + if (Event.Write notin oe) and (Event.Write in ne): iFD_SET(fd, s.wSet) iFD_SET(fd, s.eSet) inc(s.count) @@ -1384,17 +1343,17 @@ else: proc unregister*[T](s: Selector[T], fd: SocketHandle) = s.withSelectLock(): s.fds.withValue(fd, skey) do: - if eventRead in skey.flags: + if Event.Read in skey.flags: iFD_CLR(fd, s.rSet) dec(s.count) - if eventWrite in skey.flags: + if Event.Write in skey.flags: iFD_CLR(fd, s.wSet) iFD_CLR(fd, s.eSet) dec(s.count) s.fds.del(fd) proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) = - var flags = {flagUser, eventRead} + var flags = {Event.flagUser, Event.Read} var nkey = SelectorKey[T](ident: ev.rsock.int, flags: flags) nkey.key.fd = ev.rsock.int nkey.key.data = data @@ -1488,13 +1447,13 @@ else: while i < rset.fd_count: let fd = rset.fd_array[i] if iFD_ISSET(fd, rset): - var events = {eventRead} - if iFD_ISSET(fd, eset): events = events + {eventError} - if iFD_ISSET(fd, wset): events = events + {eventWrite} + var events = {Event.Read} + if iFD_ISSET(fd, eset): events = events + {Event.Error} + if iFD_ISSET(fd, wset): events = events + {Event.Write} s.fds.withValue(fd, skey) do: - if flagHandle in skey.flags: + if Event.flagHandle in skey.flags: skey.key.events = events - elif flagUser in skey.flags: + elif Event.flagUser in skey.flags: var data: int = 0 if winlean.recv(fd, cast[pointer](addr(data)), sizeof(int).cint, 0) != sizeof(int): @@ -1505,7 +1464,7 @@ else: # someone already consumed event data inc(i) continue - skey.key.events = {eventUser} + skey.key.events = {Event.User} results[rindex].fd = skey.key.fd results[rindex].data = skey.key.data results[rindex].events = skey.key.events @@ -1516,9 +1475,9 @@ else: while i < wset.fd_count: let fd = wset.fd_array[i] if iFD_ISSET(fd, wset): - var events = {eventWrite} + var events = {Event.Write} if not iFD_ISSET(fd, rset): - if iFD_ISSET(fd, eset): events = events + {eventError} + if iFD_ISSET(fd, eset): events = events + {Event.Error} s.fds.withValue(fd, skey) do: skey.key.events = events results[rindex].fd = skey.key.fd @@ -1545,35 +1504,23 @@ else: else: const MAX_POLL_RESULT_EVENTS = 64 - when hasThreadSupport: - type - SelectorImpl[T] = object - maxFD : uint - pollcnt: int - fds: ptr SharedArray[SelectorKey[T]] - pollfds: ptr SharedArray[TPollFd] - count: int + type + SelectorImpl[T] = object + maxFD : uint + pollcnt: int + fds: ptr SharedArray[SelectorKey[T]] + pollfds: ptr SharedArray[TPollFd] + count: int + when hasThreadSupport: lock: Lock - else: - type - SelectorImpl[T] = object - maxFD : uint - pollcnt: int - fds: seq[SelectorKey[T]] - pollfds: seq[TPollFd] - count: int - when hasThreadSupport: - type Selector*[T] = ptr SelectorImpl[T] - else: - type Selector*[T] = ref SelectorImpl[T] + Selector*[T] = ptr SelectorImpl[T] - type SelectEventImpl = object rfd: cint wfd: cint - type SelectEvent* = ptr SelectEventImpl + SelectEvent* = ptr SelectEventImpl when hasThreadSupport: template withPollLock[T](s: Selector[T], body: untyped) = @@ -1590,29 +1537,25 @@ else: proc newSelector*[T](): Selector[T] = var maxFD = getMaxFds() + result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T]))) + result.maxFD = maxFD.uint + result.fds = allocSharedArray[SelectorKey[T]](maxFD) + result.pollfds = allocSharedArray[TPollFd](maxFD) when hasThreadSupport: - result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T]))) - result.maxFD = maxFD.uint - result.fds = allocSharedArray[SelectorKey[T]](maxFD) - result.pollfds = allocSharedArray[TPollFd](maxFD) initLock(result.lock) - else: - result = Selector[T](maxFD: maxFD.uint) - result.fds = newSeq[SelectorKey[T]](maxFD) - result.pollfds = newSeq[TPollFd](maxFD) proc close*[T](s: Selector[T]) = when hasThreadSupport: deinitLock(s.lock) - deallocSharedArray(s.fds) - deallocSharedArray(s.pollfds) - deallocShared(cast[pointer](s)) + deallocSharedArray(s.fds) + deallocSharedArray(s.pollfds) + deallocShared(cast[pointer](s)) template pollAdd[T](s: Selector[T], sock: cint, events: set[Event]) = withPollLock(s): var pollev: cshort = 0 - if eventRead in events: pollev = pollev or POLLIN - if eventWrite in events: pollev = pollev or POLLOUT + if Event.Read in events: pollev = pollev or POLLIN + if Event.Write in events: pollev = pollev or POLLOUT s.pollfds[s.pollcnt].fd = cint(sock) s.pollfds[s.pollcnt].events = pollev inc(s.count) @@ -1622,8 +1565,8 @@ else: withPollLock(s): var i = 0 var pollev: cshort = 0 - if eventRead in events: pollev = pollev or POLLIN - if eventWrite in events: pollev = pollev or POLLOUT + if Event.Read in events: pollev = pollev or POLLIN + if Event.Write in events: pollev = pollev or POLLOUT while i < s.pollcnt: if s.pollfds[i].fd == sock: @@ -1658,11 +1601,9 @@ else: events: set[Event], data: T) = var fdi = int(fd) if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0: - setKey(s, fdi, fdi, {flagHandle} + events, 0, data) - s.pollAdd(fdi.cint, events) - else: - raise newException(ValueError, "Re-use of non-closed descriptor") + doAssert(s.fds[fdi].ident == 0) + setKey(s, fdi, fdi, {Event.flagHandle} + events, 0, data) + s.pollAdd(fdi.cint, events) else: raise newException(ValueError, "Maximum file descriptors exceeded") @@ -1670,21 +1611,16 @@ else: events: set[Event]) = var fdi = int(fd) if fdi.uint < s.maxFD: - if s.fds[fdi].ident != 0: - var oe = s.fds[fdi].flags - if flagHandle in oe: - var ne = events + {flagHandle} - if ne != oe: - if events != {}: - s.pollUpdate(fd.cint, events) - else: - s.pollRemove(fd.cint) - s.fds[fdi].flags = ne + var oe = s.fds[fdi].flags + doAssert(s.fds[fdi].ident != 0) + doAssert(Event.flagHandle in oe) + var ne = events + {Event.flagHandle} + if ne != oe: + if events != {}: + s.pollUpdate(fd.cint, events) else: - raise newException(ValueError, - "Could not update non-handle descriptor") - else: - raise newException(ValueError, "Re-use of non closed descriptor") + s.pollRemove(fd.cint) + s.fds[fdi].flags = ne else: raise newException(ValueError, "Maximum file descriptors exceeded") @@ -1702,15 +1638,10 @@ else: proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) = var fdi = int(ev.rfd) - if fdi.uint < s.maxFD: - if s.fds[fdi].ident == 0: - var events = {flagUser, eventRead} - setKey(s, fdi, fdi, events, 0, data) - s.pollAdd(fdi.cint, events) - else: - raise newException(ValueError, "Re-use of non-closed descriptor") - else: - raise newException(ValueError, "Maximum file descriptors exceeded") + doAssert(s.fds[fdi].ident == 0) + var events = {Event.flagUser, Event.Read} + setKey(s, fdi, fdi, events, 0, data) + s.pollAdd(fdi.cint, events) proc flush*[T](s: Selector[T]) = discard @@ -1727,7 +1658,7 @@ else: proc unregister*[T](s: Selector[T], ev: SelectEvent) = var fdi = int(ev.rfd) if fdi.uint < s.maxFD: - if s.fds[fdi].ident != 0 and (flagUser in s.fds[fdi].flags): + if s.fds[fdi].ident != 0 and (Event.flagUser in s.fds[fdi].flags): clearKey(s, fdi) s.pollRemove(fdi.cint) @@ -1769,16 +1700,16 @@ else: if revents != 0: var events: set[Event] = {} if (revents and POLLIN) != 0: - events = events + {eventRead} + events = events + {Event.Read} if (revents and POLLOUT) != 0: - events = events + {eventWrite} + events = events + {Event.Write} if (revents and POLLERR) != 0 or (revents and POLLHUP) != 0 or (revents and POLLNVAL) != 0: - events = events + {eventError} + events = events + {Event.Error} var skey = addr(s.fds[fd]) - if flagUser in skey.flags: - if eventRead in events: + if Event.flagUser in skey.flags: + if Event.Read in events: var data: int = 0 if posix.read(fd, addr data, sizeof(int)) != sizeof(int): let err = osLastError() @@ -1788,7 +1719,7 @@ else: # someone already consumed event data inc(i) continue - events = {eventUser} + events = {Event.User} results[rindex].fd = fd results[rindex].events = events diff --git a/tests/async/tioselectors.nim b/tests/async/tioselectors.nim index f3f38be7f..ebfe10fd6 100644 --- a/tests/async/tioselectors.nim +++ b/tests/async/tioselectors.nim @@ -38,8 +38,8 @@ when not defined(windows): var client_socket = create_test_socket() var server_socket = create_test_socket() - registerHandle(selector, server_socket, {eventRead}, 0) - registerHandle(selector, client_socket, {eventWrite}, 0) + registerHandle(selector, server_socket, {Event.Read}, 0) + registerHandle(selector, client_socket, {Event.Write}, 0) var option : int32 = 1 if setsockopt(server_socket, cint(SOL_SOCKET), cint(SO_REUSEADDR), @@ -67,13 +67,13 @@ when not defined(windows): cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) assert(server2_socket != osInvalidSocket) - selector.registerHandle(server2_socket, {eventRead}, 0) + selector.registerHandle(server2_socket, {Event.Read}, 0) if posix.send(client_socket, addr(client_message[0]), len(client_message), 0) == -1: raiseOSError(osLastError()) - selector.updateHandle(client_socket, {eventRead}) + selector.updateHandle(client_socket, {Event.Read}) var rc2 = selector.select(100) assert(len(rc2) == 1) @@ -90,13 +90,13 @@ when not defined(windows): break assert(test1) - selector.updateHandle(server2_socket, {eventWrite}) + selector.updateHandle(server2_socket, {Event.Write}) var rc3 = selector.select(0) assert(len(rc3) == 1) if posix.send(server2_socket, addr(server_message[0]), len(server_message), 0) == -1: raiseOSError(osLastError()) - selector.updateHandle(server2_socket, {eventRead}) + selector.updateHandle(server2_socket, {Event.Read}) var rc4 = selector.select(100) assert(len(rc4) == 1) @@ -238,7 +238,7 @@ when not defined(windows): var event = newEvent() for i in 0..high(thr): createThread(thr[i], event_wait_thread, event) - selector.registerHandle(sock, {eventRead}, 1) + selector.registerHandle(sock, {Event.Read}, 1) discard selector.select(500) selector.unregister(sock) event.setEvent() @@ -273,8 +273,8 @@ else: var client_socket = create_test_socket() var server_socket = create_test_socket() - selector.registerHandle(server_socket, {eventRead}, 0) - selector.registerHandle(client_socket, {eventWrite}, 0) + selector.registerHandle(server_socket, {Event.Read}, 0) + selector.registerHandle(client_socket, {Event.Write}, 0) var option : int32 = 1 if setsockopt(server_socket, cint(SOL_SOCKET), cint(SO_REUSEADDR), @@ -305,13 +305,13 @@ else: cast[ptr SockAddr](addr(sockAddress)), addr(addrLen)) assert(server2_socket != osInvalidSocket) - selector.registerHandle(server2_socket, {eventRead}, 0) + selector.registerHandle(server2_socket, {Event.Read}, 0) if send(client_socket, cast[pointer](addr(client_message[0])), cint(len(client_message)), 0) == -1: raiseOSError(osLastError()) - selector.updateHandle(client_socket, {eventRead}) + selector.updateHandle(client_socket, {Event.Read}) var rc2 = selector.select(100) assert(len(rc2) == 1) |