diff options
author | Dominik Picheta <dominikpicheta@googlemail.com> | 2016-09-02 18:21:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-02 18:21:35 +0200 |
commit | 46948a9509d77e025b33e4f890bf510b4eec9d46 (patch) | |
tree | ec7e4e4b54bd67fdfb5715818da854cef6a91d01 | |
parent | a5de03ea25712a2e948de09b32032f4632aa3bbd (diff) | |
parent | c5ffdd03897225ebcb8bef23bdb64f212c45e8e8 (diff) | |
download | Nim-46948a9509d77e025b33e4f890bf510b4eec9d46.tar.gz |
Merge pull request #4680 from cheatfate/asyncwinsend
async: protect data argument in windows send operation.
-rw-r--r-- | lib/pure/asyncdispatch.nim | 7 | ||||
-rw-r--r-- | lib/upcoming/asyncdispatch.nim | 7 |
2 files changed, 12 insertions, 2 deletions
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 79bc1b96d..cefa233be 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -827,14 +827,17 @@ when defined(windows) or defined(nimdoc): var retFuture = newFuture[void]("send") var dataBuf: TWSABuf - dataBuf.buf = data # since this is not used in a callback, this is fine + dataBuf.buf = data dataBuf.len = data.len.ULONG + GC_ref(data) # we need to protect data until send operation is completed + # or failed. var bytesReceived, lowFlags: Dword var ol = PCustomOverlapped() GC_ref(ol) ol.data = CompletionData(fd: socket, cb: proc (fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + GC_unref(data) # if operation completed `data` must be released. if not retFuture.finished: if errcode == OSErrorCode(-1): retFuture.complete() @@ -851,6 +854,8 @@ when defined(windows) or defined(nimdoc): let err = osLastError() if err.int32 != ERROR_IO_PENDING: GC_unref(ol) + GC_unref(data) # if operation failed `data` must be released, because + # completion routine will not be called. if flags.isDisconnectionError(err): retFuture.complete() else: diff --git a/lib/upcoming/asyncdispatch.nim b/lib/upcoming/asyncdispatch.nim index 19c9815d2..4a079e895 100644 --- a/lib/upcoming/asyncdispatch.nim +++ b/lib/upcoming/asyncdispatch.nim @@ -796,14 +796,17 @@ when defined(windows) or defined(nimdoc): var retFuture = newFuture[void]("send") var dataBuf: TWSABuf - dataBuf.buf = data # since this is not used in a callback, this is fine + dataBuf.buf = data dataBuf.len = data.len.ULONG + GC_ref(data) # we need to protect data until send operation is completed + # or failed. var bytesReceived, lowFlags: Dword var ol = PCustomOverlapped() GC_ref(ol) ol.data = CompletionData(fd: socket, cb: proc (fd: AsyncFD, bytesCount: Dword, errcode: OSErrorCode) = + GC_unref(data) # if operation completed `data` must be released. if not retFuture.finished: if errcode == OSErrorCode(-1): retFuture.complete() @@ -820,6 +823,8 @@ when defined(windows) or defined(nimdoc): let err = osLastError() if err.int32 != ERROR_IO_PENDING: GC_unref(ol) + GC_unref(data) # if operation failed `data` must be released, because + # completion routine will not be called. if flags.isDisconnectionError(err): retFuture.complete() else: |