diff options
| author | Dan Engelbrecht <[email protected]> | 2022-05-28 00:29:17 +0200 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2022-05-28 00:29:17 +0200 |
| commit | da0ca23fa55f7e900853bdfd06523b78fce32259 (patch) | |
| tree | 8b2190cb5341d01fcd9efa9026b1b14f227123bc /zencore/iobuffer.cpp | |
| parent | Horde execute compressed input blobs (#109) (diff) | |
| download | zen-da0ca23fa55f7e900853bdfd06523b78fce32259.tar.xz zen-da0ca23fa55f7e900853bdfd06523b78fce32259.zip | |
Enable FILE_SHARE_DELETE on standalone files in disk buckets
This allows us to delete the file even if it is open for read.
We do a delete, the rename since we are not allowed to do a rename-overwrite, only delete.
As we have the shard lock for the file we want to replace we can safely do a delete+rename.
In the rare case that we fail to rename the file into place the old data is lost.
As this is a *cache* and it should be very rare this is OK.
Diffstat (limited to 'zencore/iobuffer.cpp')
| -rw-r--r-- | zencore/iobuffer.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/zencore/iobuffer.cpp b/zencore/iobuffer.cpp index c4b7f7bdf..61db25d0f 100644 --- a/zencore/iobuffer.cpp +++ b/zencore/iobuffer.cpp @@ -470,6 +470,51 @@ IoBufferBuilder::MakeFromFileHandle(void* FileHandle, uint64_t Offset, uint64_t } IoBuffer +IoBufferBuilder::MakeFromFileWithSharedDelete(const std::filesystem::path& FileName) +{ + uint64_t Size; + +#if ZEN_PLATFORM_WINDOWS + CAtlFile DataFile; + + HRESULT hRes = DataFile.Create(FileName.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, OPEN_EXISTING); + + if (FAILED(hRes)) + { + return {}; + } + + DataFile.GetSize((ULONGLONG&)Size); +#else + int Fd = open(FileName.c_str(), O_RDONLY | O_CLOEXEC); + if (Fd < 0) + { + return {}; + } + + static_assert(sizeof(decltype(stat::st_size)) == sizeof(uint64_t), "fstat() doesn't support large files"); + struct stat Stat; + fstat(Fd, &Stat); + Size = Stat.st_size; +#endif // ZEN_PLATFORM_WINDOWS + + if (Size) + { +#if ZEN_PLATFORM_WINDOWS + void* Fd = DataFile.Detach(); +#endif + return IoBuffer(IoBuffer::File, (void*)uintptr_t(Fd), 0, Size); + } + +#if !ZEN_PLATFORM_WINDOWS + close(Fd); +#endif + + // For an empty file, we may as well just return an empty memory IoBuffer + return IoBuffer(IoBuffer::Wrap, "", 0); +} + +IoBuffer IoBufferBuilder::MakeFromFile(const std::filesystem::path& FileName, uint64_t Offset, uint64_t Size) { uint64_t FileSize; |