diff --git a/reader/HDF5ImageSource.cpp b/reader/HDF5ImageSource.cpp index 6022ed90..c207ccfa 100644 --- a/reader/HDF5ImageSource.cpp +++ b/reader/HDF5ImageSource.cpp @@ -116,7 +116,7 @@ HDF5ImageSource::GetDataset(const HDF5ImageLocator::Location &loc) const { entry.algorithm = dcpl.GetCompression(); if (entry.direct_chunk && !loc.path.empty()) { - entry.raw = std::make_unique(loc.path); + entry.raw = std::make_shared(loc.path); if (!entry.raw->IsOpen()) entry.raw.reset(); hid_t fcpl = H5Fget_create_plist(loc.file->GetID()); @@ -148,7 +148,7 @@ HDF5ImageSource::PrepareDirectRead(const HDF5ImageLocator::Location &loc) const if (address == HADDR_UNDEF || size == 0) return {}; - return DirectChunk{ds.raw.get(), ds.user_block + address, static_cast(size), + return DirectChunk{ds.raw, ds.user_block + address, static_cast(size), ds.width, ds.height, ds.mode, ds.algorithm}; } diff --git a/reader/HDF5ImageSource.h b/reader/HDF5ImageSource.h index f2763152..97cdaf30 100644 --- a/reader/HDF5ImageSource.h +++ b/reader/HDF5ImageSource.h @@ -47,7 +47,10 @@ public: // Where the bytes of one image are, and what they decode to. Everything needed to read an image // without calling HDF5 again. struct DirectChunk { - const RawFile *file = nullptr; + // Shared, not borrowed: GetRawImage drops the HDF5 lock before reading through this, so a + // concurrent Clear() - which ReadFile() and Close() both do - would otherwise free the file + // and close its descriptor under the reader. + std::shared_ptr file; uint64_t address = 0; uint32_t size = 0; hsize_t width = 0; @@ -100,7 +103,7 @@ private: struct OpenDataset { std::shared_ptr file; std::unique_ptr dataset; - std::unique_ptr raw; + std::shared_ptr raw; // HDF5 addresses count from the end of the user block, so they are file offsets only once // its size is added. Zero for everything this project writes, but not for every file. uint64_t user_block = 0;