Merge pull request #4336 from cheatfate/protectwinrw
Implement protection on callback environment.
This commit is contained in:
commit
9837b12ee6
1 changed files with 16 additions and 0 deletions
|
|
@ -434,6 +434,9 @@ when defined(windows) or defined(nimdoc):
|
||||||
fd*: AsyncFD # TODO: Rename this.
|
fd*: AsyncFD # TODO: Rename this.
|
||||||
cb*: proc (fd: AsyncFD, bytesTransferred: Dword,
|
cb*: proc (fd: AsyncFD, bytesTransferred: Dword,
|
||||||
errcode: OSErrorCode) {.closure,gcsafe.}
|
errcode: OSErrorCode) {.closure,gcsafe.}
|
||||||
|
cell*: ForeignCell # we need this `cell` to protect our `cb` environment,
|
||||||
|
# when using RegisterWaitForSingleObject, because
|
||||||
|
# waiting is done in different thread.
|
||||||
|
|
||||||
PDispatcher* = ref object of PDispatcherBase
|
PDispatcher* = ref object of PDispatcherBase
|
||||||
ioPort: Handle
|
ioPort: Handle
|
||||||
|
|
@ -517,6 +520,13 @@ when defined(windows) or defined(nimdoc):
|
||||||
|
|
||||||
customOverlapped.data.cb(customOverlapped.data.fd,
|
customOverlapped.data.cb(customOverlapped.data.fd,
|
||||||
lpNumberOfBytesTransferred, OSErrorCode(-1))
|
lpNumberOfBytesTransferred, OSErrorCode(-1))
|
||||||
|
|
||||||
|
# If cell.data != nil, then system.protect(rawEnv(cb)) was called,
|
||||||
|
# so we need to dispose our `cb` environment, because it is not needed
|
||||||
|
# anymore.
|
||||||
|
if customOverlapped.data.cell.data != nil:
|
||||||
|
system.dispose(customOverlapped.data.cell)
|
||||||
|
|
||||||
GC_unref(customOverlapped)
|
GC_unref(customOverlapped)
|
||||||
else:
|
else:
|
||||||
let errCode = osLastError()
|
let errCode = osLastError()
|
||||||
|
|
@ -524,6 +534,8 @@ when defined(windows) or defined(nimdoc):
|
||||||
assert customOverlapped.data.fd == lpCompletionKey.AsyncFD
|
assert customOverlapped.data.fd == lpCompletionKey.AsyncFD
|
||||||
customOverlapped.data.cb(customOverlapped.data.fd,
|
customOverlapped.data.cb(customOverlapped.data.fd,
|
||||||
lpNumberOfBytesTransferred, errCode)
|
lpNumberOfBytesTransferred, errCode)
|
||||||
|
if customOverlapped.data.cell.data != nil:
|
||||||
|
system.dispose(customOverlapped.data.cell)
|
||||||
GC_unref(customOverlapped)
|
GC_unref(customOverlapped)
|
||||||
else:
|
else:
|
||||||
if errCode.int32 == WAIT_TIMEOUT:
|
if errCode.int32 == WAIT_TIMEOUT:
|
||||||
|
|
@ -1026,6 +1038,10 @@ when defined(windows) or defined(nimdoc):
|
||||||
# poll()
|
# poll()
|
||||||
GC_ref(pcd.ovl)
|
GC_ref(pcd.ovl)
|
||||||
)
|
)
|
||||||
|
# We need to protect our callback environment value, so GC will not free it
|
||||||
|
# accidentally.
|
||||||
|
ol.data.cell = system.protect(rawEnv(ol.data.cb))
|
||||||
|
|
||||||
# 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:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue