aboutsummaryrefslogtreecommitdiff
path: root/zencore/iobuffer.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-05-28 00:29:17 +0200
committerDan Engelbrecht <[email protected]>2022-05-28 00:29:17 +0200
commitda0ca23fa55f7e900853bdfd06523b78fce32259 (patch)
tree8b2190cb5341d01fcd9efa9026b1b14f227123bc /zencore/iobuffer.cpp
parentHorde execute compressed input blobs (#109) (diff)
downloadzen-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.cpp45
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;