Merge pull request #3316 from jlp765/memfilesWinClose
bug fix: close() only unmapViewOfFile when fHandle is valid.
This commit is contained in:
commit
308a0d0a55
3 changed files with 60 additions and 4 deletions
|
|
@ -32,8 +32,9 @@ type
|
||||||
size*: int ## size of the memory mapped file
|
size*: int ## size of the memory mapped file
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
fHandle: int
|
fHandle: Handle
|
||||||
mapHandle: int
|
mapHandle: Handle
|
||||||
|
wasOpened: bool ## only close if wasOpened
|
||||||
else:
|
else:
|
||||||
handle: cint
|
handle: cint
|
||||||
|
|
||||||
|
|
@ -115,7 +116,8 @@ proc open*(filename: string, mode: FileMode = fmRead,
|
||||||
template callCreateFile(winApiProc, filename: expr): expr =
|
template callCreateFile(winApiProc, filename: expr): expr =
|
||||||
winApiProc(
|
winApiProc(
|
||||||
filename,
|
filename,
|
||||||
if readonly: GENERIC_READ else: GENERIC_ALL,
|
# GENERIC_ALL != (GENERIC_READ or GENERIC_WRITE)
|
||||||
|
if readonly: GENERIC_READ else: GENERIC_READ or GENERIC_WRITE,
|
||||||
FILE_SHARE_READ,
|
FILE_SHARE_READ,
|
||||||
nil,
|
nil,
|
||||||
if newFileSize != -1: CREATE_ALWAYS else: OPEN_EXISTING,
|
if newFileSize != -1: CREATE_ALWAYS else: OPEN_EXISTING,
|
||||||
|
|
@ -172,6 +174,8 @@ proc open*(filename: string, mode: FileMode = fmRead,
|
||||||
if mappedSize != -1: result.size = min(fileSize, mappedSize).int
|
if mappedSize != -1: result.size = min(fileSize, mappedSize).int
|
||||||
else: result.size = fileSize.int
|
else: result.size = fileSize.int
|
||||||
|
|
||||||
|
result.wasOpened = true
|
||||||
|
|
||||||
else:
|
else:
|
||||||
template fail(errCode: OSErrorCode, msg: expr) =
|
template fail(errCode: OSErrorCode, msg: expr) =
|
||||||
rollback()
|
rollback()
|
||||||
|
|
@ -226,7 +230,7 @@ proc close*(f: var MemFile) =
|
||||||
var lastErr: OSErrorCode
|
var lastErr: OSErrorCode
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
if f.fHandle != INVALID_HANDLE_VALUE:
|
if f.fHandle != INVALID_HANDLE_VALUE and f.wasOpened:
|
||||||
error = unmapViewOfFile(f.mem) == 0
|
error = unmapViewOfFile(f.mem) == 0
|
||||||
lastErr = osLastError()
|
lastErr = osLastError()
|
||||||
error = (closeHandle(f.mapHandle) == 0) or error
|
error = (closeHandle(f.mapHandle) == 0) or error
|
||||||
|
|
@ -243,6 +247,7 @@ proc close*(f: var MemFile) =
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
f.fHandle = 0
|
f.fHandle = 0
|
||||||
f.mapHandle = 0
|
f.mapHandle = 0
|
||||||
|
f.wasOpened = false
|
||||||
else:
|
else:
|
||||||
f.handle = 0
|
f.handle = 0
|
||||||
|
|
||||||
|
|
|
||||||
13
tests/stdlib/tmemfiles1.nim
Normal file
13
tests/stdlib/tmemfiles1.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
discard """
|
||||||
|
test that closing a closed file is ignored (no error raised)
|
||||||
|
file: "tmemfiles1.nim"
|
||||||
|
"""
|
||||||
|
import memfiles, os
|
||||||
|
var
|
||||||
|
mm: MemFile
|
||||||
|
fn = "test.mmap"
|
||||||
|
# Create a new file
|
||||||
|
mm = memfiles.open(fn, mode = fmReadWrite, newFileSize = 20)
|
||||||
|
mm.close()
|
||||||
|
mm.close()
|
||||||
|
if fileExists(fn): removeFile(fn)
|
||||||
38
tests/stdlib/tmemfiles2.nim
Normal file
38
tests/stdlib/tmemfiles2.nim
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
discard """
|
||||||
|
test creating/reading/writing/changing memfiles
|
||||||
|
file: "tmemfiles2.nim"
|
||||||
|
output: '''Full read size: 20
|
||||||
|
Half read size: 10 Data: Hello'''
|
||||||
|
"""
|
||||||
|
import memfiles, os
|
||||||
|
var
|
||||||
|
mm, mm_full, mm_half: MemFile
|
||||||
|
fn = "test.mmap"
|
||||||
|
p: pointer
|
||||||
|
|
||||||
|
if fileExists(fn): removeFile(fn)
|
||||||
|
|
||||||
|
# Create a new file, data all zeros
|
||||||
|
mm = memfiles.open(fn, mode = fmReadWrite, newFileSize = 20)
|
||||||
|
mm.close()
|
||||||
|
|
||||||
|
# read, change
|
||||||
|
mm_full = memfiles.open(fn, mode = fmWrite, mappedSize = -1)
|
||||||
|
echo "Full read size: ",mm_full.size
|
||||||
|
p = mm_full.mapMem(fmReadWrite, 20, 0)
|
||||||
|
var p2 = cast[cstring](p)
|
||||||
|
p2[0] = 'H'
|
||||||
|
p2[1] = 'e'
|
||||||
|
p2[2] = 'l'
|
||||||
|
p2[3] = 'l'
|
||||||
|
p2[4] = 'o'
|
||||||
|
p2[5] = '\0'
|
||||||
|
mm_full.unmapMem(p, 20)
|
||||||
|
mm_full.close()
|
||||||
|
|
||||||
|
# read half, and verify data change
|
||||||
|
mm_half = memfiles.open(fn, mode = fmRead, mappedSize = 10)
|
||||||
|
echo "Half read size: ",mm_half.size, " Data: ", cast[cstring](mm_half.mem)
|
||||||
|
mm_half.close()
|
||||||
|
|
||||||
|
if fileExists(fn): removeFile(fn)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue