diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-12-12 12:00:12 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-12 12:00:12 +0100 |
commit | cddc4be209604f6b1a9099660e75cd920d7d2355 (patch) | |
tree | 831352dba239fc4ba21dc93a131234339496c0f4 | |
parent | d9ae9201c442f2e1427140283f3eab77b4f8c70c (diff) | |
parent | b92594572e485fabe4bacec500ba4f9409e234c8 (diff) | |
download | Nim-cddc4be209604f6b1a9099660e75cd920d7d2355.tar.gz |
Merge pull request #9922 from c-blake/devel
Let handles be seen outside of `memfiles` module so that "updating"
-rw-r--r-- | lib/pure/memfiles.nim | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index e5345e645..d2beb629a 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -281,6 +281,35 @@ proc flush*(f: var MemFile; attempts: Natural = 3) = if lastErr != EBUSY.OSErrorCode: raiseOSError(lastErr, "error flushing mapping") +proc resize*(f: var MemFile, newFileSize: int) = + ## resize and re-map the file underlying an ``allowRemap MemFile``. NOTE: + ## this assumes the entire file is mapped read-write at offset zero. Also, + ## the value of ``.mem`` will probably change. + when defined(windows): + discard #TODO This needs to be implemented. + else: + if f.handle == -1: + raise newException(IOError, + "Cannot resize MemFile opened with allowRemap=false") + if ftruncate(f.handle, newFileSize) == -1: + raiseOSError(osLastError()) + when defined(linux): #Maybe NetBSD, too? + #On Linux this can be over 100 times faster than a munmap,mmap cycle. + proc mremap(old: pointer; oldSize,newSize: csize; flags: cint): pointer {. + importc: "mremap", header: "<sys/mman.h>" .} + let newAddr = mremap(f.mem, csize(f.size), csize(newFileSize), cint(1)) + if newAddr == cast[pointer](MAP_FAILED): + raiseOSError(osLastError()) + else: + if munmap(f.mem, f.size) != 0: + raiseOSError(osLastError()) + let newAddr = mmap(nil, newFileSize, PROT_READ or PROT_WRITE, + MAP_SHARED or MAP_POPULATE, f.handle, 0) + if newAddr == cast[pointer](MAP_FAILED): + raiseOSError(osLastError()) + f.mem = newAddr + f.size = newFileSize + proc close*(f: var MemFile) = ## closes the memory mapped file `f`. All changes are written back to the ## file system, if `f` was opened with write access. |