mirror of
https://github.com/status-im/nim-stew.git
synced 2025-01-09 11:45:42 +00:00
Add cross-platform fsync() primitive and improve Direct mode. (#228)
This commit is contained in:
parent
fc09b2e023
commit
4d4dfb7b32
34
stew/io2.nim
34
stew/io2.nim
@ -35,6 +35,7 @@ when defined(windows):
|
|||||||
FILE_APPEND_DATA = 0x00000004'u32
|
FILE_APPEND_DATA = 0x00000004'u32
|
||||||
|
|
||||||
FILE_FLAG_NO_BUFFERING = 0x20000000'u32
|
FILE_FLAG_NO_BUFFERING = 0x20000000'u32
|
||||||
|
FILE_FLAG_WRITE_THROUGH = 0x80000000'u32
|
||||||
FILE_ATTRIBUTE_READONLY = 0x00000001'u32
|
FILE_ATTRIBUTE_READONLY = 0x00000001'u32
|
||||||
FILE_ATTRIBUTE_DIRECTORY = 0x00000010'u32
|
FILE_ATTRIBUTE_DIRECTORY = 0x00000010'u32
|
||||||
|
|
||||||
@ -200,6 +201,8 @@ when defined(windows):
|
|||||||
sideEffect.}
|
sideEffect.}
|
||||||
proc getTempPathW(nBufferLength: uint32, lpBuffer: WideCString): uint32 {.
|
proc getTempPathW(nBufferLength: uint32, lpBuffer: WideCString): uint32 {.
|
||||||
importc: "GetTempPathW", dynlib: "kernel32", stdcall, sideEffect.}
|
importc: "GetTempPathW", dynlib: "kernel32", stdcall, sideEffect.}
|
||||||
|
proc flushFileBuffers(hFile: uint): int32 {.
|
||||||
|
importc: "FlushFileBuffers", dynlib: "kernel32", stdcall, sideEffect.}
|
||||||
|
|
||||||
const
|
const
|
||||||
NO_ERROR = IoErrorCode(0)
|
NO_ERROR = IoErrorCode(0)
|
||||||
@ -1024,15 +1027,16 @@ proc openFile*(pathName: string, flags: set[OpenFlags],
|
|||||||
when defined(linux) or defined(freebsd) or defined(netbsd) or
|
when defined(linux) or defined(freebsd) or defined(netbsd) or
|
||||||
defined(dragonflybsd):
|
defined(dragonflybsd):
|
||||||
if OpenFlags.Direct in flags:
|
if OpenFlags.Direct in flags:
|
||||||
cflags = cflags or O_DIRECT
|
cflags = cflags or O_DIRECT or O_SYNC
|
||||||
if OpenFlags.Inherit notin flags:
|
if OpenFlags.Inherit notin flags:
|
||||||
cflags = cflags or O_CLOEXEC
|
cflags = cflags or O_CLOEXEC
|
||||||
if OpenFlags.NonBlock in flags:
|
if OpenFlags.NonBlock in flags:
|
||||||
cflags = cflags or posix.O_NONBLOCK
|
cflags = cflags or posix.O_NONBLOCK
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
let omask = setUmask(0)
|
let
|
||||||
let ores = posix.open(cstring(pathName), cflags, Mode(createMode))
|
omask = setUmask(0)
|
||||||
|
ores = posix.open(cstring(pathName), cflags, Mode(createMode))
|
||||||
discard setUmask(omask)
|
discard setUmask(omask)
|
||||||
if ores == -1:
|
if ores == -1:
|
||||||
let errCode = ioLastError()
|
let errCode = ioLastError()
|
||||||
@ -1041,7 +1045,7 @@ proc openFile*(pathName: string, flags: set[OpenFlags],
|
|||||||
else:
|
else:
|
||||||
return err(errCode)
|
return err(errCode)
|
||||||
else:
|
else:
|
||||||
when defined(macosx):
|
when defined(macosx) or defined(macos):
|
||||||
if OpenFlags.Direct in flags:
|
if OpenFlags.Direct in flags:
|
||||||
while true:
|
while true:
|
||||||
let fres = posix.fcntl(cint(ores), F_NOCACHE, 1)
|
let fres = posix.fcntl(cint(ores), F_NOCACHE, 1)
|
||||||
@ -1105,7 +1109,7 @@ proc openFile*(pathName: string, flags: set[OpenFlags],
|
|||||||
if OpenFlags.NonBlock in flags:
|
if OpenFlags.NonBlock in flags:
|
||||||
dwFlags = dwFlags or FILE_FLAG_OVERLAPPED
|
dwFlags = dwFlags or FILE_FLAG_OVERLAPPED
|
||||||
if OpenFlags.Direct in flags:
|
if OpenFlags.Direct in flags:
|
||||||
dwFlags = dwFlags or FILE_FLAG_NO_BUFFERING
|
dwFlags = dwFlags or FILE_FLAG_NO_BUFFERING or FILE_FLAG_WRITE_THROUGH
|
||||||
if OpenFlags.Inherit in flags:
|
if OpenFlags.Inherit in flags:
|
||||||
sa.bInheritHandle = 1
|
sa.bInheritHandle = 1
|
||||||
|
|
||||||
@ -1391,6 +1395,26 @@ proc truncate*(pathName: string, length: int64): IoResult[void] =
|
|||||||
else:
|
else:
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
|
proc fsync*(handle: IoHandle): IoResult[void] =
|
||||||
|
## Ensure that all data for the open file descriptor named by ``handle``
|
||||||
|
## is to be transferred to the storage device associated with the file.
|
||||||
|
when defined(windows):
|
||||||
|
let res = flushFileBuffers(uint(handle))
|
||||||
|
if res == 0:
|
||||||
|
return err(ioLastError())
|
||||||
|
ok()
|
||||||
|
else:
|
||||||
|
while true:
|
||||||
|
let res = posix.fsync(cint(handle))
|
||||||
|
if res == -1:
|
||||||
|
let errCode = ioLastError()
|
||||||
|
if errCode == EINTR:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
return err(errCode)
|
||||||
|
else:
|
||||||
|
return ok()
|
||||||
|
|
||||||
proc checkFileSize*(value: int64): IoResult[int] =
|
proc checkFileSize*(value: int64): IoResult[int] =
|
||||||
## Checks if ``value`` fits into supported by Nim string/sequence indexing
|
## Checks if ``value`` fits into supported by Nim string/sequence indexing
|
||||||
## mechanism.
|
## mechanism.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user