Event enum is now .pure.
Modified getMaxFds() to work more properly. Removed seqs from code Some exceptions replaced with doAssert
This commit is contained in:
parent
ee6257b992
commit
2eb34a8129
2 changed files with 377 additions and 446 deletions
|
|
@ -50,16 +50,16 @@ when defined(nimdoc):
|
||||||
Selector*[T] = ref object
|
Selector*[T] = ref object
|
||||||
## An object which holds descriptors to be checked for read/write status
|
## An object which holds descriptors to be checked for read/write status
|
||||||
|
|
||||||
Event* = enum
|
Event* {.pure.} = enum
|
||||||
## An enum which hold event types
|
## An enum which hold event types
|
||||||
eventRead, ## Descriptor is available for read
|
Read, ## Descriptor is available for read
|
||||||
eventWrite, ## Descriptor is available for write
|
Write, ## Descriptor is available for write
|
||||||
eventTimer, ## Timer descriptor is completed
|
Timer, ## Timer descriptor is completed
|
||||||
eventSignal, ## Signal is raised
|
Signal, ## Signal is raised
|
||||||
eventProcess, ## Process is finished
|
Process, ## Process is finished
|
||||||
eventVnode, ## Currently not supported
|
Vnode, ## Currently not supported
|
||||||
eventUser, ## User event is raised
|
User, ## User event is raised
|
||||||
eventError ## Error happens while waiting, for descriptor
|
Error ## Error happens while waiting, for descriptor
|
||||||
|
|
||||||
ReadyKey*[T] = object
|
ReadyKey*[T] = object
|
||||||
## An object which holds result for descriptor
|
## An object which holds result for descriptor
|
||||||
|
|
@ -189,10 +189,30 @@ when defined(nimdoc):
|
||||||
##
|
##
|
||||||
|
|
||||||
else:
|
else:
|
||||||
when not defined(windows):
|
when defined(macosx) or defined(freebsd):
|
||||||
when defined(macosx):
|
when defined(macosx):
|
||||||
var
|
const maxDescriptors = 29 # KERN_MAXFILESPERPROC (MacOS)
|
||||||
OPEN_MAX {.importc: "OPEN_MAX", header: "<sys/resource.h>".}: cint
|
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
|
var
|
||||||
RLIMIT_NOFILE {.importc: "RLIMIT_NOFILE",
|
RLIMIT_NOFILE {.importc: "RLIMIT_NOFILE",
|
||||||
header: "<sys/resource.h>".}: cint
|
header: "<sys/resource.h>".}: cint
|
||||||
|
|
@ -201,24 +221,36 @@ else:
|
||||||
header: "<sys/resource.h>", pure, final.} = object
|
header: "<sys/resource.h>", pure, final.} = object
|
||||||
rlim_cur: int
|
rlim_cur: int
|
||||||
rlim_max: int
|
rlim_max: int
|
||||||
proc getrlimit(resource: cint, rlp: var rlimit): cint {.
|
proc getrlimit(resource: cint, rlp: var rlimit): cint
|
||||||
importc: "getrlimit",header: "<sys/resource.h>"}
|
{.importc: "getrlimit",header: "<sys/resource.h>".}
|
||||||
|
|
||||||
proc getMaxFds*(): int =
|
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()
|
var a = rlimit()
|
||||||
if getrlimit(RLIMIT_NOFILE, a) != 0:
|
if getrlimit(RLIMIT_NOFILE, a) != 0:
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
result = a.rlim_max
|
result = a.rlim_max
|
||||||
when defined(macosx):
|
|
||||||
if a.rlim_max > OPEN_MAX:
|
|
||||||
result = OPEN_MAX
|
|
||||||
|
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
import locks
|
import locks
|
||||||
|
|
||||||
type
|
type
|
||||||
Event* = enum
|
Event* {.pure.} = enum
|
||||||
eventRead, eventWrite, eventTimer, eventSignal, eventProcess,
|
Read, Write, Timer, Signal, Process, Vnode, User, Error,
|
||||||
eventVnode, eventUser, eventError,
|
|
||||||
flagHandle, flagTimer, flagSignal, flagProcess, flagVnode, flagUser,
|
flagHandle, flagTimer, flagSignal, flagProcess, flagVnode, flagUser,
|
||||||
flagOneshot
|
flagOneshot
|
||||||
|
|
||||||
|
|
@ -234,7 +266,6 @@ else:
|
||||||
key : ReadyKey[T]
|
key : ReadyKey[T]
|
||||||
|
|
||||||
when not defined(windows):
|
when not defined(windows):
|
||||||
when hasThreadSupport:
|
|
||||||
type
|
type
|
||||||
SharedArrayHolder[T] = object
|
SharedArrayHolder[T] = object
|
||||||
part: array[16, T]
|
part: array[16, T]
|
||||||
|
|
@ -298,7 +329,6 @@ else:
|
||||||
MAX_KQUEUE_CHANGE_EVENTS = 64
|
MAX_KQUEUE_CHANGE_EVENTS = 64
|
||||||
MAX_KQUEUE_RESULT_EVENTS = 64
|
MAX_KQUEUE_RESULT_EVENTS = 64
|
||||||
|
|
||||||
when hasThreadSupport:
|
|
||||||
type
|
type
|
||||||
SelectorImpl[T] = object
|
SelectorImpl[T] = object
|
||||||
kqFD : cint
|
kqFD : cint
|
||||||
|
|
@ -307,21 +337,9 @@ else:
|
||||||
changesCount: int
|
changesCount: int
|
||||||
fds: ptr SharedArray[SelectorKey[T]]
|
fds: ptr SharedArray[SelectorKey[T]]
|
||||||
count: int
|
count: int
|
||||||
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:
|
when hasThreadSupport:
|
||||||
type Selector*[T] = ptr SelectorImpl[T]
|
changesLock: Lock
|
||||||
else:
|
Selector*[T] = ptr SelectorImpl[T]
|
||||||
type Selector*[T] = ref SelectorImpl[T]
|
|
||||||
|
|
||||||
type
|
type
|
||||||
SelectEventImpl = object
|
SelectEventImpl = object
|
||||||
|
|
@ -336,15 +354,13 @@ else:
|
||||||
var kqFD = kqueue()
|
var kqFD = kqueue()
|
||||||
if kqFD < 0:
|
if kqFD < 0:
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
when hasThreadSupport:
|
|
||||||
result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T])))
|
result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T])))
|
||||||
result.kqFD = kqFD
|
result.kqFD = kqFD
|
||||||
result.maxFD = maxFD.uint
|
result.maxFD = maxFD.uint
|
||||||
result.fds = allocSharedArray[SelectorKey[T]](maxFD)
|
result.fds = allocSharedArray[SelectorKey[T]](maxFD)
|
||||||
|
when hasThreadSupport:
|
||||||
initLock(result.changesLock)
|
initLock(result.changesLock)
|
||||||
else:
|
|
||||||
result = Selector[T](kqFD: kqFD, maxFD: maxFD.uint)
|
|
||||||
result.fds = newSeq[SelectorKey[T]](maxFD)
|
|
||||||
|
|
||||||
proc close*[T](s: Selector[T]) =
|
proc close*[T](s: Selector[T]) =
|
||||||
if posix.close(s.kqFD) != 0:
|
if posix.close(s.kqFD) != 0:
|
||||||
|
|
@ -386,17 +402,15 @@ else:
|
||||||
events: set[Event], data: T) =
|
events: set[Event], data: T) =
|
||||||
var fdi = int(fd)
|
var fdi = int(fd)
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident == 0:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
setKey(s, fdi, fdi, {flagHandle} + events, 0, data)
|
setKey(s, fdi, fdi, {Event.flagHandle} + events, 0, data)
|
||||||
if events != {}:
|
if events != {}:
|
||||||
if eventRead in events:
|
if Event.Read in events:
|
||||||
modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil)
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
if eventWrite in events:
|
if Event.Write in events:
|
||||||
modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_ADD, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_ADD, 0, 0, nil)
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
|
|
||||||
|
|
@ -404,30 +418,24 @@ else:
|
||||||
events: set[Event]) =
|
events: set[Event]) =
|
||||||
var fdi = int(fd)
|
var fdi = int(fd)
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident != 0:
|
doAssert(s.fds[fdi].ident != 0)
|
||||||
if flagHandle in s.fds[fdi].flags:
|
doAssert(Event.flagHandle in s.fds[fdi].flags)
|
||||||
var ne = events + {flagHandle}
|
var ne = events + {Event.flagHandle}
|
||||||
var oe = s.fds[fdi].flags
|
var oe = s.fds[fdi].flags
|
||||||
if oe != ne:
|
if oe != ne:
|
||||||
if (eventRead in oe) and (eventRead notin ne):
|
if (Event.Read in oe) and (Event.Read notin ne):
|
||||||
modifyKQueue(s, fdi.uint, EVFILT_READ, EV_DELETE, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, EVFILT_READ, EV_DELETE, 0, 0, nil)
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
if (eventWrite in oe) and (eventWrite notin ne):
|
if (Event.Write in oe) and (Event.Write notin ne):
|
||||||
modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_DELETE, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_DELETE, 0, 0, nil)
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
if (eventRead notin oe) and (eventRead in ne):
|
if (Event.Read notin oe) and (Event.Read in ne):
|
||||||
modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil)
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
if (eventWrite notin oe) and (eventWrite in ne):
|
if (Event.Write notin oe) and (Event.Write in ne):
|
||||||
modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_ADD, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_ADD, 0, 0, nil)
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
s.fds[fdi].flags = ne
|
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")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
|
|
||||||
|
|
@ -438,9 +446,9 @@ else:
|
||||||
if fdi == -1:
|
if fdi == -1:
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident == 0:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
var mflags = if oneshot: {flagTimer, flagOneshot}
|
var mflags = if oneshot: {Event.flagTimer, Event.flagOneshot}
|
||||||
else: {flagTimer}
|
else: {Event.flagTimer}
|
||||||
var kflags: cushort = if oneshot: EV_ONESHOT or EV_ADD
|
var kflags: cushort = if oneshot: EV_ONESHOT or EV_ADD
|
||||||
else: EV_ADD
|
else: EV_ADD
|
||||||
setKey(s, fdi, fdi, mflags, 0, data)
|
setKey(s, fdi, fdi, mflags, 0, data)
|
||||||
|
|
@ -450,8 +458,6 @@ else:
|
||||||
modifyKQueue(s, fdi.uint, EVFILT_TIMER, kflags, 0, cint(timeout), nil)
|
modifyKQueue(s, fdi.uint, EVFILT_TIMER, kflags, 0, cint(timeout), nil)
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
result = fdi
|
result = fdi
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
|
|
||||||
|
|
@ -463,8 +469,8 @@ else:
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
|
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident == 0:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
setKey(s, fdi, signal, {flagSignal}, signal, data)
|
setKey(s, fdi, signal, {Event.flagSignal}, signal, data)
|
||||||
# block signal `signal`
|
# block signal `signal`
|
||||||
var nmask: Sigset
|
var nmask: Sigset
|
||||||
var omask: Sigset
|
var omask: Sigset
|
||||||
|
|
@ -478,8 +484,6 @@ else:
|
||||||
cast[pointer](fdi))
|
cast[pointer](fdi))
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
result = fdi
|
result = fdi
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
|
|
||||||
|
|
@ -491,15 +495,13 @@ else:
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
|
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident == 0:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
var kflags: cushort = EV_ONESHOT or EV_ADD
|
var kflags: cushort = EV_ONESHOT or EV_ADD
|
||||||
setKey(s, fdi, pid, {flagProcess, flagOneshot}, pid, data)
|
setKey(s, fdi, pid, {Event.flagProcess, Event.flagOneshot}, pid, data)
|
||||||
modifyKQueue(s, pid.uint, EVFILT_PROC, kflags, NOTE_EXIT, 0,
|
modifyKQueue(s, pid.uint, EVFILT_PROC, kflags, NOTE_EXIT, 0,
|
||||||
cast[pointer](fdi))
|
cast[pointer](fdi))
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
result = fdi
|
result = fdi
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
|
|
||||||
|
|
@ -509,22 +511,22 @@ else:
|
||||||
var flags = s.fds[fdi].flags
|
var flags = s.fds[fdi].flags
|
||||||
var filter: cshort = 0
|
var filter: cshort = 0
|
||||||
if s.fds[fdi].ident != 0 and flags != {}:
|
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
|
# if events == 0, than descriptor was modified with
|
||||||
# updateHandle(fd, 0), so it was already deleted from kqueue.
|
# updateHandle(fd, 0), so it was already deleted from kqueue.
|
||||||
if flags != {flagHandle}:
|
if flags != {Event.flagHandle}:
|
||||||
if eventRead in flags:
|
if Event.Read in flags:
|
||||||
modifyKQueue(s, fdi.uint, EVFILT_READ, EV_DELETE, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, EVFILT_READ, EV_DELETE, 0, 0, nil)
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
if eventWrite in flags:
|
if Event.Write in flags:
|
||||||
modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_DELETE, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, EVFILT_WRITE, EV_DELETE, 0, 0, nil)
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
elif flagTimer in flags:
|
elif Event.flagTimer in flags:
|
||||||
filter = EVFILT_TIMER
|
filter = EVFILT_TIMER
|
||||||
discard posix.close(cint(s.fds[fdi].key.fd))
|
discard posix.close(cint(s.fds[fdi].key.fd))
|
||||||
modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil)
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
elif flagSignal in flags:
|
elif Event.flagSignal in flags:
|
||||||
filter = EVFILT_SIGNAL
|
filter = EVFILT_SIGNAL
|
||||||
# unblocking signal
|
# unblocking signal
|
||||||
var nmask = Sigset()
|
var nmask = Sigset()
|
||||||
|
|
@ -536,12 +538,12 @@ else:
|
||||||
discard posix.close(cint(s.fds[fdi].key.fd))
|
discard posix.close(cint(s.fds[fdi].key.fd))
|
||||||
modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil)
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
elif flagProcess in flags:
|
elif Event.flagProcess in flags:
|
||||||
filter = EVFILT_PROC
|
filter = EVFILT_PROC
|
||||||
discard posix.close(cint(s.fds[fdi].key.fd))
|
discard posix.close(cint(s.fds[fdi].key.fd))
|
||||||
modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil)
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
elif flagUser in flags:
|
elif Event.flagUser in flags:
|
||||||
filter = EVFILT_READ
|
filter = EVFILT_READ
|
||||||
modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, filter, EV_DELETE, 0, 0, nil)
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
|
|
@ -583,15 +585,10 @@ else:
|
||||||
|
|
||||||
proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) =
|
proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) =
|
||||||
let fdi = ev.rfd.int
|
let fdi = ev.rfd.int
|
||||||
if fdi.uint < s.maxFD:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
if s.fds[fdi].ident == 0 and s.fds[fdi].flags == {}:
|
setKey(s, fdi, fdi, {Event.flagUser}, 0, data)
|
||||||
setKey(s, fdi, fdi, {flagUser}, 0, data)
|
|
||||||
modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil)
|
modifyKQueue(s, fdi.uint, EVFILT_READ, EV_ADD, 0, 0, nil)
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Event wait still pending!")
|
|
||||||
|
|
||||||
proc unregister*[T](s: Selector[T], ev: SelectEvent) =
|
proc unregister*[T](s: Selector[T], ev: SelectEvent) =
|
||||||
let fdi = ev.rfd.int
|
let fdi = ev.rfd.int
|
||||||
|
|
@ -640,9 +637,9 @@ else:
|
||||||
case kevent.filter
|
case kevent.filter
|
||||||
of EVFILT_READ:
|
of EVFILT_READ:
|
||||||
skey = addr(s.fds[kevent.ident.int])
|
skey = addr(s.fds[kevent.ident.int])
|
||||||
if flagHandle in skey.flags:
|
if Event.flagHandle in skey.flags:
|
||||||
events = {eventRead}
|
events = {Event.Read}
|
||||||
elif flagUser in skey.flags:
|
elif Event.flagUser in skey.flags:
|
||||||
var data: int = 0
|
var data: int = 0
|
||||||
if posix.read(kevent.ident.cint, addr data,
|
if posix.read(kevent.ident.cint, addr data,
|
||||||
sizeof(int)) != sizeof(int):
|
sizeof(int)) != sizeof(int):
|
||||||
|
|
@ -653,28 +650,28 @@ else:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
events = {eventUser}
|
events = {Event.User}
|
||||||
else:
|
else:
|
||||||
events = {eventRead}
|
events = {Event.Read}
|
||||||
of EVFILT_WRITE:
|
of EVFILT_WRITE:
|
||||||
skey = addr(s.fds[kevent.ident.int])
|
skey = addr(s.fds[kevent.ident.int])
|
||||||
events = {eventWrite}
|
events = {Event.Write}
|
||||||
of EVFILT_TIMER:
|
of EVFILT_TIMER:
|
||||||
skey = addr(s.fds[kevent.ident.int])
|
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:
|
if posix.close(skey.ident.cint) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
clearKey(s, skey.ident)
|
clearKey(s, skey.ident)
|
||||||
# no need to modify kqueue, because EV_ONESHOT is already made
|
# no need to modify kqueue, because EV_ONESHOT is already made
|
||||||
# this for us
|
# this for us
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
events = {eventTimer}
|
events = {Event.Timer}
|
||||||
of EVFILT_VNODE:
|
of EVFILT_VNODE:
|
||||||
skey = addr(s.fds[kevent.ident.int])
|
skey = addr(s.fds[kevent.ident.int])
|
||||||
events = {eventVnode}
|
events = {Event.Vnode}
|
||||||
of EVFILT_SIGNAL:
|
of EVFILT_SIGNAL:
|
||||||
skey = addr(s.fds[cast[int](kevent.udata)])
|
skey = addr(s.fds[cast[int](kevent.udata)])
|
||||||
events = {eventSignal}
|
events = {Event.Signal}
|
||||||
of EVFILT_PROC:
|
of EVFILT_PROC:
|
||||||
skey = addr(s.fds[cast[int](kevent.udata)])
|
skey = addr(s.fds[cast[int](kevent.udata)])
|
||||||
if posix.close(skey.ident.cint) == -1:
|
if posix.close(skey.ident.cint) == -1:
|
||||||
|
|
@ -683,13 +680,13 @@ else:
|
||||||
# no need to modify kqueue, because EV_ONESHOT is already made
|
# no need to modify kqueue, because EV_ONESHOT is already made
|
||||||
# this for us
|
# this for us
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
events = {eventProcess}
|
events = {Event.Process}
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Unsupported kqueue filter in queue")
|
"Unsupported kqueue filter in queue")
|
||||||
|
|
||||||
if (kevent.flags and EV_EOF) != 0:
|
if (kevent.flags and EV_EOF) != 0:
|
||||||
events = events + {eventError}
|
events = events + {Event.Error}
|
||||||
results[k].fd = skey.key.fd
|
results[k].fd = skey.key.fd
|
||||||
results[k].events = events
|
results[k].events = events
|
||||||
results[k].data = skey.key.data
|
results[k].data = skey.key.data
|
||||||
|
|
@ -775,50 +772,35 @@ else:
|
||||||
proc eventfd(count: cuint, flags: cint): cint
|
proc eventfd(count: cuint, flags: cint): cint
|
||||||
{.cdecl, importc: "eventfd", header: "<sys/eventfd.h>".}
|
{.cdecl, importc: "eventfd", header: "<sys/eventfd.h>".}
|
||||||
|
|
||||||
when hasThreadSupport:
|
|
||||||
type
|
type
|
||||||
SelectorImpl[T] = object
|
SelectorImpl[T] = object
|
||||||
epollFD : cint
|
epollFD : cint
|
||||||
maxFD : uint
|
maxFD : uint
|
||||||
fds: ptr SharedArray[SelectorKey[T]]
|
fds: ptr SharedArray[SelectorKey[T]]
|
||||||
count: int
|
count: int
|
||||||
else:
|
|
||||||
type
|
|
||||||
SelectorImpl[T] = object
|
|
||||||
epollFD : cint
|
|
||||||
maxFD : uint
|
|
||||||
fds: seq[SelectorKey[T]]
|
|
||||||
count: int
|
|
||||||
|
|
||||||
when hasThreadSupport:
|
Selector*[T] = ptr SelectorImpl[T]
|
||||||
type Selector*[T] = ptr SelectorImpl[T]
|
|
||||||
else:
|
|
||||||
type Selector*[T] = ref SelectorImpl[T]
|
|
||||||
|
|
||||||
type
|
|
||||||
SelectEventImpl = object
|
SelectEventImpl = object
|
||||||
efd: cint
|
efd: cint
|
||||||
|
|
||||||
type SelectEvent* = ptr SelectEventImpl
|
SelectEvent* = ptr SelectEventImpl
|
||||||
|
|
||||||
proc newSelector*[T](): Selector[T] =
|
proc newSelector*[T](): Selector[T] =
|
||||||
var maxFD = getMaxFds()
|
var maxFD = getMaxFds()
|
||||||
var epollFD = epoll_create(MAX_EPOLL_RESULT_EVENTS)
|
var epollFD = epoll_create(MAX_EPOLL_RESULT_EVENTS)
|
||||||
if epollFD < 0:
|
if epollFD < 0:
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
when hasThreadSupport:
|
|
||||||
result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T])))
|
result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T])))
|
||||||
result.epollFD = epollFD
|
result.epollFD = epollFD
|
||||||
result.maxFD = maxFD.uint
|
result.maxFD = maxFD.uint
|
||||||
result.fds = allocSharedArray[SelectorKey[T]](maxFD)
|
result.fds = allocSharedArray[SelectorKey[T]](maxFD)
|
||||||
else:
|
|
||||||
result = Selector[T](epollFD: epollFD, maxFD: maxFD.uint)
|
|
||||||
result.fds = newSeq[SelectorKey[T]](maxFD)
|
|
||||||
|
|
||||||
proc close*[T](s: Selector[T]) =
|
proc close*[T](s: Selector[T]) =
|
||||||
if posix.close(s.epollFD) != 0:
|
if posix.close(s.epollFD) != 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
when hasThreadSupport:
|
|
||||||
deallocSharedArray(s.fds)
|
deallocSharedArray(s.fds)
|
||||||
deallocShared(cast[pointer](s))
|
deallocShared(cast[pointer](s))
|
||||||
|
|
||||||
|
|
@ -826,21 +808,19 @@ else:
|
||||||
events: set[Event], data: T) =
|
events: set[Event], data: T) =
|
||||||
var fdi = int(fd)
|
var fdi = int(fd)
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident == 0:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
setKey(s, fdi, fdi, events + {flagHandle}, 0, data)
|
setKey(s, fdi, fdi, events + {Event.flagHandle}, 0, data)
|
||||||
if events != {}:
|
if events != {}:
|
||||||
var epv: epoll_event
|
var epv: epoll_event
|
||||||
epv.events = EPOLLRDHUP
|
epv.events = EPOLLRDHUP
|
||||||
epv.data.u64 = fdi.uint
|
epv.data.u64 = fdi.uint
|
||||||
if eventRead in events:
|
if Event.Read in events:
|
||||||
epv.events = epv.events or EPOLLIN
|
epv.events = epv.events or EPOLLIN
|
||||||
if eventWrite in events:
|
if Event.Write in events:
|
||||||
epv.events = epv.events or EPOLLOUT
|
epv.events = epv.events or EPOLLOUT
|
||||||
if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1:
|
if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
|
|
||||||
|
|
@ -848,22 +828,22 @@ else:
|
||||||
events: set[Event]) =
|
events: set[Event]) =
|
||||||
var fdi = int(fd)
|
var fdi = int(fd)
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident != 0:
|
|
||||||
var oe = s.fds[fdi].flags
|
var oe = s.fds[fdi].flags
|
||||||
if flagHandle in oe:
|
doAssert(s.fds[fdi].ident != 0)
|
||||||
var ne = events + {flagHandle}
|
doAssert(Event.flagHandle in oe)
|
||||||
|
var ne = events + {Event.flagHandle}
|
||||||
if oe != ne:
|
if oe != ne:
|
||||||
var epv: epoll_event
|
var epv: epoll_event
|
||||||
epv.data.u64 = fdi.uint
|
epv.data.u64 = fdi.uint
|
||||||
epv.events = EPOLLRDHUP
|
epv.events = EPOLLRDHUP
|
||||||
|
|
||||||
if eventRead in events:
|
if Event.Read in events:
|
||||||
epv.events = epv.events or EPOLLIN
|
epv.events = epv.events or EPOLLIN
|
||||||
if eventWrite in events:
|
if Event.Write in events:
|
||||||
epv.events = epv.events or EPOLLOUT
|
epv.events = epv.events or EPOLLOUT
|
||||||
|
|
||||||
if oe == {flagHandle}:
|
if oe == {Event.flagHandle}:
|
||||||
if ne != {flagHandle}:
|
if ne != {Event.flagHandle}:
|
||||||
if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint,
|
if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint,
|
||||||
addr epv) == -1:
|
addr epv) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
|
|
@ -879,12 +859,6 @@ else:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
s.fds[fdi].flags = ne
|
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")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
|
|
||||||
|
|
@ -894,21 +868,21 @@ else:
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
var flags = s.fds[fdi].flags
|
var flags = s.fds[fdi].flags
|
||||||
if s.fds[fdi].ident != 0 and 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
|
# if events == {flagHandle}, then descriptor was already
|
||||||
# unregistered from epoll with updateHandle() call.
|
# unregistered from epoll with updateHandle() call.
|
||||||
# This check is done to omit EBADF error.
|
# 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,
|
if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint,
|
||||||
addr epv) == -1:
|
addr epv) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
dec(s.count)
|
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:
|
if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
discard posix.close(fdi.cint)
|
discard posix.close(fdi.cint)
|
||||||
dec(s.count)
|
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:
|
if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
var nmask: Sigset
|
var nmask: Sigset
|
||||||
|
|
@ -919,7 +893,7 @@ else:
|
||||||
unblockSignals(nmask, omask)
|
unblockSignals(nmask, omask)
|
||||||
discard posix.close(fdi.cint)
|
discard posix.close(fdi.cint)
|
||||||
dec(s.count)
|
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:
|
if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
var nmask: Sigset
|
var nmask: Sigset
|
||||||
|
|
@ -935,7 +909,7 @@ else:
|
||||||
proc unregister*[T](s: Selector[T], ev: SelectEvent) =
|
proc unregister*[T](s: Selector[T], ev: SelectEvent) =
|
||||||
let fdi = int(ev.efd)
|
let fdi = int(ev.efd)
|
||||||
if fdi.uint < s.maxFD:
|
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)
|
clearKey(s, fdi)
|
||||||
var epv: epoll_event
|
var epv: epoll_event
|
||||||
if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) == -1:
|
if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint, addr epv) == -1:
|
||||||
|
|
@ -951,8 +925,8 @@ else:
|
||||||
if fdi == -1:
|
if fdi == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident == 0:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
var flags = {flagTimer}
|
var flags = {Event.flagTimer}
|
||||||
var epv: epoll_event
|
var epv: epoll_event
|
||||||
epv.data.u64 = fdi.uint
|
epv.data.u64 = fdi.uint
|
||||||
epv.events = EPOLLIN or EPOLLRDHUP
|
epv.events = EPOLLIN or EPOLLRDHUP
|
||||||
|
|
@ -962,7 +936,7 @@ else:
|
||||||
new_ts.it_interval.tv_nsec = 0
|
new_ts.it_interval.tv_nsec = 0
|
||||||
new_ts.it_value.tv_sec = (timeout div 1_000).Time
|
new_ts.it_value.tv_sec = (timeout div 1_000).Time
|
||||||
new_ts.it_value.tv_nsec = (timeout %% 1_000) * 1_000_000
|
new_ts.it_value.tv_nsec = (timeout %% 1_000) * 1_000_000
|
||||||
flags = flags + {flagOneshot}
|
flags = flags + {Event.flagOneshot}
|
||||||
epv.events = epv.events or EPOLLONESHOT
|
epv.events = epv.events or EPOLLONESHOT
|
||||||
else:
|
else:
|
||||||
new_ts.it_interval.tv_sec = (timeout div 1000).Time
|
new_ts.it_interval.tv_sec = (timeout div 1000).Time
|
||||||
|
|
@ -976,8 +950,6 @@ else:
|
||||||
setKey(s, fdi, fdi, flags, 0, data)
|
setKey(s, fdi, fdi, flags, 0, data)
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
result = fdi
|
result = fdi
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
|
|
||||||
|
|
@ -995,18 +967,16 @@ else:
|
||||||
if fdi == -1:
|
if fdi == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident == 0:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
setNonBlocking(fdi.cint)
|
setNonBlocking(fdi.cint)
|
||||||
var epv: epoll_event
|
var epv: epoll_event
|
||||||
epv.data.u64 = fdi.uint
|
epv.data.u64 = fdi.uint
|
||||||
epv.events = EPOLLIN or EPOLLRDHUP
|
epv.events = EPOLLIN or EPOLLRDHUP
|
||||||
if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1:
|
if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
setKey(s, fdi, signal, {flagSignal}, signal, data)
|
setKey(s, fdi, signal, {Event.flagSignal}, signal, data)
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
result = fdi
|
result = fdi
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
|
|
||||||
|
|
@ -1020,28 +990,22 @@ else:
|
||||||
discard sigemptyset(omask)
|
discard sigemptyset(omask)
|
||||||
discard sigaddset(nmask, posix.SIGCHLD)
|
discard sigaddset(nmask, posix.SIGCHLD)
|
||||||
blockSignals(nmask, omask)
|
blockSignals(nmask, omask)
|
||||||
try:
|
|
||||||
var fdi = signalfd(-1, nmask, 0)
|
var fdi = signalfd(-1, nmask, 0)
|
||||||
if fd == -1:
|
if fd == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident == 0:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
setNonBlocking(fdi.cint)
|
setNonBlocking(fdi.cint)
|
||||||
var epv: epoll_event
|
var epv: epoll_event
|
||||||
epv.data.u64 = fdi.uint
|
epv.data.u64 = fdi.uint
|
||||||
epv.events = EPOLLIN or EPOLLRDHUP
|
epv.events = EPOLLIN or EPOLLRDHUP
|
||||||
if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1:
|
if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, fdi.cint, addr epv) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
setKey(s, fdi, pid, {flagProcess}, pid, data)
|
setKey(s, fdi, pid, {Event.flagProcess}, pid, data)
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
result = fdi
|
result = fdi
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
except:
|
|
||||||
if fd != -1: discard posix.close(fd.cint)
|
|
||||||
unblockSignals(omask, nmask)
|
|
||||||
|
|
||||||
proc flush*[T](s: Selector[T]) =
|
proc flush*[T](s: Selector[T]) =
|
||||||
discard
|
discard
|
||||||
|
|
@ -1051,18 +1015,13 @@ else:
|
||||||
|
|
||||||
proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) =
|
proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) =
|
||||||
let fdi = int(ev.efd)
|
let fdi = int(ev.efd)
|
||||||
if fdi.uint < s.maxFD:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
if s.fds[fdi].ident == 0:
|
setKey(s, fdi, fdi, {Event.flagUser}, 0, data)
|
||||||
setKey(s, fdi, fdi, {flagUser}, 0, data)
|
|
||||||
var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP)
|
var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP)
|
||||||
epv.data.u64 = ev.efd.uint
|
epv.data.u64 = ev.efd.uint
|
||||||
if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, ev.efd, addr epv) == -1:
|
if epoll_ctl(s.epollFD, EPOLL_CTL_ADD, ev.efd, addr epv) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
|
||||||
|
|
||||||
proc setEvent*(ev: SelectEvent) =
|
proc setEvent*(ev: SelectEvent) =
|
||||||
var data : uint64 = 1
|
var data : uint64 = 1
|
||||||
|
|
@ -1105,36 +1064,36 @@ else:
|
||||||
if skey.ident != 0 and flags != {}:
|
if skey.ident != 0 and flags != {}:
|
||||||
block processItem:
|
block processItem:
|
||||||
if (pevents and EPOLLERR) != 0 or (pevents and EPOLLHUP) != 0:
|
if (pevents and EPOLLERR) != 0 or (pevents and EPOLLHUP) != 0:
|
||||||
events = events + {eventError}
|
events = events + {Event.Error}
|
||||||
if (pevents and EPOLLOUT) != 0:
|
if (pevents and EPOLLOUT) != 0:
|
||||||
events = events + {eventWrite}
|
events = events + {Event.Write}
|
||||||
if (pevents and EPOLLIN) != 0:
|
if (pevents and EPOLLIN) != 0:
|
||||||
if flagHandle in flags:
|
if Event.flagHandle in flags:
|
||||||
events = events + {eventRead}
|
events = events + {Event.Read}
|
||||||
elif flagTimer in flags:
|
elif Event.flagTimer in flags:
|
||||||
var data: uint64 = 0
|
var data: uint64 = 0
|
||||||
if posix.read(fdi.cint, addr data,
|
if posix.read(fdi.cint, addr data,
|
||||||
sizeof(uint64)) != sizeof(uint64):
|
sizeof(uint64)) != sizeof(uint64):
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
events = events + {eventTimer}
|
events = events + {Event.Timer}
|
||||||
elif flagSignal in flags:
|
elif Event.flagSignal in flags:
|
||||||
var data: SignalFdInfo
|
var data: SignalFdInfo
|
||||||
if posix.read(fdi.cint, addr data,
|
if posix.read(fdi.cint, addr data,
|
||||||
sizeof(SignalFdInfo)) != sizeof(SignalFdInfo):
|
sizeof(SignalFdInfo)) != sizeof(SignalFdInfo):
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
events = events + {eventSignal}
|
events = events + {Event.Signal}
|
||||||
elif flagProcess in flags:
|
elif Event.flagProcess in flags:
|
||||||
var data: SignalFdInfo
|
var data: SignalFdInfo
|
||||||
if posix.read(fdi.cint, addr data,
|
if posix.read(fdi.cint, addr data,
|
||||||
sizeof(SignalFdInfo)) != sizeof(SignalFdInfo):
|
sizeof(SignalFdInfo)) != sizeof(SignalFdInfo):
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
if cast[int](data.ssi_pid) == skey.param:
|
if cast[int](data.ssi_pid) == skey.param:
|
||||||
events = events + {eventProcess}
|
events = events + {Event.Process}
|
||||||
# we want to free resources for this event
|
# we want to free resources for this event
|
||||||
flags = flags + {flagOneshot}
|
flags = flags + {Event.flagOneshot}
|
||||||
else:
|
else:
|
||||||
break processItem
|
break processItem
|
||||||
elif flagUser in flags:
|
elif Event.flagUser in flags:
|
||||||
var data: uint = 0
|
var data: uint = 0
|
||||||
if posix.read(fdi.cint, addr data,
|
if posix.read(fdi.cint, addr data,
|
||||||
sizeof(uint)) != sizeof(uint):
|
sizeof(uint)) != sizeof(uint):
|
||||||
|
|
@ -1145,7 +1104,7 @@ else:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
raiseOSError(err)
|
raiseOSError(err)
|
||||||
events = events + {eventUser}
|
events = events + {Event.User}
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Unsupported epoll event in queue")
|
"Unsupported epoll event in queue")
|
||||||
|
|
@ -1153,7 +1112,7 @@ else:
|
||||||
results[k].events = events
|
results[k].events = events
|
||||||
results[k].data = skey.key.data
|
results[k].data = skey.key.data
|
||||||
|
|
||||||
if flagOneshot in flags:
|
if Event.flagOneshot in flags:
|
||||||
var epv: epoll_event
|
var epv: epoll_event
|
||||||
try:
|
try:
|
||||||
if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint,
|
if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, fdi.cint,
|
||||||
|
|
@ -1305,12 +1264,12 @@ else:
|
||||||
events: set[Event]) =
|
events: set[Event]) =
|
||||||
mixin withSelectLock
|
mixin withSelectLock
|
||||||
s.withSelectLock():
|
s.withSelectLock():
|
||||||
if eventRead in events:
|
if Event.Read in events:
|
||||||
if s.rSet.fd_count == FD_SETSIZE:
|
if s.rSet.fd_count == FD_SETSIZE:
|
||||||
raise newException(ValueError, "Maximum numbers of fds exceeded")
|
raise newException(ValueError, "Maximum numbers of fds exceeded")
|
||||||
iFD_SET(fd, s.rSet)
|
iFD_SET(fd, s.rSet)
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
if eventWrite in events:
|
if Event.Write in events:
|
||||||
if s.wSet.fd_count == FD_SETSIZE:
|
if s.wSet.fd_count == FD_SETSIZE:
|
||||||
raise newException(ValueError, "Maximum numbers of fds exceeded")
|
raise newException(ValueError, "Maximum numbers of fds exceeded")
|
||||||
iFD_SET(fd, s.wSet)
|
iFD_SET(fd, s.wSet)
|
||||||
|
|
@ -1320,7 +1279,7 @@ else:
|
||||||
proc registerHandle*[T](s: Selector[T], fd: SocketHandle,
|
proc registerHandle*[T](s: Selector[T], fd: SocketHandle,
|
||||||
events: set[Event], data: T) =
|
events: set[Event], data: T) =
|
||||||
var fdi = int(fd)
|
var fdi = int(fd)
|
||||||
var flags = {flagHandle} + events
|
var flags = {Event.flagHandle} + events
|
||||||
var nkey = SelectorKey[T](ident: fdi, flags: flags)
|
var nkey = SelectorKey[T](ident: fdi, flags: flags)
|
||||||
nkey.key.fd = fdi
|
nkey.key.fd = fdi
|
||||||
nkey.key.data = data
|
nkey.key.data = data
|
||||||
|
|
@ -1333,21 +1292,21 @@ else:
|
||||||
events: set[Event]) =
|
events: set[Event]) =
|
||||||
s.withSelectLock():
|
s.withSelectLock():
|
||||||
withValue(s.fds, fd, skey) do:
|
withValue(s.fds, fd, skey) do:
|
||||||
if flagHandle in skey.flags:
|
if Event.flagHandle in skey.flags:
|
||||||
var oe = skey.flags
|
var oe = skey.flags
|
||||||
var ne = events + {flagHandle}
|
var ne = events + {Event.flagHandle}
|
||||||
if oe != ne:
|
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)
|
iFD_CLR(fd, s.rSet)
|
||||||
dec(s.count)
|
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.wSet)
|
||||||
iFD_CLR(fd, s.eSet)
|
iFD_CLR(fd, s.eSet)
|
||||||
dec(s.count)
|
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)
|
iFD_SET(fd, s.rSet)
|
||||||
inc(s.count)
|
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.wSet)
|
||||||
iFD_SET(fd, s.eSet)
|
iFD_SET(fd, s.eSet)
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
|
|
@ -1384,17 +1343,17 @@ else:
|
||||||
proc unregister*[T](s: Selector[T], fd: SocketHandle) =
|
proc unregister*[T](s: Selector[T], fd: SocketHandle) =
|
||||||
s.withSelectLock():
|
s.withSelectLock():
|
||||||
s.fds.withValue(fd, skey) do:
|
s.fds.withValue(fd, skey) do:
|
||||||
if eventRead in skey.flags:
|
if Event.Read in skey.flags:
|
||||||
iFD_CLR(fd, s.rSet)
|
iFD_CLR(fd, s.rSet)
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
if eventWrite in skey.flags:
|
if Event.Write in skey.flags:
|
||||||
iFD_CLR(fd, s.wSet)
|
iFD_CLR(fd, s.wSet)
|
||||||
iFD_CLR(fd, s.eSet)
|
iFD_CLR(fd, s.eSet)
|
||||||
dec(s.count)
|
dec(s.count)
|
||||||
s.fds.del(fd)
|
s.fds.del(fd)
|
||||||
|
|
||||||
proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) =
|
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)
|
var nkey = SelectorKey[T](ident: ev.rsock.int, flags: flags)
|
||||||
nkey.key.fd = ev.rsock.int
|
nkey.key.fd = ev.rsock.int
|
||||||
nkey.key.data = data
|
nkey.key.data = data
|
||||||
|
|
@ -1488,13 +1447,13 @@ else:
|
||||||
while i < rset.fd_count:
|
while i < rset.fd_count:
|
||||||
let fd = rset.fd_array[i]
|
let fd = rset.fd_array[i]
|
||||||
if iFD_ISSET(fd, rset):
|
if iFD_ISSET(fd, rset):
|
||||||
var events = {eventRead}
|
var events = {Event.Read}
|
||||||
if iFD_ISSET(fd, eset): events = events + {eventError}
|
if iFD_ISSET(fd, eset): events = events + {Event.Error}
|
||||||
if iFD_ISSET(fd, wset): events = events + {eventWrite}
|
if iFD_ISSET(fd, wset): events = events + {Event.Write}
|
||||||
s.fds.withValue(fd, skey) do:
|
s.fds.withValue(fd, skey) do:
|
||||||
if flagHandle in skey.flags:
|
if Event.flagHandle in skey.flags:
|
||||||
skey.key.events = events
|
skey.key.events = events
|
||||||
elif flagUser in skey.flags:
|
elif Event.flagUser in skey.flags:
|
||||||
var data: int = 0
|
var data: int = 0
|
||||||
if winlean.recv(fd, cast[pointer](addr(data)),
|
if winlean.recv(fd, cast[pointer](addr(data)),
|
||||||
sizeof(int).cint, 0) != sizeof(int):
|
sizeof(int).cint, 0) != sizeof(int):
|
||||||
|
|
@ -1505,7 +1464,7 @@ else:
|
||||||
# someone already consumed event data
|
# someone already consumed event data
|
||||||
inc(i)
|
inc(i)
|
||||||
continue
|
continue
|
||||||
skey.key.events = {eventUser}
|
skey.key.events = {Event.User}
|
||||||
results[rindex].fd = skey.key.fd
|
results[rindex].fd = skey.key.fd
|
||||||
results[rindex].data = skey.key.data
|
results[rindex].data = skey.key.data
|
||||||
results[rindex].events = skey.key.events
|
results[rindex].events = skey.key.events
|
||||||
|
|
@ -1516,9 +1475,9 @@ else:
|
||||||
while i < wset.fd_count:
|
while i < wset.fd_count:
|
||||||
let fd = wset.fd_array[i]
|
let fd = wset.fd_array[i]
|
||||||
if iFD_ISSET(fd, wset):
|
if iFD_ISSET(fd, wset):
|
||||||
var events = {eventWrite}
|
var events = {Event.Write}
|
||||||
if not iFD_ISSET(fd, rset):
|
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:
|
s.fds.withValue(fd, skey) do:
|
||||||
skey.key.events = events
|
skey.key.events = events
|
||||||
results[rindex].fd = skey.key.fd
|
results[rindex].fd = skey.key.fd
|
||||||
|
|
@ -1545,7 +1504,6 @@ else:
|
||||||
else:
|
else:
|
||||||
const MAX_POLL_RESULT_EVENTS = 64
|
const MAX_POLL_RESULT_EVENTS = 64
|
||||||
|
|
||||||
when hasThreadSupport:
|
|
||||||
type
|
type
|
||||||
SelectorImpl[T] = object
|
SelectorImpl[T] = object
|
||||||
maxFD : uint
|
maxFD : uint
|
||||||
|
|
@ -1553,27 +1511,16 @@ else:
|
||||||
fds: ptr SharedArray[SelectorKey[T]]
|
fds: ptr SharedArray[SelectorKey[T]]
|
||||||
pollfds: ptr SharedArray[TPollFd]
|
pollfds: ptr SharedArray[TPollFd]
|
||||||
count: int
|
count: int
|
||||||
lock: Lock
|
|
||||||
else:
|
|
||||||
type
|
|
||||||
SelectorImpl[T] = object
|
|
||||||
maxFD : uint
|
|
||||||
pollcnt: int
|
|
||||||
fds: seq[SelectorKey[T]]
|
|
||||||
pollfds: seq[TPollFd]
|
|
||||||
count: int
|
|
||||||
|
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
type Selector*[T] = ptr SelectorImpl[T]
|
lock: Lock
|
||||||
else:
|
|
||||||
type Selector*[T] = ref SelectorImpl[T]
|
Selector*[T] = ptr SelectorImpl[T]
|
||||||
|
|
||||||
type
|
|
||||||
SelectEventImpl = object
|
SelectEventImpl = object
|
||||||
rfd: cint
|
rfd: cint
|
||||||
wfd: cint
|
wfd: cint
|
||||||
|
|
||||||
type SelectEvent* = ptr SelectEventImpl
|
SelectEvent* = ptr SelectEventImpl
|
||||||
|
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
template withPollLock[T](s: Selector[T], body: untyped) =
|
template withPollLock[T](s: Selector[T], body: untyped) =
|
||||||
|
|
@ -1590,16 +1537,12 @@ else:
|
||||||
proc newSelector*[T](): Selector[T] =
|
proc newSelector*[T](): Selector[T] =
|
||||||
var maxFD = getMaxFds()
|
var maxFD = getMaxFds()
|
||||||
|
|
||||||
when hasThreadSupport:
|
|
||||||
result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T])))
|
result = cast[Selector[T]](allocShared0(sizeof(SelectorImpl[T])))
|
||||||
result.maxFD = maxFD.uint
|
result.maxFD = maxFD.uint
|
||||||
result.fds = allocSharedArray[SelectorKey[T]](maxFD)
|
result.fds = allocSharedArray[SelectorKey[T]](maxFD)
|
||||||
result.pollfds = allocSharedArray[TPollFd](maxFD)
|
result.pollfds = allocSharedArray[TPollFd](maxFD)
|
||||||
|
when hasThreadSupport:
|
||||||
initLock(result.lock)
|
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]) =
|
proc close*[T](s: Selector[T]) =
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
|
|
@ -1611,8 +1554,8 @@ else:
|
||||||
template pollAdd[T](s: Selector[T], sock: cint, events: set[Event]) =
|
template pollAdd[T](s: Selector[T], sock: cint, events: set[Event]) =
|
||||||
withPollLock(s):
|
withPollLock(s):
|
||||||
var pollev: cshort = 0
|
var pollev: cshort = 0
|
||||||
if eventRead in events: pollev = pollev or POLLIN
|
if Event.Read in events: pollev = pollev or POLLIN
|
||||||
if eventWrite in events: pollev = pollev or POLLOUT
|
if Event.Write in events: pollev = pollev or POLLOUT
|
||||||
s.pollfds[s.pollcnt].fd = cint(sock)
|
s.pollfds[s.pollcnt].fd = cint(sock)
|
||||||
s.pollfds[s.pollcnt].events = pollev
|
s.pollfds[s.pollcnt].events = pollev
|
||||||
inc(s.count)
|
inc(s.count)
|
||||||
|
|
@ -1622,8 +1565,8 @@ else:
|
||||||
withPollLock(s):
|
withPollLock(s):
|
||||||
var i = 0
|
var i = 0
|
||||||
var pollev: cshort = 0
|
var pollev: cshort = 0
|
||||||
if eventRead in events: pollev = pollev or POLLIN
|
if Event.Read in events: pollev = pollev or POLLIN
|
||||||
if eventWrite in events: pollev = pollev or POLLOUT
|
if Event.Write in events: pollev = pollev or POLLOUT
|
||||||
|
|
||||||
while i < s.pollcnt:
|
while i < s.pollcnt:
|
||||||
if s.pollfds[i].fd == sock:
|
if s.pollfds[i].fd == sock:
|
||||||
|
|
@ -1658,11 +1601,9 @@ else:
|
||||||
events: set[Event], data: T) =
|
events: set[Event], data: T) =
|
||||||
var fdi = int(fd)
|
var fdi = int(fd)
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident == 0:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
setKey(s, fdi, fdi, {flagHandle} + events, 0, data)
|
setKey(s, fdi, fdi, {Event.flagHandle} + events, 0, data)
|
||||||
s.pollAdd(fdi.cint, events)
|
s.pollAdd(fdi.cint, events)
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
|
|
||||||
|
|
@ -1670,21 +1611,16 @@ else:
|
||||||
events: set[Event]) =
|
events: set[Event]) =
|
||||||
var fdi = int(fd)
|
var fdi = int(fd)
|
||||||
if fdi.uint < s.maxFD:
|
if fdi.uint < s.maxFD:
|
||||||
if s.fds[fdi].ident != 0:
|
|
||||||
var oe = s.fds[fdi].flags
|
var oe = s.fds[fdi].flags
|
||||||
if flagHandle in oe:
|
doAssert(s.fds[fdi].ident != 0)
|
||||||
var ne = events + {flagHandle}
|
doAssert(Event.flagHandle in oe)
|
||||||
|
var ne = events + {Event.flagHandle}
|
||||||
if ne != oe:
|
if ne != oe:
|
||||||
if events != {}:
|
if events != {}:
|
||||||
s.pollUpdate(fd.cint, events)
|
s.pollUpdate(fd.cint, events)
|
||||||
else:
|
else:
|
||||||
s.pollRemove(fd.cint)
|
s.pollRemove(fd.cint)
|
||||||
s.fds[fdi].flags = ne
|
s.fds[fdi].flags = ne
|
||||||
else:
|
|
||||||
raise newException(ValueError,
|
|
||||||
"Could not update non-handle descriptor")
|
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non closed descriptor")
|
|
||||||
else:
|
else:
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
raise newException(ValueError, "Maximum file descriptors exceeded")
|
||||||
|
|
||||||
|
|
@ -1702,15 +1638,10 @@ else:
|
||||||
|
|
||||||
proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) =
|
proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) =
|
||||||
var fdi = int(ev.rfd)
|
var fdi = int(ev.rfd)
|
||||||
if fdi.uint < s.maxFD:
|
doAssert(s.fds[fdi].ident == 0)
|
||||||
if s.fds[fdi].ident == 0:
|
var events = {Event.flagUser, Event.Read}
|
||||||
var events = {flagUser, eventRead}
|
|
||||||
setKey(s, fdi, fdi, events, 0, data)
|
setKey(s, fdi, fdi, events, 0, data)
|
||||||
s.pollAdd(fdi.cint, events)
|
s.pollAdd(fdi.cint, events)
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Re-use of non-closed descriptor")
|
|
||||||
else:
|
|
||||||
raise newException(ValueError, "Maximum file descriptors exceeded")
|
|
||||||
|
|
||||||
proc flush*[T](s: Selector[T]) = discard
|
proc flush*[T](s: Selector[T]) = discard
|
||||||
|
|
||||||
|
|
@ -1727,7 +1658,7 @@ else:
|
||||||
proc unregister*[T](s: Selector[T], ev: SelectEvent) =
|
proc unregister*[T](s: Selector[T], ev: SelectEvent) =
|
||||||
var fdi = int(ev.rfd)
|
var fdi = int(ev.rfd)
|
||||||
if fdi.uint < s.maxFD:
|
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)
|
clearKey(s, fdi)
|
||||||
s.pollRemove(fdi.cint)
|
s.pollRemove(fdi.cint)
|
||||||
|
|
||||||
|
|
@ -1769,16 +1700,16 @@ else:
|
||||||
if revents != 0:
|
if revents != 0:
|
||||||
var events: set[Event] = {}
|
var events: set[Event] = {}
|
||||||
if (revents and POLLIN) != 0:
|
if (revents and POLLIN) != 0:
|
||||||
events = events + {eventRead}
|
events = events + {Event.Read}
|
||||||
if (revents and POLLOUT) != 0:
|
if (revents and POLLOUT) != 0:
|
||||||
events = events + {eventWrite}
|
events = events + {Event.Write}
|
||||||
if (revents and POLLERR) != 0 or (revents and POLLHUP) != 0 or
|
if (revents and POLLERR) != 0 or (revents and POLLHUP) != 0 or
|
||||||
(revents and POLLNVAL) != 0:
|
(revents and POLLNVAL) != 0:
|
||||||
events = events + {eventError}
|
events = events + {Event.Error}
|
||||||
|
|
||||||
var skey = addr(s.fds[fd])
|
var skey = addr(s.fds[fd])
|
||||||
if flagUser in skey.flags:
|
if Event.flagUser in skey.flags:
|
||||||
if eventRead in events:
|
if Event.Read in events:
|
||||||
var data: int = 0
|
var data: int = 0
|
||||||
if posix.read(fd, addr data, sizeof(int)) != sizeof(int):
|
if posix.read(fd, addr data, sizeof(int)) != sizeof(int):
|
||||||
let err = osLastError()
|
let err = osLastError()
|
||||||
|
|
@ -1788,7 +1719,7 @@ else:
|
||||||
# someone already consumed event data
|
# someone already consumed event data
|
||||||
inc(i)
|
inc(i)
|
||||||
continue
|
continue
|
||||||
events = {eventUser}
|
events = {Event.User}
|
||||||
|
|
||||||
results[rindex].fd = fd
|
results[rindex].fd = fd
|
||||||
results[rindex].events = events
|
results[rindex].events = events
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,8 @@ when not defined(windows):
|
||||||
var client_socket = create_test_socket()
|
var client_socket = create_test_socket()
|
||||||
var server_socket = create_test_socket()
|
var server_socket = create_test_socket()
|
||||||
|
|
||||||
registerHandle(selector, server_socket, {eventRead}, 0)
|
registerHandle(selector, server_socket, {Event.Read}, 0)
|
||||||
registerHandle(selector, client_socket, {eventWrite}, 0)
|
registerHandle(selector, client_socket, {Event.Write}, 0)
|
||||||
|
|
||||||
var option : int32 = 1
|
var option : int32 = 1
|
||||||
if setsockopt(server_socket, cint(SOL_SOCKET), cint(SO_REUSEADDR),
|
if setsockopt(server_socket, cint(SOL_SOCKET), cint(SO_REUSEADDR),
|
||||||
|
|
@ -67,13 +67,13 @@ when not defined(windows):
|
||||||
cast[ptr SockAddr](addr(sockAddress)),
|
cast[ptr SockAddr](addr(sockAddress)),
|
||||||
addr(addrLen))
|
addr(addrLen))
|
||||||
assert(server2_socket != osInvalidSocket)
|
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]),
|
if posix.send(client_socket, addr(client_message[0]),
|
||||||
len(client_message), 0) == -1:
|
len(client_message), 0) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
|
|
||||||
selector.updateHandle(client_socket, {eventRead})
|
selector.updateHandle(client_socket, {Event.Read})
|
||||||
|
|
||||||
var rc2 = selector.select(100)
|
var rc2 = selector.select(100)
|
||||||
assert(len(rc2) == 1)
|
assert(len(rc2) == 1)
|
||||||
|
|
@ -90,13 +90,13 @@ when not defined(windows):
|
||||||
break
|
break
|
||||||
assert(test1)
|
assert(test1)
|
||||||
|
|
||||||
selector.updateHandle(server2_socket, {eventWrite})
|
selector.updateHandle(server2_socket, {Event.Write})
|
||||||
var rc3 = selector.select(0)
|
var rc3 = selector.select(0)
|
||||||
assert(len(rc3) == 1)
|
assert(len(rc3) == 1)
|
||||||
if posix.send(server2_socket, addr(server_message[0]),
|
if posix.send(server2_socket, addr(server_message[0]),
|
||||||
len(server_message), 0) == -1:
|
len(server_message), 0) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
selector.updateHandle(server2_socket, {eventRead})
|
selector.updateHandle(server2_socket, {Event.Read})
|
||||||
|
|
||||||
var rc4 = selector.select(100)
|
var rc4 = selector.select(100)
|
||||||
assert(len(rc4) == 1)
|
assert(len(rc4) == 1)
|
||||||
|
|
@ -238,7 +238,7 @@ when not defined(windows):
|
||||||
var event = newEvent()
|
var event = newEvent()
|
||||||
for i in 0..high(thr):
|
for i in 0..high(thr):
|
||||||
createThread(thr[i], event_wait_thread, event)
|
createThread(thr[i], event_wait_thread, event)
|
||||||
selector.registerHandle(sock, {eventRead}, 1)
|
selector.registerHandle(sock, {Event.Read}, 1)
|
||||||
discard selector.select(500)
|
discard selector.select(500)
|
||||||
selector.unregister(sock)
|
selector.unregister(sock)
|
||||||
event.setEvent()
|
event.setEvent()
|
||||||
|
|
@ -273,8 +273,8 @@ else:
|
||||||
var client_socket = create_test_socket()
|
var client_socket = create_test_socket()
|
||||||
var server_socket = create_test_socket()
|
var server_socket = create_test_socket()
|
||||||
|
|
||||||
selector.registerHandle(server_socket, {eventRead}, 0)
|
selector.registerHandle(server_socket, {Event.Read}, 0)
|
||||||
selector.registerHandle(client_socket, {eventWrite}, 0)
|
selector.registerHandle(client_socket, {Event.Write}, 0)
|
||||||
|
|
||||||
var option : int32 = 1
|
var option : int32 = 1
|
||||||
if setsockopt(server_socket, cint(SOL_SOCKET), cint(SO_REUSEADDR),
|
if setsockopt(server_socket, cint(SOL_SOCKET), cint(SO_REUSEADDR),
|
||||||
|
|
@ -305,13 +305,13 @@ else:
|
||||||
cast[ptr SockAddr](addr(sockAddress)),
|
cast[ptr SockAddr](addr(sockAddress)),
|
||||||
addr(addrLen))
|
addr(addrLen))
|
||||||
assert(server2_socket != osInvalidSocket)
|
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])),
|
if send(client_socket, cast[pointer](addr(client_message[0])),
|
||||||
cint(len(client_message)), 0) == -1:
|
cint(len(client_message)), 0) == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
|
|
||||||
selector.updateHandle(client_socket, {eventRead})
|
selector.updateHandle(client_socket, {Event.Read})
|
||||||
|
|
||||||
var rc2 = selector.select(100)
|
var rc2 = selector.select(100)
|
||||||
assert(len(rc2) == 1)
|
assert(len(rc2) == 1)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue