From 10c141fece26f9946595028afb069cbee1502067 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Wed, 7 Dec 2022 10:55:57 +0100 Subject: Cache request record/replay (#198) This adds recording and playback of cache request with full data - both get and put operations can be replayed. Invoke via web request. `/z$/exec$/start-recording?` `/z$/exec$/stop-recording` `/z$/exec$/replay-recording?&` --- zencore/filesystem.cpp | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'zencore/filesystem.cpp') diff --git a/zencore/filesystem.cpp b/zencore/filesystem.cpp index 5e376ffda..0aa478404 100644 --- a/zencore/filesystem.cpp +++ b/zencore/filesystem.cpp @@ -947,7 +947,28 @@ PathFromHandle(void* NativeHandle) return std::filesystem::path(); } - const DWORD RequiredLengthIncludingNul = GetFinalPathNameByHandleW(NativeHandle, nullptr, 0, FILE_NAME_OPENED); + auto GetFinalPathNameByHandleWRetry = [](HANDLE hFile, LPWSTR lpszFilePath, DWORD cchFilePath, DWORD dwFlags) -> DWORD { + while (true) + { + DWORD Res = GetFinalPathNameByHandleW(hFile, lpszFilePath, cchFilePath, dwFlags); + if (Res == 0) + { + DWORD LastError = zen::GetLastError(); + // Under heavy concurrent loads we might get access denied on a file handle while trying to get path name. + // Retry if that is the case. + if (LastError != ERROR_ACCESS_DENIED) + { + ThrowSystemError(LastError, fmt::format("failed to get path from file handle {}", hFile)); + } + // Retry + continue; + } + ZEN_ASSERT(Res != 1); // We don't accept empty path names + return Res; + } + }; + + DWORD RequiredLengthIncludingNul = GetFinalPathNameByHandleWRetry(NativeHandle, nullptr, 0, FILE_NAME_OPENED); if (RequiredLengthIncludingNul == 0) { ThrowLastError(fmt::format("failed to get path from file handle {}", NativeHandle)); @@ -956,8 +977,7 @@ PathFromHandle(void* NativeHandle) std::wstring FullPath; FullPath.resize(RequiredLengthIncludingNul - 1); - const DWORD FinalLength = GetFinalPathNameByHandleW(NativeHandle, FullPath.data(), RequiredLengthIncludingNul, FILE_NAME_OPENED); - + const DWORD FinalLength = GetFinalPathNameByHandleWRetry(NativeHandle, FullPath.data(), RequiredLengthIncludingNul, FILE_NAME_OPENED); ZEN_UNUSED(FinalLength); return FullPath; -- cgit v1.2.3