QGlobalStatic: fix atomics in ~Holder

Back when we set the guard and _then_ destroyed the object, the
atomic_thread_fence was correctly placed between the guard setting and
the dtor invocation.

We know nothing about the payload type. For all we know it could be
some fancy lockless data structure. So in general we need the acquire
fence to synchronize the reads done by the dtor with stores performed
to the object in other threads. The acquire fence did that for us.

But when we reversed the two operations, the fence has moved to after
the dtor call, leaving the dtor unprotected. Move it back to before
the dtor call.

That leaves the store to the guard unordered w.r.t. the execution of
the destructor. To fix, make it a store-release instead.

Amends e3e2674100.

Pick-to: 6.7 6.6 6.5
Change-Id: Ic7adbe17c8b474e82af4e84950c0109984b495d1
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Marc Mutz 2024-01-23 16:44:23 +01:00
parent 2699304628
commit b6537a9513
1 changed files with 3 additions and 2 deletions

View File

@ -40,9 +40,10 @@ template <typename QGS> union Holder
~Holder()
{
// import changes to *pointer() by other threads before running ~PlainType():
std::atomic_thread_fence(std::memory_order_acquire);
pointer()->~PlainType();
std::atomic_thread_fence(std::memory_order_acquire); // avoid mixing stores to guard and *pointer()
guard.storeRelaxed(QtGlobalStatic::Destroyed);
guard.storeRelease(QtGlobalStatic::Destroyed);
}
PlainType *pointer() noexcept