Fix UB (data race) in Q_GLOBAL_STATIC

The store to guard in the inner function's critical
section was not synchronized-with the load at the
start of the function:

    T1                    T2
    guard.load()
    mutex.lock()
    guard.load()
    d = new Type
    guard.store()
                          guard.load()
                          // use d
    mutex.unlock()

The use of d in T2 does not synchronize with
the write to d in T1 -> data race -> UB.

Fix by storing with release memory ordering,
so that the guard.load() in T2 synchronizes
with the guard.store() in T1.

Change-Id: I5c1cd1fa097c6397cb0b48b0d8e8012f95978558
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
Marc Mutz 2016-04-29 11:27:11 +02:00
parent a4d26cf522
commit 54d95d0988

View File

@ -110,7 +110,7 @@ QT_BEGIN_NAMESPACE
guard.store(QtGlobalStatic::Destroyed); \
} \
} cleanup; \
guard.store(QtGlobalStatic::Initialized); \
guard.storeRelease(QtGlobalStatic::Initialized); \
} \
} \
return d; \