Fixes #5532 win async write (#5791)

* nimgrab tool bugfix: don't divide by zero
* fixes #5532 (asyncfile write on Windows)
* add a comment about what has been tried instead
This commit is contained in:
Andreas Rumpf
2017-05-14 17:10:39 +02:00
committed by GitHub
parent ec50dab57d
commit 3afd852f54
3 changed files with 28 additions and 5 deletions

View File

@@ -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

View File

@@ -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")

View File

@@ -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%"