@@ -225,18 +225,16 @@ void ADIOS2File::finalize()
225225 {
226226 return ;
227227 }
228+ if (!m_uniquePtrPuts.empty ())
229+ {
230+ throw error::Internal (
231+ " [ADIOS2 backend] Orphaned unique-ptr put operations found "
232+ " when closing file." );
233+ }
228234 // if write accessing, ensure that the engine is opened
229- // and that all datasets are written
230- // (attributes and unique_ptr datasets are written upon closing a step
231- // or a file which users might never do)
232- bool needToWrite = !m_uniquePtrPuts.empty ();
233- if ((needToWrite || !m_engine) && writeOnly (m_mode))
235+ if (!m_engine && writeOnly (m_mode))
234236 {
235237 getEngine ();
236- for (auto &entry : m_uniquePtrPuts)
237- {
238- entry.run (*this );
239- }
240238 }
241239 if (m_engine)
242240 {
@@ -1027,12 +1025,19 @@ void ADIOS2File::flush_impl(
10271025 initializedDefaults = true ;
10281026 }
10291027
1028+ std::vector<BufferedUniquePtrPut> drainedUniquePtrPuts;
10301029 if (writeLatePuts)
10311030 {
10321031 for (auto &entry : m_uniquePtrPuts)
10331032 {
10341033 entry.run (*this );
10351034 }
1035+ // Move the operations out of the queue so that no one has ideas to run
1036+ // them for a second time
1037+ drainedUniquePtrPuts = std::move (m_uniquePtrPuts);
1038+ // m_uniquePtrPuts is in a valid, but unspecified state after moving
1039+ // --> clear it
1040+ m_uniquePtrPuts.clear ();
10361041 }
10371042
10381043 if (readOnly (m_mode))
@@ -1047,10 +1052,7 @@ void ADIOS2File::flush_impl(
10471052 m_updateSpans.clear ();
10481053 m_buffer.clear ();
10491054 m_alreadyEnqueued.clear ();
1050- if (writeLatePuts)
1051- {
1052- m_uniquePtrPuts.clear ();
1053- }
1055+ drainedUniquePtrPuts.clear ();
10541056
10551057 break ;
10561058
0 commit comments