mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-02 12:04:44 +00:00
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:
@@ -12,6 +12,12 @@
|
|||||||
`getBool`, `getFloat`, `getBiggestInt`. Also `getInt` procedure was added.
|
`getBool`, `getFloat`, `getBiggestInt`. Also `getInt` procedure was added.
|
||||||
- `reExtended` is no longer default for the `re` constructor in the `re`
|
- `reExtended` is no longer default for the `re` constructor in the `re`
|
||||||
module.
|
module.
|
||||||
|
|
||||||
|
|
||||||
|
### Library changes
|
||||||
|
|
||||||
|
- The `AsyncFD` type now reflects the fact that the underlying FD is registered
|
||||||
|
in the async dispatcher.
|
||||||
- The overloading rules changed slightly so that constrained generics are
|
- The overloading rules changed slightly so that constrained generics are
|
||||||
preferred over unconstrained generics. (Bug #6526)
|
preferred over unconstrained generics. (Bug #6526)
|
||||||
- It is now possible to forward declare object types so that mutually
|
- It is now possible to forward declare object types so that mutually
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ when defined(windows) or defined(nimdoc):
|
|||||||
|
|
||||||
PCustomOverlapped* = ref CustomOverlapped
|
PCustomOverlapped* = ref CustomOverlapped
|
||||||
|
|
||||||
AsyncFD* = distinct int
|
AsyncFD* = distinct int ## An FD that is registered in the dispatcher.
|
||||||
|
|
||||||
PostCallbackData = object
|
PostCallbackData = object
|
||||||
ioPort: Handle
|
ioPort: Handle
|
||||||
@@ -262,13 +262,22 @@ when defined(windows) or defined(nimdoc):
|
|||||||
setGlobalDispatcher(newDispatcher())
|
setGlobalDispatcher(newDispatcher())
|
||||||
result = gDisp
|
result = gDisp
|
||||||
|
|
||||||
proc register*(fd: AsyncFD) =
|
proc register*(fd: cint | SocketHandle | AsyncFD): AsyncFD {.discardable.} =
|
||||||
## Registers ``fd`` with the dispatcher.
|
## 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()
|
let p = getGlobalDispatcher()
|
||||||
|
when fd is AsyncFD:
|
||||||
|
if fd in p.handles:
|
||||||
|
return
|
||||||
|
|
||||||
if createIoCompletionPort(fd.Handle, p.ioPort,
|
if createIoCompletionPort(fd.Handle, p.ioPort,
|
||||||
cast[CompletionKey](fd), 1) == 0:
|
cast[CompletionKey](fd), 1) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
p.handles.incl(fd)
|
p.handles.incl(fd)
|
||||||
|
return fd.AsyncFD
|
||||||
|
|
||||||
proc verifyPresence(fd: AsyncFD) =
|
proc verifyPresence(fd: AsyncFD) =
|
||||||
## Ensures that file descriptor has been registered with the dispatcher.
|
## Ensures that file descriptor has been registered with the dispatcher.
|
||||||
@@ -753,6 +762,9 @@ when defined(windows) or defined(nimdoc):
|
|||||||
## Unregisters ``fd``.
|
## Unregisters ``fd``.
|
||||||
getGlobalDispatcher().handles.excl(fd)
|
getGlobalDispatcher().handles.excl(fd)
|
||||||
|
|
||||||
|
proc contains*(disp: PDispatcher, fd: AsyncFd | SocketHandle): bool =
|
||||||
|
return fd.SocketHandle in disp.handles
|
||||||
|
|
||||||
{.push stackTrace:off.}
|
{.push stackTrace:off.}
|
||||||
proc waitableCallback(param: pointer,
|
proc waitableCallback(param: pointer,
|
||||||
timerOrWaitFired: WINBOOL): void {.stdcall.} =
|
timerOrWaitFired: WINBOOL): void {.stdcall.} =
|
||||||
@@ -1091,10 +1103,14 @@ else:
|
|||||||
setGlobalDispatcher(newDispatcher())
|
setGlobalDispatcher(newDispatcher())
|
||||||
result = gDisp
|
result = gDisp
|
||||||
|
|
||||||
proc register*(fd: AsyncFD) =
|
proc register*(fd: cint | SocketHandle | AsyncFD): AsyncFD {.discardable.} =
|
||||||
let p = getGlobalDispatcher()
|
let p = getGlobalDispatcher()
|
||||||
|
when fd is AsyncFD:
|
||||||
|
if fd.SocketHandle in p.selector:
|
||||||
|
return
|
||||||
var data = newAsyncData()
|
var data = newAsyncData()
|
||||||
p.selector.registerHandle(fd.SocketHandle, {}, data)
|
p.selector.registerHandle(fd.SocketHandle, {}, data)
|
||||||
|
return fd.AsyncFD
|
||||||
|
|
||||||
proc closeSocket*(sock: AsyncFD) =
|
proc closeSocket*(sock: AsyncFD) =
|
||||||
let disp = getGlobalDispatcher()
|
let disp = getGlobalDispatcher()
|
||||||
@@ -1106,6 +1122,9 @@ else:
|
|||||||
|
|
||||||
proc unregister*(ev: AsyncEvent) =
|
proc unregister*(ev: AsyncEvent) =
|
||||||
getGlobalDispatcher().selector.unregister(SelectEvent(ev))
|
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) =
|
proc addRead*(fd: AsyncFD, cb: Callback) =
|
||||||
let p = getGlobalDispatcher()
|
let p = getGlobalDispatcher()
|
||||||
|
|||||||
@@ -81,11 +81,10 @@ proc getFileSize*(f: AsyncFile): int64 =
|
|||||||
else:
|
else:
|
||||||
result = lseek(f.fd.cint, 0, SEEK_END)
|
result = lseek(f.fd.cint, 0, SEEK_END)
|
||||||
|
|
||||||
proc newAsyncFile*(fd: AsyncFd): AsyncFile =
|
proc newAsyncFile*(fd: cint | AsyncFd): AsyncFile =
|
||||||
## Creates `AsyncFile` with a previously opened file descriptor `fd`.
|
## Creates `AsyncFile` with a previously opened file descriptor `fd`.
|
||||||
new result
|
new result
|
||||||
result.fd = fd
|
result.fd = register(result.fd)
|
||||||
register(result.fd)
|
|
||||||
|
|
||||||
proc openAsync*(filename: string, mode = fmRead): AsyncFile =
|
proc openAsync*(filename: string, mode = fmRead): AsyncFile =
|
||||||
## Opens a file specified by the path in ``filename`` using
|
## Opens a file specified by the path in ``filename`` using
|
||||||
@@ -97,16 +96,16 @@ proc openAsync*(filename: string, mode = fmRead): AsyncFile =
|
|||||||
when useWinUnicode:
|
when useWinUnicode:
|
||||||
let fd = createFileW(newWideCString(filename), desiredAccess,
|
let fd = createFileW(newWideCString(filename), desiredAccess,
|
||||||
FILE_SHARE_READ,
|
FILE_SHARE_READ,
|
||||||
nil, creationDisposition, flags, 0).AsyncFd
|
nil, creationDisposition, flags, 0)
|
||||||
else:
|
else:
|
||||||
let fd = createFileA(filename, desiredAccess,
|
let fd = createFileA(filename, desiredAccess,
|
||||||
FILE_SHARE_READ,
|
FILE_SHARE_READ,
|
||||||
nil, creationDisposition, flags, 0).AsyncFd
|
nil, creationDisposition, flags, 0)
|
||||||
|
|
||||||
if fd.Handle == INVALID_HANDLE_VALUE:
|
if fd == INVALID_HANDLE_VALUE:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
|
|
||||||
result = newAsyncFile(fd)
|
result = newAsyncFile(fd.cint)
|
||||||
|
|
||||||
if mode == fmAppend:
|
if mode == fmAppend:
|
||||||
result.offset = getFileSize(result)
|
result.offset = getFileSize(result)
|
||||||
@@ -115,7 +114,7 @@ proc openAsync*(filename: string, mode = fmRead): AsyncFile =
|
|||||||
let flags = getPosixFlags(mode)
|
let flags = getPosixFlags(mode)
|
||||||
# RW (Owner), RW (Group), R (Other)
|
# RW (Owner), RW (Group), R (Other)
|
||||||
let perm = S_IRUSR or S_IWUSR or S_IRGRP or S_IWGRP or S_IROTH
|
let perm = S_IRUSR or S_IWUSR or S_IRGRP or S_IWGRP or S_IROTH
|
||||||
let fd = open(filename, flags, perm).AsyncFD
|
let fd = open(filename, flags, perm)
|
||||||
if fd.cint == -1:
|
if fd.cint == -1:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user