Avoid other threads blocking for Q_GLOBAL_STATIC constructor on Mac

The compiler inserts __cxa_guard_acquire, __cxa_guard_release calls around
the initialization of local static objects to make the initialization
thread safe. However, the implementation of _cxa_guard_acquire in Apple's
libc++abi uses a global lock, which means that only one thread can
initialize a local static variable at a time. This can be a problem if
e.g. the constructor of the variable is blocking while waiting for another
thread ...

This behavior has caused issues so far in webkit and the qml debugging
infrastructure. Better avoid it by using our custom lock implementation.

__cxa_guard_acquire implementation:
http://www.opensource.apple.com/source/libcppabi/libcppabi-24.2/src/cxa_guard.cxx

Task-number: QTBUG-33967
Change-Id: I0d50531ed91ddd074aa07f61f6bf7791e23d990b
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Kai Koehne 2013-10-09 12:08:43 +02:00 committed by The Qt Project
parent 89c01c3242
commit 816e7f11f1

View File

@ -57,11 +57,16 @@ enum GuardValues {
};
}
#if defined(QT_NO_THREAD) || defined(Q_CC_GNU)
#if defined(QT_NO_THREAD) || (defined(Q_CC_GNU) && !defined(Q_OS_MAC))
// some compilers support thread-safe statics
// The IA-64 C++ ABI requires this, so we know that all GCC versions since 3.4
// support it. C++11 also requires this behavior.
// Clang and Intel CC masquerade as GCC when compiling on Linux and Mac OS X.
// Clang and Intel CC masquerade as GCC when compiling on Linux.
//
// Apple's libc++abi however uses a global lock for initializing local statics,
// which will block other threads also trying to initialize a local static
// until the constructor returns ...
// We better avoid these kind of problems by using our own locked implementation.
#define Q_GLOBAL_STATIC_INTERNAL(ARGS) \
Q_DECL_HIDDEN inline Type *innerFunction() \