|
|
@ -48,7 +48,8 @@ ThreadStatusUpdater* CreateThreadStatusUpdater() { |
|
|
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
namespace { |
|
|
|
|
|
|
|
|
|
|
|
static const size_t kSectorSize = 512; // Sector size used when physical sector size could not be obtained from device.
|
|
|
|
// Sector size used when physical sector size cannot be obtained from device.
|
|
|
|
|
|
|
|
static const size_t kSectorSize = 512; |
|
|
|
|
|
|
|
|
|
|
|
// RAII helpers for HANDLEs
|
|
|
|
// RAII helpers for HANDLEs
|
|
|
|
const auto CloseHandleFunc = [](HANDLE h) { ::CloseHandle(h); }; |
|
|
|
const auto CloseHandleFunc = [](HANDLE h) { ::CloseHandle(h); }; |
|
|
@ -96,7 +97,8 @@ WinEnvIO::WinEnvIO(Env* hosted_env) |
|
|
|
|
|
|
|
|
|
|
|
HMODULE module = GetModuleHandle("kernel32.dll"); |
|
|
|
HMODULE module = GetModuleHandle("kernel32.dll"); |
|
|
|
if (module != NULL) { |
|
|
|
if (module != NULL) { |
|
|
|
GetSystemTimePreciseAsFileTime_ = (FnGetSystemTimePreciseAsFileTime)GetProcAddress( |
|
|
|
GetSystemTimePreciseAsFileTime_ = |
|
|
|
|
|
|
|
(FnGetSystemTimePreciseAsFileTime)GetProcAddress( |
|
|
|
module, "GetSystemTimePreciseAsFileTime"); |
|
|
|
module, "GetSystemTimePreciseAsFileTime"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -195,8 +197,8 @@ Status WinEnvIO::NewRandomAccessFile(const std::string& fname, |
|
|
|
HANDLE hFile = 0; |
|
|
|
HANDLE hFile = 0; |
|
|
|
{ |
|
|
|
{ |
|
|
|
IOSTATS_TIMER_GUARD(open_nanos); |
|
|
|
IOSTATS_TIMER_GUARD(open_nanos); |
|
|
|
hFile = |
|
|
|
hFile = RX_CreateFile( |
|
|
|
RX_CreateFile(RX_FN(fname).c_str(), GENERIC_READ, |
|
|
|
RX_FN(fname).c_str(), GENERIC_READ, |
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
|
|
|
NULL, OPEN_EXISTING, fileFlags, NULL); |
|
|
|
NULL, OPEN_EXISTING, fileFlags, NULL); |
|
|
|
} |
|
|
|
} |
|
|
@ -224,7 +226,7 @@ Status WinEnvIO::NewRandomAccessFile(const std::string& fname, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
HANDLE hMap = RX_CreateFileMapping(hFile, NULL, PAGE_READONLY, |
|
|
|
HANDLE hMap = RX_CreateFileMapping(hFile, NULL, PAGE_READONLY, |
|
|
|
0, // Whole file at its present length
|
|
|
|
0, // At its present length
|
|
|
|
0, |
|
|
|
0, |
|
|
|
NULL); // Mapping name
|
|
|
|
NULL); // Mapping name
|
|
|
|
|
|
|
|
|
|
|
@ -259,7 +261,9 @@ Status WinEnvIO::NewRandomAccessFile(const std::string& fname, |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
result->reset(new WinRandomAccessFile(fname, hFile, |
|
|
|
result->reset(new WinRandomAccessFile(fname, hFile, |
|
|
|
std::max(GetSectorSize(fname), page_size_), options)); |
|
|
|
std::max(GetSectorSize(fname), |
|
|
|
|
|
|
|
page_size_), |
|
|
|
|
|
|
|
options)); |
|
|
|
fileGuard.release(); |
|
|
|
fileGuard.release(); |
|
|
|
} |
|
|
|
} |
|
|
|
return s; |
|
|
|
return s; |
|
|
@ -313,7 +317,8 @@ Status WinEnvIO::OpenWritableFile(const std::string& fname, |
|
|
|
desired_access, // Access desired
|
|
|
|
desired_access, // Access desired
|
|
|
|
shared_mode, |
|
|
|
shared_mode, |
|
|
|
NULL, // Security attributes
|
|
|
|
NULL, // Security attributes
|
|
|
|
creation_disposition, // Posix env says (reopen) ? (O_CREATE | O_APPEND) : O_CREAT | O_TRUNC
|
|
|
|
// Posix env says (reopen) ? (O_CREATE | O_APPEND) : O_CREAT | O_TRUNC
|
|
|
|
|
|
|
|
creation_disposition, |
|
|
|
fileFlags, // Flags
|
|
|
|
fileFlags, // Flags
|
|
|
|
NULL); // Template File
|
|
|
|
NULL); // Template File
|
|
|
|
} |
|
|
|
} |
|
|
@ -332,7 +337,8 @@ Status WinEnvIO::OpenWritableFile(const std::string& fname, |
|
|
|
if (!ret) { |
|
|
|
if (!ret) { |
|
|
|
auto lastError = GetLastError(); |
|
|
|
auto lastError = GetLastError(); |
|
|
|
return IOErrorFromWindowsError( |
|
|
|
return IOErrorFromWindowsError( |
|
|
|
"Failed to create a ReopenWritableFile move to the end: " + fname, lastError); |
|
|
|
"Failed to create a ReopenWritableFile move to the end: " + fname, |
|
|
|
|
|
|
|
lastError); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -344,14 +350,17 @@ Status WinEnvIO::OpenWritableFile(const std::string& fname, |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// Here we want the buffer allocation to be aligned by the SSD page size
|
|
|
|
// Here we want the buffer allocation to be aligned by the SSD page size
|
|
|
|
// and to be a multiple of it
|
|
|
|
// and to be a multiple of it
|
|
|
|
result->reset(new WinWritableFile(fname, hFile, std::max(GetSectorSize(fname), GetPageSize()), |
|
|
|
result->reset(new WinWritableFile(fname, hFile, |
|
|
|
|
|
|
|
std::max(GetSectorSize(fname), |
|
|
|
|
|
|
|
GetPageSize()), |
|
|
|
c_BufferCapacity, local_options)); |
|
|
|
c_BufferCapacity, local_options)); |
|
|
|
} |
|
|
|
} |
|
|
|
return s; |
|
|
|
return s; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Status WinEnvIO::NewRandomRWFile(const std::string & fname, |
|
|
|
Status WinEnvIO::NewRandomRWFile(const std::string & fname, |
|
|
|
std::unique_ptr<RandomRWFile>* result, const EnvOptions & options) { |
|
|
|
std::unique_ptr<RandomRWFile>* result, |
|
|
|
|
|
|
|
const EnvOptions & options) { |
|
|
|
|
|
|
|
|
|
|
|
Status s; |
|
|
|
Status s; |
|
|
|
|
|
|
|
|
|
|
@ -388,14 +397,17 @@ Status WinEnvIO::NewRandomRWFile(const std::string & fname, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
UniqueCloseHandlePtr fileGuard(hFile, CloseHandleFunc); |
|
|
|
UniqueCloseHandlePtr fileGuard(hFile, CloseHandleFunc); |
|
|
|
result->reset(new WinRandomRWFile(fname, hFile, std::max(GetSectorSize(fname), GetPageSize()), |
|
|
|
result->reset(new WinRandomRWFile(fname, hFile, |
|
|
|
|
|
|
|
std::max(GetSectorSize(fname), |
|
|
|
|
|
|
|
GetPageSize()), |
|
|
|
options)); |
|
|
|
options)); |
|
|
|
fileGuard.release(); |
|
|
|
fileGuard.release(); |
|
|
|
|
|
|
|
|
|
|
|
return s; |
|
|
|
return s; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Status WinEnvIO::NewMemoryMappedFileBuffer(const std::string & fname, |
|
|
|
Status WinEnvIO::NewMemoryMappedFileBuffer( |
|
|
|
|
|
|
|
const std::string & fname, |
|
|
|
std::unique_ptr<MemoryMappedFileBuffer>* result) { |
|
|
|
std::unique_ptr<MemoryMappedFileBuffer>* result) { |
|
|
|
Status s; |
|
|
|
Status s; |
|
|
|
result->reset(); |
|
|
|
result->reset(); |
|
|
@ -416,8 +428,8 @@ Status WinEnvIO::NewMemoryMappedFileBuffer(const std::string & fname, |
|
|
|
|
|
|
|
|
|
|
|
if (INVALID_HANDLE_VALUE == hFile) { |
|
|
|
if (INVALID_HANDLE_VALUE == hFile) { |
|
|
|
auto lastError = GetLastError(); |
|
|
|
auto lastError = GetLastError(); |
|
|
|
s = IOErrorFromWindowsError("Failed to open NewMemoryMappedFileBuffer: " + fname, |
|
|
|
s = IOErrorFromWindowsError( |
|
|
|
lastError); |
|
|
|
"Failed to open NewMemoryMappedFileBuffer: " + fname, lastError); |
|
|
|
return s; |
|
|
|
return s; |
|
|
|
} |
|
|
|
} |
|
|
|
UniqueCloseHandlePtr fileGuard(hFile, CloseHandleFunc); |
|
|
|
UniqueCloseHandlePtr fileGuard(hFile, CloseHandleFunc); |
|
|
@ -429,13 +441,15 @@ Status WinEnvIO::NewMemoryMappedFileBuffer(const std::string & fname, |
|
|
|
} |
|
|
|
} |
|
|
|
// Will not map empty files
|
|
|
|
// Will not map empty files
|
|
|
|
if (fileSize == 0) { |
|
|
|
if (fileSize == 0) { |
|
|
|
return Status::NotSupported("NewMemoryMappedFileBuffer can not map zero length files: " + fname); |
|
|
|
return Status::NotSupported( |
|
|
|
|
|
|
|
"NewMemoryMappedFileBuffer can not map zero length files: " + fname); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// size_t is 32-bit with 32-bit builds
|
|
|
|
// size_t is 32-bit with 32-bit builds
|
|
|
|
if (fileSize > std::numeric_limits<size_t>::max()) { |
|
|
|
if (fileSize > std::numeric_limits<size_t>::max()) { |
|
|
|
return Status::NotSupported( |
|
|
|
return Status::NotSupported( |
|
|
|
"The specified file size does not fit into 32-bit memory addressing: " + fname); |
|
|
|
"The specified file size does not fit into 32-bit memory addressing: " |
|
|
|
|
|
|
|
+ fname); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
HANDLE hMap = RX_CreateFileMapping(hFile, NULL, PAGE_READWRITE, |
|
|
|
HANDLE hMap = RX_CreateFileMapping(hFile, NULL, PAGE_READWRITE, |
|
|
@ -446,8 +460,7 @@ Status WinEnvIO::NewMemoryMappedFileBuffer(const std::string & fname, |
|
|
|
if (!hMap) { |
|
|
|
if (!hMap) { |
|
|
|
auto lastError = GetLastError(); |
|
|
|
auto lastError = GetLastError(); |
|
|
|
return IOErrorFromWindowsError( |
|
|
|
return IOErrorFromWindowsError( |
|
|
|
"Failed to create file mapping for NewMemoryMappedFileBuffer: " + fname, |
|
|
|
"Failed to create file mapping for: " + fname, lastError); |
|
|
|
lastError); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
UniqueCloseHandlePtr mapGuard(hMap, CloseHandleFunc); |
|
|
|
UniqueCloseHandlePtr mapGuard(hMap, CloseHandleFunc); |
|
|
|
|
|
|
|
|
|
|
@ -464,8 +477,8 @@ Status WinEnvIO::NewMemoryMappedFileBuffer(const std::string & fname, |
|
|
|
lastError); |
|
|
|
lastError); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
result->reset(new WinMemoryMappedBuffer(hFile, hMap,
|
|
|
|
result->reset(new WinMemoryMappedBuffer(hFile, hMap, base, |
|
|
|
base, static_cast<size_t>(fileSize))); |
|
|
|
static_cast<size_t>(fileSize))); |
|
|
|
|
|
|
|
|
|
|
|
mapGuard.release(); |
|
|
|
mapGuard.release(); |
|
|
|
fileGuard.release(); |
|
|
|
fileGuard.release(); |
|
|
@ -489,7 +502,8 @@ Status WinEnvIO::NewDirectory(const std::string& name, |
|
|
|
// 0 - for access means read metadata
|
|
|
|
// 0 - for access means read metadata
|
|
|
|
{ |
|
|
|
{ |
|
|
|
IOSTATS_TIMER_GUARD(open_nanos); |
|
|
|
IOSTATS_TIMER_GUARD(open_nanos); |
|
|
|
handle = RX_CreateFile(RX_FN(name).c_str(), 0, |
|
|
|
handle = RX_CreateFile( |
|
|
|
|
|
|
|
RX_FN(name).c_str(), 0, |
|
|
|
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, |
|
|
|
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, |
|
|
|
NULL, |
|
|
|
NULL, |
|
|
|
OPEN_EXISTING, |
|
|
|
OPEN_EXISTING, |
|
|
@ -499,8 +513,7 @@ Status WinEnvIO::NewDirectory(const std::string& name, |
|
|
|
|
|
|
|
|
|
|
|
if (INVALID_HANDLE_VALUE == handle) { |
|
|
|
if (INVALID_HANDLE_VALUE == handle) { |
|
|
|
auto lastError = GetLastError(); |
|
|
|
auto lastError = GetLastError(); |
|
|
|
s = IOErrorFromWindowsError( |
|
|
|
s = IOErrorFromWindowsError("open folder: " + name, lastError); |
|
|
|
"open folder: " + name, lastError); |
|
|
|
|
|
|
|
return s; |
|
|
|
return s; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -515,7 +528,8 @@ Status WinEnvIO::FileExists(const std::string& fname) { |
|
|
|
// which is consistent with _access() impl on windows
|
|
|
|
// which is consistent with _access() impl on windows
|
|
|
|
// but can be added
|
|
|
|
// but can be added
|
|
|
|
WIN32_FILE_ATTRIBUTE_DATA attrs; |
|
|
|
WIN32_FILE_ATTRIBUTE_DATA attrs; |
|
|
|
if (FALSE == RX_GetFileAttributesEx(RX_FN(fname).c_str(), GetFileExInfoStandard, &attrs)) { |
|
|
|
if (FALSE == RX_GetFileAttributesEx(RX_FN(fname).c_str(), |
|
|
|
|
|
|
|
GetFileExInfoStandard, &attrs)) { |
|
|
|
auto lastError = GetLastError(); |
|
|
|
auto lastError = GetLastError(); |
|
|
|
switch (lastError) { |
|
|
|
switch (lastError) { |
|
|
|
case ERROR_ACCESS_DENIED: |
|
|
|
case ERROR_ACCESS_DENIED: |
|
|
@ -546,7 +560,8 @@ Status WinEnvIO::GetChildren(const std::string& dir, |
|
|
|
pattern.append("\\").append("*"); |
|
|
|
pattern.append("\\").append("*"); |
|
|
|
|
|
|
|
|
|
|
|
HANDLE handle = RX_FindFirstFileEx(RX_FN(pattern).c_str(), |
|
|
|
HANDLE handle = RX_FindFirstFileEx(RX_FN(pattern).c_str(), |
|
|
|
FindExInfoBasic, // Do not want alternative name
|
|
|
|
// Do not want alternative name
|
|
|
|
|
|
|
|
FindExInfoBasic, |
|
|
|
&data, |
|
|
|
&data, |
|
|
|
FindExSearchNameMatch, |
|
|
|
FindExSearchNameMatch, |
|
|
|
NULL, // lpSearchFilter
|
|
|
|
NULL, // lpSearchFilter
|
|
|
@ -631,7 +646,8 @@ Status WinEnvIO::DeleteDir(const std::string& name) { |
|
|
|
BOOL ret = RX_RemoveDirectory(RX_FN(name).c_str()); |
|
|
|
BOOL ret = RX_RemoveDirectory(RX_FN(name).c_str()); |
|
|
|
if (!ret) { |
|
|
|
if (!ret) { |
|
|
|
auto lastError = GetLastError(); |
|
|
|
auto lastError = GetLastError(); |
|
|
|
result = IOErrorFromWindowsError("Failed to remove dir: " + name, lastError); |
|
|
|
result = IOErrorFromWindowsError("Failed to remove dir: " + name, |
|
|
|
|
|
|
|
lastError); |
|
|
|
} |
|
|
|
} |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
@ -641,7 +657,8 @@ Status WinEnvIO::GetFileSize(const std::string& fname, |
|
|
|
Status s; |
|
|
|
Status s; |
|
|
|
|
|
|
|
|
|
|
|
WIN32_FILE_ATTRIBUTE_DATA attrs; |
|
|
|
WIN32_FILE_ATTRIBUTE_DATA attrs; |
|
|
|
if (RX_GetFileAttributesEx(RX_FN(fname).c_str(), GetFileExInfoStandard, &attrs)) { |
|
|
|
if (RX_GetFileAttributesEx(RX_FN(fname).c_str(), GetFileExInfoStandard, |
|
|
|
|
|
|
|
&attrs)) { |
|
|
|
ULARGE_INTEGER file_size; |
|
|
|
ULARGE_INTEGER file_size; |
|
|
|
file_size.HighPart = attrs.nFileSizeHigh; |
|
|
|
file_size.HighPart = attrs.nFileSizeHigh; |
|
|
|
file_size.LowPart = attrs.nFileSizeLow; |
|
|
|
file_size.LowPart = attrs.nFileSizeLow; |
|
|
@ -676,7 +693,8 @@ Status WinEnvIO::GetFileModificationTime(const std::string& fname, |
|
|
|
Status s; |
|
|
|
Status s; |
|
|
|
|
|
|
|
|
|
|
|
WIN32_FILE_ATTRIBUTE_DATA attrs; |
|
|
|
WIN32_FILE_ATTRIBUTE_DATA attrs; |
|
|
|
if (RX_GetFileAttributesEx(RX_FN(fname).c_str(), GetFileExInfoStandard, &attrs)) { |
|
|
|
if (RX_GetFileAttributesEx(RX_FN(fname).c_str(), GetFileExInfoStandard, |
|
|
|
|
|
|
|
&attrs)) { |
|
|
|
*file_mtime = FileTimeToUnixTime(attrs.ftLastWriteTime); |
|
|
|
*file_mtime = FileTimeToUnixTime(attrs.ftLastWriteTime); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
auto lastError = GetLastError(); |
|
|
|
auto lastError = GetLastError(); |
|
|
@ -694,7 +712,8 @@ Status WinEnvIO::RenameFile(const std::string& src, |
|
|
|
|
|
|
|
|
|
|
|
// rename() is not capable of replacing the existing file as on Linux
|
|
|
|
// rename() is not capable of replacing the existing file as on Linux
|
|
|
|
// so use OS API directly
|
|
|
|
// so use OS API directly
|
|
|
|
if (!RX_MoveFileEx(RX_FN(src).c_str(), RX_FN(target).c_str(), MOVEFILE_REPLACE_EXISTING)) { |
|
|
|
if (!RX_MoveFileEx(RX_FN(src).c_str(), RX_FN(target).c_str(), |
|
|
|
|
|
|
|
MOVEFILE_REPLACE_EXISTING)) { |
|
|
|
DWORD lastError = GetLastError(); |
|
|
|
DWORD lastError = GetLastError(); |
|
|
|
|
|
|
|
|
|
|
|
std::string text("Failed to rename: "); |
|
|
|
std::string text("Failed to rename: "); |
|
|
@ -765,7 +784,8 @@ Status WinEnvIO::AreFilesSame(const std::string& first, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 0 - for access means read metadata
|
|
|
|
// 0 - for access means read metadata
|
|
|
|
HANDLE file_1 = RX_CreateFile(RX_FN(first).c_str(), 0,
|
|
|
|
HANDLE file_1 = RX_CreateFile( |
|
|
|
|
|
|
|
RX_FN(first).c_str(), 0, |
|
|
|
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, |
|
|
|
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, |
|
|
|
NULL, |
|
|
|
NULL, |
|
|
|
OPEN_EXISTING, |
|
|
|
OPEN_EXISTING, |
|
|
@ -774,13 +794,13 @@ Status WinEnvIO::AreFilesSame(const std::string& first, |
|
|
|
|
|
|
|
|
|
|
|
if (INVALID_HANDLE_VALUE == file_1) { |
|
|
|
if (INVALID_HANDLE_VALUE == file_1) { |
|
|
|
auto lastError = GetLastError(); |
|
|
|
auto lastError = GetLastError(); |
|
|
|
s = IOErrorFromWindowsError( |
|
|
|
s = IOErrorFromWindowsError("open file: " + first, lastError); |
|
|
|
"open file: " + first, lastError); |
|
|
|
|
|
|
|
return s; |
|
|
|
return s; |
|
|
|
} |
|
|
|
} |
|
|
|
UniqueCloseHandlePtr g_1(file_1, CloseHandleFunc); |
|
|
|
UniqueCloseHandlePtr g_1(file_1, CloseHandleFunc); |
|
|
|
|
|
|
|
|
|
|
|
HANDLE file_2 = RX_CreateFile(RX_FN(second).c_str(), 0, |
|
|
|
HANDLE file_2 = RX_CreateFile( |
|
|
|
|
|
|
|
RX_FN(second).c_str(), 0, |
|
|
|
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, |
|
|
|
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, |
|
|
|
NULL, OPEN_EXISTING, |
|
|
|
NULL, OPEN_EXISTING, |
|
|
|
FILE_FLAG_BACKUP_SEMANTICS, // make opening folders possible
|
|
|
|
FILE_FLAG_BACKUP_SEMANTICS, // make opening folders possible
|
|
|
@ -788,8 +808,7 @@ Status WinEnvIO::AreFilesSame(const std::string& first, |
|
|
|
|
|
|
|
|
|
|
|
if (INVALID_HANDLE_VALUE == file_2) { |
|
|
|
if (INVALID_HANDLE_VALUE == file_2) { |
|
|
|
auto lastError = GetLastError(); |
|
|
|
auto lastError = GetLastError(); |
|
|
|
s = IOErrorFromWindowsError( |
|
|
|
s = IOErrorFromWindowsError("open file: " + second, lastError); |
|
|
|
"open file: " + second, lastError); |
|
|
|
|
|
|
|
return s; |
|
|
|
return s; |
|
|
|
} |
|
|
|
} |
|
|
|
UniqueCloseHandlePtr g_2(file_2, CloseHandleFunc); |
|
|
|
UniqueCloseHandlePtr g_2(file_2, CloseHandleFunc); |
|
|
@ -800,8 +819,7 @@ Status WinEnvIO::AreFilesSame(const std::string& first, |
|
|
|
|
|
|
|
|
|
|
|
if (!result) { |
|
|
|
if (!result) { |
|
|
|
auto lastError = GetLastError(); |
|
|
|
auto lastError = GetLastError(); |
|
|
|
s = IOErrorFromWindowsError( |
|
|
|
s = IOErrorFromWindowsError("stat file: " + first, lastError); |
|
|
|
"stat file: " + first, lastError); |
|
|
|
|
|
|
|
return s; |
|
|
|
return s; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -811,13 +829,13 @@ Status WinEnvIO::AreFilesSame(const std::string& first, |
|
|
|
|
|
|
|
|
|
|
|
if (!result) { |
|
|
|
if (!result) { |
|
|
|
auto lastError = GetLastError(); |
|
|
|
auto lastError = GetLastError(); |
|
|
|
s = IOErrorFromWindowsError( |
|
|
|
s = IOErrorFromWindowsError("stat file: " + second, lastError); |
|
|
|
"stat file: " + second, lastError); |
|
|
|
|
|
|
|
return s; |
|
|
|
return s; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (FileInfo_1.VolumeSerialNumber == FileInfo_2.VolumeSerialNumber) { |
|
|
|
if (FileInfo_1.VolumeSerialNumber == FileInfo_2.VolumeSerialNumber) { |
|
|
|
*res = (0 == memcmp(FileInfo_1.FileId.Identifier, FileInfo_2.FileId.Identifier,
|
|
|
|
*res = (0 == memcmp(FileInfo_1.FileId.Identifier, |
|
|
|
|
|
|
|
FileInfo_2.FileId.Identifier, |
|
|
|
sizeof(FileInfo_1.FileId.Identifier))); |
|
|
|
sizeof(FileInfo_1.FileId.Identifier))); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
*res = false; |
|
|
|
*res = false; |
|
|
@ -842,7 +860,8 @@ Status WinEnvIO::LockFile(const std::string& lockFname, |
|
|
|
HANDLE hFile = 0; |
|
|
|
HANDLE hFile = 0; |
|
|
|
{ |
|
|
|
{ |
|
|
|
IOSTATS_TIMER_GUARD(open_nanos); |
|
|
|
IOSTATS_TIMER_GUARD(open_nanos); |
|
|
|
hFile = RX_CreateFile(RX_FN(lockFname).c_str(), (GENERIC_READ | GENERIC_WRITE), |
|
|
|
hFile = RX_CreateFile(RX_FN(lockFname).c_str(), |
|
|
|
|
|
|
|
(GENERIC_READ | GENERIC_WRITE), |
|
|
|
ExclusiveAccessON, NULL, CREATE_ALWAYS, |
|
|
|
ExclusiveAccessON, NULL, CREATE_ALWAYS, |
|
|
|
FILE_ATTRIBUTE_NORMAL, NULL); |
|
|
|
FILE_ATTRIBUTE_NORMAL, NULL); |
|
|
|
} |
|
|
|
} |
|
|
@ -1002,7 +1021,6 @@ Status WinEnvIO::GetHostName(char* name, uint64_t len) { |
|
|
|
|
|
|
|
|
|
|
|
Status WinEnvIO::GetAbsolutePath(const std::string& db_path, |
|
|
|
Status WinEnvIO::GetAbsolutePath(const std::string& db_path, |
|
|
|
std::string* output_path) { |
|
|
|
std::string* output_path) { |
|
|
|
|
|
|
|
|
|
|
|
// Check if we already have an absolute path
|
|
|
|
// Check if we already have an absolute path
|
|
|
|
// For test compatibility we will consider starting slash as an
|
|
|
|
// For test compatibility we will consider starting slash as an
|
|
|
|
// absolute path
|
|
|
|
// absolute path
|
|
|
@ -1092,7 +1110,8 @@ EnvOptions WinEnvIO::OptimizeForManifestRead( |
|
|
|
// Returns true iff the named directory exists and is a directory.
|
|
|
|
// Returns true iff the named directory exists and is a directory.
|
|
|
|
bool WinEnvIO::DirExists(const std::string& dname) { |
|
|
|
bool WinEnvIO::DirExists(const std::string& dname) { |
|
|
|
WIN32_FILE_ATTRIBUTE_DATA attrs; |
|
|
|
WIN32_FILE_ATTRIBUTE_DATA attrs; |
|
|
|
if (RX_GetFileAttributesEx(RX_FN(dname).c_str(), GetFileExInfoStandard, &attrs)) { |
|
|
|
if (RX_GetFileAttributesEx(RX_FN(dname).c_str(), |
|
|
|
|
|
|
|
GetFileExInfoStandard, &attrs)) { |
|
|
|
return 0 != (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); |
|
|
|
return 0 != (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -1114,8 +1133,7 @@ size_t WinEnvIO::GetSectorSize(const std::string& fname) { |
|
|
|
return sector_size; |
|
|
|
return sector_size; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
HANDLE hDevice = CreateFile(devicename, 0, 0, |
|
|
|
HANDLE hDevice = CreateFile(devicename, 0, 0, nullptr, OPEN_EXISTING, |
|
|
|
nullptr, OPEN_EXISTING, |
|
|
|
|
|
|
|
FILE_ATTRIBUTE_NORMAL, nullptr); |
|
|
|
FILE_ATTRIBUTE_NORMAL, nullptr); |
|
|
|
|
|
|
|
|
|
|
|
if (hDevice == INVALID_HANDLE_VALUE) { |
|
|
|
if (hDevice == INVALID_HANDLE_VALUE) { |
|
|
@ -1130,8 +1148,10 @@ size_t WinEnvIO::GetSectorSize(const std::string& fname) { |
|
|
|
DWORD output_bytes = 0; |
|
|
|
DWORD output_bytes = 0; |
|
|
|
|
|
|
|
|
|
|
|
BOOL ret = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, |
|
|
|
BOOL ret = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, |
|
|
|
&spropertyquery, sizeof(spropertyquery), output_buffer, |
|
|
|
&spropertyquery, sizeof(spropertyquery), |
|
|
|
sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR), &output_bytes, nullptr); |
|
|
|
output_buffer, |
|
|
|
|
|
|
|
sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR), |
|
|
|
|
|
|
|
&output_bytes, nullptr); |
|
|
|
|
|
|
|
|
|
|
|
if (ret) { |
|
|
|
if (ret) { |
|
|
|
sector_size = ((STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR *)output_buffer)->BytesPerLogicalSector; |
|
|
|
sector_size = ((STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR *)output_buffer)->BytesPerLogicalSector; |
|
|
@ -1157,7 +1177,8 @@ size_t WinEnvIO::GetSectorSize(const std::string& fname) { |
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// WinEnvThreads
|
|
|
|
// WinEnvThreads
|
|
|
|
|
|
|
|
|
|
|
|
WinEnvThreads::WinEnvThreads(Env* hosted_env) : hosted_env_(hosted_env), thread_pools_(Env::Priority::TOTAL) { |
|
|
|
WinEnvThreads::WinEnvThreads(Env* hosted_env) |
|
|
|
|
|
|
|
: hosted_env_(hosted_env), thread_pools_(Env::Priority::TOTAL) { |
|
|
|
|
|
|
|
|
|
|
|
for (int pool_id = 0; pool_id < Env::Priority::TOTAL; ++pool_id) { |
|
|
|
for (int pool_id = 0; pool_id < Env::Priority::TOTAL; ++pool_id) { |
|
|
|
thread_pools_[pool_id].SetThreadPriority( |
|
|
|
thread_pools_[pool_id].SetThreadPriority( |
|
|
@ -1176,8 +1197,9 @@ WinEnvThreads::~WinEnvThreads() { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void WinEnvThreads::Schedule(void(*function)(void*), void* arg, Env::Priority pri, |
|
|
|
void WinEnvThreads::Schedule(void(*function)(void*), void* arg, |
|
|
|
void* tag, void(*unschedFunction)(void* arg)) { |
|
|
|
Env::Priority pri, void* tag, |
|
|
|
|
|
|
|
void(*unschedFunction)(void* arg)) { |
|
|
|
assert(pri >= Env::Priority::BOTTOM && pri <= Env::Priority::HIGH); |
|
|
|
assert(pri >= Env::Priority::BOTTOM && pri <= Env::Priority::HIGH); |
|
|
|
thread_pools_[pri].Schedule(function, arg, tag, unschedFunction); |
|
|
|
thread_pools_[pri].Schedule(function, arg, tag, unschedFunction); |
|
|
|
} |
|
|
|
} |
|
|
@ -1272,8 +1294,7 @@ WinEnv::~WinEnv() { |
|
|
|
delete thread_status_updater_; |
|
|
|
delete thread_status_updater_; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Status WinEnv::GetThreadList( |
|
|
|
Status WinEnv::GetThreadList(std::vector<ThreadStatus>* thread_list) { |
|
|
|
std::vector<ThreadStatus>* thread_list) { |
|
|
|
|
|
|
|
assert(thread_status_updater_); |
|
|
|
assert(thread_status_updater_); |
|
|
|
return thread_status_updater_->GetThreadList(thread_list); |
|
|
|
return thread_status_updater_->GetThreadList(thread_list); |
|
|
|
} |
|
|
|
} |
|
|
@ -1309,16 +1330,19 @@ Status WinEnv::NewWritableFile(const std::string& fname, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Status WinEnv::ReopenWritableFile(const std::string& fname, |
|
|
|
Status WinEnv::ReopenWritableFile(const std::string& fname, |
|
|
|
std::unique_ptr<WritableFile>* result, const EnvOptions& options) { |
|
|
|
std::unique_ptr<WritableFile>* result, |
|
|
|
|
|
|
|
const EnvOptions& options) { |
|
|
|
return winenv_io_.OpenWritableFile(fname, result, options, true); |
|
|
|
return winenv_io_.OpenWritableFile(fname, result, options, true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Status WinEnv::NewRandomRWFile(const std::string & fname, |
|
|
|
Status WinEnv::NewRandomRWFile(const std::string & fname, |
|
|
|
std::unique_ptr<RandomRWFile>* result, const EnvOptions & options) { |
|
|
|
std::unique_ptr<RandomRWFile>* result, |
|
|
|
|
|
|
|
const EnvOptions & options) { |
|
|
|
return winenv_io_.NewRandomRWFile(fname, result, options); |
|
|
|
return winenv_io_.NewRandomRWFile(fname, result, options); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Status WinEnv::NewMemoryMappedFileBuffer(const std::string& fname, |
|
|
|
Status WinEnv::NewMemoryMappedFileBuffer( |
|
|
|
|
|
|
|
const std::string& fname, |
|
|
|
std::unique_ptr<MemoryMappedFileBuffer>* result) { |
|
|
|
std::unique_ptr<MemoryMappedFileBuffer>* result) { |
|
|
|
return winenv_io_.NewMemoryMappedFileBuffer(fname, result); |
|
|
|
return winenv_io_.NewMemoryMappedFileBuffer(fname, result); |
|
|
|
} |
|
|
|
} |
|
|
|