@@ -156,29 +156,39 @@ private:
156156 // / aligned to kBlockAlign...
157157 static constexpr std::size_t kHeaderBlockSize = 4096 ;
158158
159- // fHeaderBlock and fBlock are raw pointers because we have to manually call operator new and delete.
160- unsigned char *fHeaderBlock = nullptr ;
161- std::size_t fBlockSize = 0 ;
162- std::uint64_t fBlockOffset = 0 ;
163- unsigned char *fBlock = nullptr ;
164-
165- // / For the simplest cases, a C file stream can be used for writing
166- FILE *fFile = nullptr ;
167159 // / Whether the C file stream has been opened with Direct I/O, introducing alignment requirements.
168160 bool fDirectIO = false ;
169- // / Keeps track of the seek offset
170- std::uint64_t fFilePos = 0 ;
171- // / Keeps track of the next key offset
172- std::uint64_t fKeyOffset = 0 ;
173- // / Keeps track of TFile control structures, which need to be updated on committing the data set
174- std::unique_ptr<ROOT ::Internal::RTFileControlBlock> fControlBlock ;
161+
162+ // / Data that is shared between a "main" RImplSimple and all its clones.
163+ // / Note that only the main file will write the header and footer, while all the clones are only
164+ // / used to (sequentially) push data into the same underlying file from multiple locations.
165+ struct RSharedData {
166+ // / For the simplest cases, a C file stream can be used for writing
167+ FILE *fFile = nullptr ;
168+ // / Keeps track of the seek offset
169+ std::uint64_t fFilePos = 0 ;
170+ // / Keeps track of the next key offset
171+ std::uint64_t fKeyOffset = 0 ;
172+
173+ // fHeaderBlock and fBlock are raw pointers because we have to manually call operator new and delete.
174+ unsigned char *fHeaderBlock = nullptr ;
175+ std::size_t fBlockSize = 0 ;
176+ std::uint64_t fBlockOffset = 0 ;
177+ unsigned char *fBlock = nullptr ;
178+
179+ // / Keeps track of TFile control structures, which need to be updated on committing the data set
180+ std::unique_ptr<ROOT ::Internal::RTFileControlBlock> fControlBlock ;
181+
182+ explicit RSharedData (FILE *file);
183+ ~RSharedData ();
184+ };
185+ std::shared_ptr<RSharedData> fShared ;
175186
176187 RImplSimple ();
177188 RImplSimple (const RImplSimple &other) = delete ;
178189 RImplSimple (RImplSimple &&other) = delete ;
179190 RImplSimple &operator =(const RImplSimple &other) = delete ;
180191 RImplSimple &operator =(RImplSimple &&other) = delete ;
181- ~RImplSimple ();
182192
183193 void AllocateBuffers (std::size_t bufferSize);
184194 void Flush ();
@@ -194,7 +204,7 @@ private:
194204 // / it must be written *before* the returned offset. (Note that the array type is purely documentation, the
195205 // / argument is actually just a pointer.)
196206 std::uint64_t ReserveBlobKey (std::size_t nbytes, std::size_t len, unsigned char keyBuffer[kBlobKeyLen ] = nullptr );
197- operator bool () const { return fFile ; }
207+ operator bool () const { return fShared -> fFile ; }
198208 };
199209
200210 template <typename T>
0 commit comments