Merge branch 'cheatfate-fix5290' into devel

This commit is contained in:
Andreas Rumpf 2017-01-27 19:29:41 +01:00
commit 0e16d43196
6 changed files with 99 additions and 82 deletions

View file

@ -871,7 +871,9 @@ when defined(windows) or defined(nimdoc):
if unregisterWait(pcd.waitFd) == 0: if unregisterWait(pcd.waitFd) == 0:
let err = osLastError() let err = osLastError()
if err.int32 != ERROR_IO_PENDING: if err.int32 != ERROR_IO_PENDING:
raiseOSError(osLastError()) deallocShared(cast[pointer](pcd))
discard wsaCloseEvent(hEvent)
raiseOSError(err)
if cb(fd): if cb(fd):
# callback returned `true`, so we free all allocated resources # callback returned `true`, so we free all allocated resources
deallocShared(cast[pointer](pcd)) deallocShared(cast[pointer](pcd))
@ -895,9 +897,10 @@ when defined(windows) or defined(nimdoc):
cast[WAITORTIMERCALLBACK](waitableCallback), cast[WAITORTIMERCALLBACK](waitableCallback),
cast[pointer](pcd), INFINITE, flags): cast[pointer](pcd), INFINITE, flags):
# pcd.ovl will be unrefed in poll() # pcd.ovl will be unrefed in poll()
let err = osLastError()
discard wsaCloseEvent(hEvent) discard wsaCloseEvent(hEvent)
deallocShared(cast[pointer](pcd)) deallocShared(cast[pointer](pcd))
raiseOSError(osLastError()) raiseOSError(err)
else: else:
# we incref `pcd.ovl` and `protect` callback one more time, # we incref `pcd.ovl` and `protect` callback one more time,
# because it will be unrefed and disposed in `poll()` after # because it will be unrefed and disposed in `poll()` after
@ -912,19 +915,21 @@ when defined(windows) or defined(nimdoc):
# This is main part of `hacky way` is using WSAEventSelect, so `hEvent` # This is main part of `hacky way` is using WSAEventSelect, so `hEvent`
# will be signaled when appropriate `mask` events will be triggered. # will be signaled when appropriate `mask` events will be triggered.
if wsaEventSelect(fd.SocketHandle, hEvent, mask) != 0: if wsaEventSelect(fd.SocketHandle, hEvent, mask) != 0:
let err = osLastError()
GC_unref(ol) GC_unref(ol)
deallocShared(cast[pointer](pcd)) deallocShared(cast[pointer](pcd))
discard wsaCloseEvent(hEvent) discard wsaCloseEvent(hEvent)
raiseOSError(osLastError()) raiseOSError(err)
pcd.ovl = ol pcd.ovl = ol
if not registerWaitForSingleObject(addr(pcd.waitFd), hEvent, if not registerWaitForSingleObject(addr(pcd.waitFd), hEvent,
cast[WAITORTIMERCALLBACK](waitableCallback), cast[WAITORTIMERCALLBACK](waitableCallback),
cast[pointer](pcd), INFINITE, flags): cast[pointer](pcd), INFINITE, flags):
let err = osLastError()
GC_unref(ol) GC_unref(ol)
deallocShared(cast[pointer](pcd)) deallocShared(cast[pointer](pcd))
discard wsaCloseEvent(hEvent) discard wsaCloseEvent(hEvent)
raiseOSError(osLastError()) raiseOSError(err)
p.handles.incl(fd) p.handles.incl(fd)
proc addRead*(fd: AsyncFD, cb: Callback) = proc addRead*(fd: AsyncFD, cb: Callback) =

View file

@ -131,11 +131,12 @@ proc newSelector*[T](): Selector[T] =
result.fds = newSeq[SelectorKey[T]](maxFD) result.fds = newSeq[SelectorKey[T]](maxFD)
proc close*[T](s: Selector[T]) = proc close*[T](s: Selector[T]) =
if posix.close(s.epollFD) != 0: let res = posix.close(s.epollFD)
raiseIOSelectorsError(osLastError())
when hasThreadSupport: when hasThreadSupport:
deallocSharedArray(s.fds) deallocSharedArray(s.fds)
deallocShared(cast[pointer](s)) deallocShared(cast[pointer](s))
if res != 0:
raiseIOSelectorsError(osLastError())
template clearKey[T](key: ptr SelectorKey[T]) = template clearKey[T](key: ptr SelectorKey[T]) =
var empty: T var empty: T
@ -157,9 +158,10 @@ proc setEvent*(ev: SelectEvent) =
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
proc close*(ev: SelectEvent) = proc close*(ev: SelectEvent) =
if posix.close(ev.efd) == -1: let res = posix.close(ev.efd)
raiseIOSelectorsError(osLastError())
deallocShared(cast[pointer](ev)) deallocShared(cast[pointer](ev))
if res != 0:
raiseIOSelectorsError(osLastError())
template checkFd(s, f) = template checkFd(s, f) =
if f >= s.maxFD: if f >= s.maxFD:
@ -176,7 +178,7 @@ proc registerHandle*[T](s: Selector[T], fd: SocketHandle,
epv.data.u64 = fdi.uint epv.data.u64 = fdi.uint
if Event.Read in events: epv.events = epv.events or EPOLLIN if Event.Read in events: epv.events = epv.events or EPOLLIN
if Event.Write in events: epv.events = epv.events or EPOLLOUT if Event.Write in events: 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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
inc(s.count) inc(s.count)
@ -196,15 +198,15 @@ proc updateHandle*[T](s: Selector[T], fd: SocketHandle, events: set[Event]) =
if Event.Write in events: epv.events = epv.events or EPOLLOUT if Event.Write in events: epv.events = epv.events or EPOLLOUT
if pkey.events == {}: if pkey.events == {}:
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
inc(s.count) inc(s.count)
else: else:
if events != {}: if events != {}:
if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fdi.cint, addr epv) == -1: if epoll_ctl(s.epollFD, EPOLL_CTL_MOD, fdi.cint, addr epv) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
else: else:
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
dec(s.count) dec(s.count)
pkey.events = events pkey.events = events
@ -219,20 +221,20 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) =
when not defined(android): when not defined(android):
if pkey.events * {Event.Read, Event.Write} != {}: if pkey.events * {Event.Read, Event.Write} != {}:
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
dec(s.count) dec(s.count)
elif Event.Timer in pkey.events: elif Event.Timer in pkey.events:
if Event.Finished notin pkey.events: if Event.Finished notin pkey.events:
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
dec(s.count) dec(s.count)
if posix.close(cint(fdi)) == -1: if posix.close(cint(fdi)) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
elif Event.Signal in pkey.events: elif Event.Signal in pkey.events:
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
var nmask, omask: Sigset var nmask, omask: Sigset
discard sigemptyset(nmask) discard sigemptyset(nmask)
@ -240,12 +242,12 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) =
discard sigaddset(nmask, cint(s.fds[fdi].param)) discard sigaddset(nmask, cint(s.fds[fdi].param))
unblockSignals(nmask, omask) unblockSignals(nmask, omask)
dec(s.count) dec(s.count)
if posix.close(cint(fdi)) == -1: if posix.close(cint(fdi)) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
elif Event.Process in pkey.events: elif Event.Process in pkey.events:
if Event.Finished notin pkey.events: if Event.Finished notin pkey.events:
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
var nmask, omask: Sigset var nmask, omask: Sigset
discard sigemptyset(nmask) discard sigemptyset(nmask)
@ -253,21 +255,21 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) =
discard sigaddset(nmask, SIGCHLD) discard sigaddset(nmask, SIGCHLD)
unblockSignals(nmask, omask) unblockSignals(nmask, omask)
dec(s.count) dec(s.count)
if posix.close(cint(fdi)) == -1: if posix.close(cint(fdi)) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
else: else:
if pkey.events * {Event.Read, Event.Write} != {}: if pkey.events * {Event.Read, Event.Write} != {}:
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
dec(s.count) dec(s.count)
elif Event.Timer in pkey.events: elif Event.Timer in pkey.events:
if Event.Finished notin pkey.events: if Event.Finished notin pkey.events:
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
dec(s.count) dec(s.count)
if posix.close(cint(fdi)) == -1: if posix.close(cint(fdi)) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
clearKey(pkey) clearKey(pkey)
@ -278,7 +280,7 @@ proc unregister*[T](s: Selector[T], ev: SelectEvent) =
doAssert(pkey.ident != 0) doAssert(pkey.ident != 0)
doAssert(Event.User in pkey.events) doAssert(Event.User in pkey.events)
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
dec(s.count) dec(s.count)
clearKey(pkey) clearKey(pkey)
@ -312,9 +314,9 @@ proc registerTimer*[T](s: Selector[T], timeout: int, oneshot: bool,
new_ts.it_value.tv_sec = new_ts.it_interval.tv_sec new_ts.it_value.tv_sec = new_ts.it_interval.tv_sec
new_ts.it_value.tv_nsec = new_ts.it_interval.tv_nsec new_ts.it_value.tv_nsec = new_ts.it_interval.tv_nsec
if timerfd_settime(fdi.cint, cint(0), new_ts, old_ts) == -1: if timerfd_settime(fdi.cint, cint(0), new_ts, old_ts) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
s.setKey(fdi, events, 0, data) s.setKey(fdi, events, 0, data)
inc(s.count) inc(s.count)
@ -342,7 +344,7 @@ when not defined(android):
var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP) var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP)
epv.data.u64 = fdi.uint epv.data.u64 = fdi.uint
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
s.setKey(fdi, {Event.Signal}, signal, data) s.setKey(fdi, {Event.Signal}, signal, data)
inc(s.count) inc(s.count)
@ -370,7 +372,7 @@ when not defined(android):
var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP) var epv = epoll_event(events: EPOLLIN or EPOLLRDHUP)
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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
s.setKey(fdi, {Event.Process, Event.Oneshot}, pid, data) s.setKey(fdi, {Event.Process, Event.Oneshot}, pid, data)
inc(s.count) inc(s.count)
@ -382,7 +384,7 @@ proc registerEvent*[T](s: Selector[T], ev: SelectEvent, data: T) =
s.setKey(fdi, {Event.User}, 0, data) s.setKey(fdi, {Event.User}, 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) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
inc(s.count) inc(s.count)
@ -480,7 +482,7 @@ proc selectInto*[T](s: Selector[T], timeout: int,
if Event.Oneshot in pkey.events: if Event.Oneshot in pkey.events:
var epv = epoll_event() var epv = epoll_event()
if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, cint(fdi), addr epv) == -1: if epoll_ctl(s.epollFD, EPOLL_CTL_DEL, cint(fdi), addr epv) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
# we will not clear key until it will be unregistered, so # we will not clear key until it will be unregistered, so
# application can obtain data, but we will decrease counter, # application can obtain data, but we will decrease counter,

View file

@ -116,12 +116,13 @@ proc newSelector*[T](): Selector[T] =
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
proc close*[T](s: Selector[T]) = proc close*[T](s: Selector[T]) =
if posix.close(s.kqFD) != 0: let res = posix.close(s.kqFD)
raiseIOSelectorsError(osLastError())
when hasThreadSupport: when hasThreadSupport:
deinitLock(s.changesLock) deinitLock(s.changesLock)
deallocSharedArray(s.fds) deallocSharedArray(s.fds)
deallocShared(cast[pointer](s)) deallocShared(cast[pointer](s))
if res != 0:
raiseIOSelectorsError(osLastError())
template clearKey[T](key: ptr SelectorKey[T]) = template clearKey[T](key: ptr SelectorKey[T]) =
var empty: T var empty: T
@ -131,7 +132,7 @@ template clearKey[T](key: ptr SelectorKey[T]) =
proc newSelectEvent*(): SelectEvent = proc newSelectEvent*(): SelectEvent =
var fds: array[2, cint] var fds: array[2, cint]
if posix.pipe(fds) == -1: if posix.pipe(fds) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
setNonBlocking(fds[0]) setNonBlocking(fds[0])
setNonBlocking(fds[1]) setNonBlocking(fds[1])
@ -145,11 +146,11 @@ proc setEvent*(ev: SelectEvent) =
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
proc close*(ev: SelectEvent) = proc close*(ev: SelectEvent) =
if posix.close(cint(ev.rfd)) == -1: let res1 = posix.close(ev.rfd)
raiseIOSelectorsError(osLastError()) let res2 = posix.close(ev.wfd)
if posix.close(cint(ev.wfd)) == -1:
raiseIOSelectorsError(osLastError())
deallocShared(cast[pointer](ev)) deallocShared(cast[pointer](ev))
if res1 != 0 or res2 != 0:
raiseIOSelectorsError(osLastError())
template checkFd(s, f) = template checkFd(s, f) =
if f >= s.maxFD: if f >= s.maxFD:
@ -386,7 +387,7 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) =
when not declared(CACHE_EVENTS): when not declared(CACHE_EVENTS):
flushKQueue(s) flushKQueue(s)
dec(s.count) dec(s.count)
if posix.close(cint(pkey.ident)) == -1: if posix.close(cint(pkey.ident)) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
elif Event.Signal in pkey.events: elif Event.Signal in pkey.events:
var nmask, omask: Sigset var nmask, omask: Sigset
@ -400,7 +401,7 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) =
when not declared(CACHE_EVENTS): when not declared(CACHE_EVENTS):
flushKQueue(s) flushKQueue(s)
dec(s.count) dec(s.count)
if posix.close(cint(pkey.ident)) == -1: if posix.close(cint(pkey.ident)) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
elif Event.Process in pkey.events: elif Event.Process in pkey.events:
if Event.Finished notin pkey.events: if Event.Finished notin pkey.events:
@ -408,7 +409,7 @@ proc unregister*[T](s: Selector[T], fd: int|SocketHandle) =
when not declared(CACHE_EVENTS): when not declared(CACHE_EVENTS):
flushKQueue(s) flushKQueue(s)
dec(s.count) dec(s.count)
if posix.close(cint(pkey.ident)) == -1: if posix.close(cint(pkey.ident)) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
elif Event.Vnode in pkey.events: elif Event.Vnode in pkey.events:
modifyKQueue(s, uint(fdi), EVFILT_VNODE, EV_DELETE, 0, 0, nil) modifyKQueue(s, uint(fdi), EVFILT_VNODE, EV_DELETE, 0, 0, nil)

View file

@ -199,7 +199,7 @@ proc unregister*[T](s: Selector[T], ev: SelectEvent) =
proc newSelectEvent*(): SelectEvent = proc newSelectEvent*(): SelectEvent =
var fds: array[2, cint] var fds: array[2, cint]
if posix.pipe(fds) == -1: if posix.pipe(fds) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
setNonBlocking(fds[0]) setNonBlocking(fds[0])
setNonBlocking(fds[1]) setNonBlocking(fds[1])
@ -213,11 +213,11 @@ proc setEvent*(ev: SelectEvent) =
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
proc close*(ev: SelectEvent) = proc close*(ev: SelectEvent) =
if posix.close(cint(ev.rfd)) == -1: let res1 = posix.close(ev.rfd)
raiseIOSelectorsError(osLastError()) let res2 = posix.close(ev.wfd)
if posix.close(cint(ev.wfd)) == -1:
raiseIOSelectorsError(osLastError())
deallocShared(cast[pointer](ev)) deallocShared(cast[pointer](ev))
if res1 != 0 or res2 != 0:
raiseIOSelectorsError(osLastError())
proc selectInto*[T](s: Selector[T], timeout: int, proc selectInto*[T](s: Selector[T], timeout: int,
results: var openarray[ReadyKey]): int = results: var openarray[ReadyKey]): int =

View file

@ -122,17 +122,17 @@ when defined(windows):
sizeof(saddr).SockLen) < 0'i32: sizeof(saddr).SockLen) < 0'i32:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
if winlean.listen(ssock, 1) == -1: if winlean.listen(ssock, 1) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
var namelen = sizeof(saddr).SockLen var namelen = sizeof(saddr).SockLen
if getsockname(ssock, cast[ptr SockAddr](addr(saddr)), if getsockname(ssock, cast[ptr SockAddr](addr(saddr)),
addr(namelen)) == -1'i32: addr(namelen)) != 0'i32:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
saddr.sin_addr.s_addr = 0x0100007F saddr.sin_addr.s_addr = 0x0100007F
if winlean.connect(wsock, cast[ptr SockAddr](addr(saddr)), if winlean.connect(wsock, cast[ptr SockAddr](addr(saddr)),
sizeof(saddr).SockLen) == -1: sizeof(saddr).SockLen) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
namelen = sizeof(saddr).SockLen namelen = sizeof(saddr).SockLen
rsock = winlean.accept(ssock, cast[ptr SockAddr](addr(saddr)), rsock = winlean.accept(ssock, cast[ptr SockAddr](addr(saddr)),
@ -140,14 +140,14 @@ when defined(windows):
if rsock == SocketHandle(-1): if rsock == SocketHandle(-1):
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
if winlean.closesocket(ssock) == -1: if winlean.closesocket(ssock) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
var mode = clong(1) var mode = clong(1)
if ioctlsocket(rsock, FIONBIO, addr(mode)) == -1: if ioctlsocket(rsock, FIONBIO, addr(mode)) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
mode = clong(1) mode = clong(1)
if ioctlsocket(wsock, FIONBIO, addr(mode)) == -1: if ioctlsocket(wsock, FIONBIO, addr(mode)) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl))) result = cast[SelectEvent](allocShared0(sizeof(SelectEventImpl)))
@ -161,14 +161,16 @@ when defined(windows):
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
proc close*(ev: SelectEvent) = proc close*(ev: SelectEvent) =
discard winlean.closesocket(ev.rsock) let res1 = winlean.closesocket(ev.rsock)
discard winlean.closesocket(ev.wsock) let res2 = winlean.closesocket(ev.wsock)
deallocShared(cast[pointer](ev)) deallocShared(cast[pointer](ev))
if res1 != 0 or res2 != 0:
raiseIOSelectorsError(osLastError())
else: else:
proc newSelectEvent*(): SelectEvent = proc newSelectEvent*(): SelectEvent =
var fds: array[2, cint] var fds: array[2, cint]
if posix.pipe(fds) == -1: if posix.pipe(fds) != 0:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
setNonBlocking(fds[0]) setNonBlocking(fds[0])
setNonBlocking(fds[1]) setNonBlocking(fds[1])
@ -182,11 +184,11 @@ else:
raiseIOSelectorsError(osLastError()) raiseIOSelectorsError(osLastError())
proc close*(ev: SelectEvent) = proc close*(ev: SelectEvent) =
if posix.close(cint(ev.rsock)) == -1: let res1 = posix.close(cint(ev.rsock))
raiseIOSelectorsError(osLastError()) let res2 = posix.close(cint(ev.wsock))
if posix.close(cint(ev.wsock)) == -1:
raiseIOSelectorsError(osLastError())
deallocShared(cast[pointer](ev)) deallocShared(cast[pointer](ev))
if res1 != 0 or res2 != 0:
raiseIOSelectorsError(osLastError())
proc setSelectKey[T](s: Selector[T], fd: SocketHandle, events: set[Event], proc setSelectKey[T](s: Selector[T], fd: SocketHandle, events: set[Event],
data: T) = data: T) =

View file

@ -856,7 +856,9 @@ when defined(windows) or defined(nimdoc):
if unregisterWait(pcd.waitFd) == 0: if unregisterWait(pcd.waitFd) == 0:
let err = osLastError() let err = osLastError()
if err.int32 != ERROR_IO_PENDING: if err.int32 != ERROR_IO_PENDING:
raiseOSError(osLastError()) deallocShared(cast[pointer](pcd))
discard wsaCloseEvent(hEvent)
raiseOSError(err)
if cb(fd): if cb(fd):
# callback returned `true`, so we free all allocated resources # callback returned `true`, so we free all allocated resources
deallocShared(cast[pointer](pcd)) deallocShared(cast[pointer](pcd))
@ -880,9 +882,10 @@ when defined(windows) or defined(nimdoc):
cast[WAITORTIMERCALLBACK](waitableCallback), cast[WAITORTIMERCALLBACK](waitableCallback),
cast[pointer](pcd), INFINITE, flags): cast[pointer](pcd), INFINITE, flags):
# pcd.ovl will be unrefed in poll() # pcd.ovl will be unrefed in poll()
discard wsaCloseEvent(hEvent) let err = osLastError()
deallocShared(cast[pointer](pcd)) deallocShared(cast[pointer](pcd))
raiseOSError(osLastError()) discard wsaCloseEvent(hEvent)
raiseOSError(err)
else: else:
# we incref `pcd.ovl` and `protect` callback one more time, # we incref `pcd.ovl` and `protect` callback one more time,
# because it will be unrefed and disposed in `poll()` after # because it will be unrefed and disposed in `poll()` after
@ -897,19 +900,21 @@ when defined(windows) or defined(nimdoc):
# This is main part of `hacky way` is using WSAEventSelect, so `hEvent` # This is main part of `hacky way` is using WSAEventSelect, so `hEvent`
# will be signaled when appropriate `mask` events will be triggered. # will be signaled when appropriate `mask` events will be triggered.
if wsaEventSelect(fd.SocketHandle, hEvent, mask) != 0: if wsaEventSelect(fd.SocketHandle, hEvent, mask) != 0:
let err = osLastError()
GC_unref(ol) GC_unref(ol)
deallocShared(cast[pointer](pcd)) deallocShared(cast[pointer](pcd))
discard wsaCloseEvent(hEvent) discard wsaCloseEvent(hEvent)
raiseOSError(osLastError()) raiseOSError(err)
pcd.ovl = ol pcd.ovl = ol
if not registerWaitForSingleObject(addr(pcd.waitFd), hEvent, if not registerWaitForSingleObject(addr(pcd.waitFd), hEvent,
cast[WAITORTIMERCALLBACK](waitableCallback), cast[WAITORTIMERCALLBACK](waitableCallback),
cast[pointer](pcd), INFINITE, flags): cast[pointer](pcd), INFINITE, flags):
let err = osLastError()
GC_unref(ol) GC_unref(ol)
deallocShared(cast[pointer](pcd)) deallocShared(cast[pointer](pcd))
discard wsaCloseEvent(hEvent) discard wsaCloseEvent(hEvent)
raiseOSError(osLastError()) raiseOSError(err)
p.handles.incl(fd) p.handles.incl(fd)
proc addRead*(fd: AsyncFD, cb: Callback) = proc addRead*(fd: AsyncFD, cb: Callback) =
@ -963,12 +968,25 @@ when defined(windows) or defined(nimdoc):
if not registerWaitForSingleObject(addr(pcd.waitFd), hEvent, if not registerWaitForSingleObject(addr(pcd.waitFd), hEvent,
cast[WAITORTIMERCALLBACK](waitableCallback), cast[WAITORTIMERCALLBACK](waitableCallback),
cast[pointer](pcd), timeout.Dword, flags): cast[pointer](pcd), timeout.Dword, flags):
let err = osLastError()
GC_unref(ol) GC_unref(ol)
deallocShared(cast[pointer](pcd)) deallocShared(cast[pointer](pcd))
discard closeHandle(hEvent) discard closeHandle(hEvent)
raiseOSError(osLastError()) raiseOSError(err)
p.handles.incl(handleFD) p.handles.incl(handleFD)
template closeWaitable(handle: untyped) =
let waitFd = pcd.waitFd
deallocShared(cast[pointer](pcd))
p.handles.excl(fd)
if unregisterWait(waitFd) == 0:
let err = osLastError()
if err.int32 != ERROR_IO_PENDING:
discard closeHandle(handle)
raiseOSError(err)
if closeHandle(handle) == 0:
raiseOSError(osLastError())
proc addTimer*(timeout: int, oneshot: bool, cb: Callback) = proc addTimer*(timeout: int, oneshot: bool, cb: Callback) =
## Registers callback ``cb`` to be called when timer expired. ## Registers callback ``cb`` to be called when timer expired.
## ``timeout`` - timeout value in milliseconds. ## ``timeout`` - timeout value in milliseconds.
@ -989,13 +1007,7 @@ when defined(windows) or defined(nimdoc):
proc timercb(fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = proc timercb(fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) =
let res = cb(fd) let res = cb(fd)
if res or oneshot: if res or oneshot:
if unregisterWait(pcd.waitFd) == 0: closeWaitable(hEvent)
let err = osLastError()
if err.int32 != ERROR_IO_PENDING:
raiseOSError(osLastError())
discard closeHandle(hEvent)
deallocShared(cast[pointer](pcd))
p.handles.excl(fd)
else: else:
# if callback returned `false`, then it wants to be called again, so # if callback returned `false`, then it wants to be called again, so
# we need to ref and protect `pcd.ovl` again, because it will be # we need to ref and protect `pcd.ovl` again, because it will be
@ -1018,13 +1030,7 @@ when defined(windows) or defined(nimdoc):
var flags = WT_EXECUTEINWAITTHREAD.Dword var flags = WT_EXECUTEINWAITTHREAD.Dword
proc proccb(fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = proc proccb(fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) =
if unregisterWait(pcd.waitFd) == 0: closeWaitable(hProcess)
let err = osLastError()
if err.int32 != ERROR_IO_PENDING:
raiseOSError(osLastError())
discard closeHandle(hProcess)
deallocShared(cast[pointer](pcd))
p.handles.excl(fd)
discard cb(fd) discard cb(fd)
registerWaitableHandle(p, hProcess, flags, pcd, INFINITE, proccb) registerWaitableHandle(p, hProcess, flags, pcd, INFINITE, proccb)
@ -1052,20 +1058,21 @@ when defined(windows) or defined(nimdoc):
## Unregisters event ``ev``. ## Unregisters event ``ev``.
if ev.hWaiter != 0: if ev.hWaiter != 0:
let p = getGlobalDispatcher() let p = getGlobalDispatcher()
p.handles.excl(AsyncFD(ev.hEvent))
if unregisterWait(ev.hWaiter) == 0: if unregisterWait(ev.hWaiter) == 0:
let err = osLastError() let err = osLastError()
if err.int32 != ERROR_IO_PENDING: if err.int32 != ERROR_IO_PENDING:
raiseOSError(osLastError()) raiseOSError(err)
p.handles.excl(AsyncFD(ev.hEvent))
ev.hWaiter = 0 ev.hWaiter = 0
else: else:
raise newException(ValueError, "Event is not registered!") raise newException(ValueError, "Event is not registered!")
proc close*(ev: AsyncEvent) = proc close*(ev: AsyncEvent) =
## Closes event ``ev``. ## Closes event ``ev``.
if closeHandle(ev.hEvent) == 0: let res = closeHandle(ev.hEvent)
raiseOSError(osLastError())
deallocShared(cast[pointer](ev)) deallocShared(cast[pointer](ev))
if res == 0:
raiseOSError(osLastError())
proc addEvent*(ev: AsyncEvent, cb: Callback) = proc addEvent*(ev: AsyncEvent, cb: Callback) =
## Registers callback ``cb`` to be called when ``ev`` will be signaled ## Registers callback ``cb`` to be called when ``ev`` will be signaled
@ -1082,8 +1089,8 @@ when defined(windows) or defined(nimdoc):
if cb(fd): if cb(fd):
# we need this check to avoid exception, if `unregister(event)` was # we need this check to avoid exception, if `unregister(event)` was
# called in callback. # called in callback.
if ev.hWaiter != 0: unregister(ev)
deallocShared(cast[pointer](pcd)) deallocShared(cast[pointer](pcd))
if ev.hWaiter != 0: unregister(ev)
else: else:
# if callback returned `false`, then it wants to be called again, so # if callback returned `false`, then it wants to be called again, so
# we need to ref and protect `pcd.ovl` again, because it will be # we need to ref and protect `pcd.ovl` again, because it will be