The AsyncFD type now implies that the underlying FD is registered.

* `asyncdispatch.register` won't attempt to register an
  ``AsyncFD``, but instead assume that it is already registered.
This commit is contained in:
Dominik Picheta 2017-11-24 16:17:48 +00:00
commit 3db460f504
3 changed files with 35 additions and 11 deletions

View file

@ -219,7 +219,7 @@ when defined(windows) or defined(nimdoc):
PCustomOverlapped* = ref CustomOverlapped
AsyncFD* = distinct int
AsyncFD* = distinct int ## An FD that is registered in the dispatcher.
PostCallbackData = object
ioPort: Handle
@ -262,13 +262,22 @@ when defined(windows) or defined(nimdoc):
setGlobalDispatcher(newDispatcher())
result = gDisp
proc register*(fd: AsyncFD) =
proc register*(fd: cint | SocketHandle | AsyncFD): AsyncFD {.discardable.} =
## Registers ``fd`` with the dispatcher.
##
## By convention, an ``AsyncFD`` is said to be already registered in the
## dispatcher. This procedure will raise an exception if ``fd`` has already
## been registered, but only if the type of the ``fd`` isn't ``AsyncFD``.
let p = getGlobalDispatcher()
when fd is AsyncFD:
if fd in p.handles:
return
if createIoCompletionPort(fd.Handle, p.ioPort,
cast[CompletionKey](fd), 1) == 0:
raiseOSError(osLastError())
p.handles.incl(fd)
return fd.AsyncFD
proc verifyPresence(fd: AsyncFD) =
## Ensures that file descriptor has been registered with the dispatcher.
@ -753,6 +762,9 @@ when defined(windows) or defined(nimdoc):
## Unregisters ``fd``.
getGlobalDispatcher().handles.excl(fd)
proc contains*(disp: PDispatcher, fd: AsyncFd | SocketHandle): bool =
return fd.SocketHandle in disp.handles
{.push stackTrace:off.}
proc waitableCallback(param: pointer,
timerOrWaitFired: WINBOOL): void {.stdcall.} =
@ -1091,10 +1103,14 @@ else:
setGlobalDispatcher(newDispatcher())
result = gDisp
proc register*(fd: AsyncFD) =
proc register*(fd: cint | SocketHandle | AsyncFD): AsyncFD {.discardable.} =
let p = getGlobalDispatcher()
when fd is AsyncFD:
if fd.SocketHandle in p.selector:
return
var data = newAsyncData()
p.selector.registerHandle(fd.SocketHandle, {}, data)
return fd.AsyncFD
proc closeSocket*(sock: AsyncFD) =
let disp = getGlobalDispatcher()
@ -1106,6 +1122,9 @@ else:
proc unregister*(ev: AsyncEvent) =
getGlobalDispatcher().selector.unregister(SelectEvent(ev))
proc contains*(disp: PDispatcher, fd: AsyncFd | SocketHandle): bool =
return fd.SocketHandle in disp.selector
proc addRead*(fd: AsyncFD, cb: Callback) =
let p = getGlobalDispatcher()