diff options
-rw-r--r-- | lib/pure/asyncfile.nim | 10 | ||||
-rw-r--r-- | tests/async/tasyncfilewrite.nim | 17 | ||||
-rw-r--r-- | tools/nimgrab.nim | 6 |
3 files changed, 28 insertions, 5 deletions
diff --git a/lib/pure/asyncfile.nim b/lib/pure/asyncfile.nim index 9bd060e30..8fb30075c 100644 --- a/lib/pure/asyncfile.nim +++ b/lib/pure/asyncfile.nim @@ -339,13 +339,17 @@ proc writeBuffer*(f: AsyncFile, buf: pointer, size: int): Future[void] = if not retFuture.finished: if errcode == OSErrorCode(-1): assert bytesCount == size.int32 - f.offset.inc(size) retFuture.complete() else: retFuture.fail(newException(OSError, osErrorMsg(errcode))) ) + # passing -1 here should work according to MSDN, but doesn't. For more + # information see + # http://stackoverflow.com/questions/33650899/does-asynchronous-file- + # appending-in-windows-preserve-order ol.offset = DWord(f.offset and 0xffffffff) ol.offsetHigh = DWord(f.offset shr 32) + f.offset.inc(size) # According to MSDN we're supposed to pass nil to lpNumberOfBytesWritten. let ret = writeFile(f.fd.Handle, buf, size.int32, nil, @@ -364,7 +368,6 @@ proc writeBuffer*(f: AsyncFile, buf: pointer, size: int): Future[void] = retFuture.fail(newException(OSError, osErrorMsg(osLastError()))) else: assert bytesWritten == size.int32 - f.offset.inc(size) retFuture.complete() else: var written = 0 @@ -410,7 +413,6 @@ proc write*(f: AsyncFile, data: string): Future[void] = if not retFuture.finished: if errcode == OSErrorCode(-1): assert bytesCount == data.len.int32 - f.offset.inc(data.len) retFuture.complete() else: retFuture.fail(newException(OSError, osErrorMsg(errcode))) @@ -420,6 +422,7 @@ proc write*(f: AsyncFile, data: string): Future[void] = ) ol.offset = DWord(f.offset and 0xffffffff) ol.offsetHigh = DWord(f.offset shr 32) + f.offset.inc(data.len) # According to MSDN we're supposed to pass nil to lpNumberOfBytesWritten. let ret = writeFile(f.fd.Handle, buffer, data.len.int32, nil, @@ -441,7 +444,6 @@ proc write*(f: AsyncFile, data: string): Future[void] = retFuture.fail(newException(OSError, osErrorMsg(osLastError()))) else: assert bytesWritten == data.len.int32 - f.offset.inc(data.len) retFuture.complete() else: var written = 0 diff --git a/tests/async/tasyncfilewrite.nim b/tests/async/tasyncfilewrite.nim new file mode 100644 index 000000000..cda612bae --- /dev/null +++ b/tests/async/tasyncfilewrite.nim @@ -0,0 +1,17 @@ +discard """ + output: '''string 1 +string 2 +string 3''' +""" +# bug #5532 +import os, asyncfile, asyncdispatch + +removeFile("test.txt") +let f = openAsync("test.txt", fmWrite) +var futs = newSeq[Future[void]]() +for i in 1..3: + futs.add(f.write("string " & $i & "\n")) +waitFor(all(futs)) +f.close() +echo readFile("test.txt") + diff --git a/tools/nimgrab.nim b/tools/nimgrab.nim index 69824369e..937a5dcd4 100644 --- a/tools/nimgrab.nim +++ b/tools/nimgrab.nim @@ -7,7 +7,11 @@ when defined(windows): proc progress(status: DownloadStatus, progress: uint, total: uint, message: string) {.procvar, gcsafe.} = echo "Downloading " & url - echo clamp(int(progress.BiggestInt*100 div total.BiggestInt), 0, 100), "%" + let t = total.BiggestInt + if t != 0: + echo clamp(int(progress.BiggestInt*100 div t), 0, 100), "%" + else: + echo "0%" downloadToFile(url, file, {optUseCache}, progress) echo "100%" |