From 88fc415c69792e3919504c610924f83b5a6d4748 Mon Sep 17 00:00:00 2001 From: JamesP Date: Sat, 12 Sep 2015 14:41:50 +1000 Subject: [PATCH 1/9] bug fix: close() only unmapViewOfFile() when fHandle is valid. Added extra test on windows close so if already closed it doesn't throw an exception. --- lib/pure/memfiles.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index 27b9895974..a8bfa14d30 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -226,7 +226,7 @@ proc close*(f: var MemFile) = var lastErr: OSErrorCode when defined(windows): - if f.fHandle != INVALID_HANDLE_VALUE: + if f.fHandle != INVALID_HANDLE_VALUE and f.fHandle != 0: error = unmapViewOfFile(f.mem) == 0 lastErr = osLastError() error = (closeHandle(f.mapHandle) == 0) or error From b6b2750327208477e84d4ebbdb289e8847ac2289 Mon Sep 17 00:00:00 2001 From: JamesP Date: Tue, 22 Sep 2015 15:54:44 +1000 Subject: [PATCH 2/9] Undo zero check --- lib/pure/memfiles.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index a8bfa14d30..27b9895974 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -226,7 +226,7 @@ proc close*(f: var MemFile) = var lastErr: OSErrorCode when defined(windows): - if f.fHandle != INVALID_HANDLE_VALUE and f.fHandle != 0: + if f.fHandle != INVALID_HANDLE_VALUE: error = unmapViewOfFile(f.mem) == 0 lastErr = osLastError() error = (closeHandle(f.mapHandle) == 0) or error From d23c697044e3d8d8d899b4c0d1355aeff25015f1 Mon Sep 17 00:00:00 2001 From: JamesP Date: Tue, 22 Sep 2015 16:16:51 +1000 Subject: [PATCH 3/9] Add wasOpened flag for windows, so not attempt close when unopened --- lib/pure/memfiles.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index 27b9895974..83d62b589a 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -34,6 +34,7 @@ type when defined(windows): fHandle: int mapHandle: int + wasOpened: bool else: handle: cint @@ -172,6 +173,8 @@ proc open*(filename: string, mode: FileMode = fmRead, if mappedSize != -1: result.size = min(fileSize, mappedSize).int else: result.size = fileSize.int + result.wasOpened = true + else: template fail(errCode: OSErrorCode, msg: expr) = rollback() @@ -226,7 +229,7 @@ proc close*(f: var MemFile) = var lastErr: OSErrorCode when defined(windows): - if f.fHandle != INVALID_HANDLE_VALUE: + if f.fHandle != INVALID_HANDLE_VALUE and wasOpened: error = unmapViewOfFile(f.mem) == 0 lastErr = osLastError() error = (closeHandle(f.mapHandle) == 0) or error From 7656fae4562f2b48087092026968b04c6337a2be Mon Sep 17 00:00:00 2001 From: JamesP Date: Wed, 23 Sep 2015 06:20:19 +1000 Subject: [PATCH 4/9] fix wasOpened reference and set to false on close --- lib/pure/memfiles.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index 83d62b589a..b128061fd8 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -229,7 +229,7 @@ proc close*(f: var MemFile) = var lastErr: OSErrorCode when defined(windows): - if f.fHandle != INVALID_HANDLE_VALUE and wasOpened: + if f.fHandle != INVALID_HANDLE_VALUE and f.wasOpened: error = unmapViewOfFile(f.mem) == 0 lastErr = osLastError() error = (closeHandle(f.mapHandle) == 0) or error @@ -246,6 +246,7 @@ proc close*(f: var MemFile) = when defined(windows): f.fHandle = 0 f.mapHandle = 0 + f.wasOpened = false else: f.handle = 0 From bdc1c5ee84977300265ea87d3cafa34fbcfc8a1d Mon Sep 17 00:00:00 2001 From: JamesP Date: Thu, 24 Sep 2015 09:03:03 +1000 Subject: [PATCH 5/9] change type of windows handles to Handle --- lib/pure/memfiles.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index b128061fd8..633fd71eba 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -32,9 +32,9 @@ type size*: int ## size of the memory mapped file when defined(windows): - fHandle: int - mapHandle: int - wasOpened: bool + fHandle: Handle + mapHandle: Handle + wasOpened: bool ## only close if wasOpened else: handle: cint From 305766a9fa079cbb96e8a80b3531b4c656a5e040 Mon Sep 17 00:00:00 2001 From: JamesP Date: Thu, 24 Sep 2015 09:04:55 +1000 Subject: [PATCH 6/9] Bug fix: change non-fmRead file mode to set GENERIC_READ or GENERIC_WRITE instead of GENERIC_ALL which on 64bit windows rasied an [OSError] exception --- lib/pure/memfiles.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index 633fd71eba..b9c574944c 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -116,7 +116,8 @@ proc open*(filename: string, mode: FileMode = fmRead, template callCreateFile(winApiProc, filename: expr): expr = winApiProc( 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, nil, if newFileSize != -1: CREATE_ALWAYS else: OPEN_EXISTING, From 74906675789624be14083a294e9cdcc766797797 Mon Sep 17 00:00:00 2001 From: JamesP Date: Thu, 24 Sep 2015 09:23:48 +1000 Subject: [PATCH 7/9] add memfiles test that closing a closed memFile is ignored (and raises no [OSError]) --- tests/stdlib/tmemfiles1.nim | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/stdlib/tmemfiles1.nim diff --git a/tests/stdlib/tmemfiles1.nim b/tests/stdlib/tmemfiles1.nim new file mode 100644 index 0000000000..282b454230 --- /dev/null +++ b/tests/stdlib/tmemfiles1.nim @@ -0,0 +1,13 @@ +discard """ +test that closing a closed file is ignored (no error raised) +output: nothing +""" +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) From 48932dbf982ce5c39185c9c02f7eab699f90c95c Mon Sep 17 00:00:00 2001 From: JamesP Date: Thu, 24 Sep 2015 09:34:44 +1000 Subject: [PATCH 8/9] improve discard text --- tests/stdlib/tmemfiles1.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/stdlib/tmemfiles1.nim b/tests/stdlib/tmemfiles1.nim index 282b454230..f7f39f5bc7 100644 --- a/tests/stdlib/tmemfiles1.nim +++ b/tests/stdlib/tmemfiles1.nim @@ -1,6 +1,6 @@ discard """ -test that closing a closed file is ignored (no error raised) -output: nothing + test that closing a closed file is ignored (no error raised) + file: "tmemfiles1.nim" """ import memfiles, os var From 63c35a98f47807cc42a7cb3f8555e0568f090fe8 Mon Sep 17 00:00:00 2001 From: JamesP Date: Thu, 24 Sep 2015 09:37:12 +1000 Subject: [PATCH 9/9] add memfiles test of create/read/write data --- tests/stdlib/tmemfiles2.nim | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/stdlib/tmemfiles2.nim diff --git a/tests/stdlib/tmemfiles2.nim b/tests/stdlib/tmemfiles2.nim new file mode 100644 index 0000000000..04ae8429f6 --- /dev/null +++ b/tests/stdlib/tmemfiles2.nim @@ -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)