diff options
Diffstat (limited to 'src/corelib/kernel/qapplicationstatic.qdoc')
-rw-r--r-- | src/corelib/kernel/qapplicationstatic.qdoc | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/corelib/kernel/qapplicationstatic.qdoc b/src/corelib/kernel/qapplicationstatic.qdoc new file mode 100644 index 0000000000..5cbac65df9 --- /dev/null +++ b/src/corelib/kernel/qapplicationstatic.qdoc @@ -0,0 +1,109 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \macro Q_APPLICATION_STATIC(Type, VariableName, ...) + \since 6.3 + \relates QGlobalStatic + + This macro extends Q_GLOBAL_STATIC and creates a global and static object + of type \l QGlobalStatic, of name \a VariableName, initialized by the + variadic arguments, and that behaves as a pointer to \a Type, where the + actual lifetime of the type is bound to the QCoreApplication. The object + created by Q_APPLICATION_STATIC initializes itself on the first use, which + means that it will not increase the application or the library's load time. + Additionally, the object is initialized in a thread-safe manner on all + platforms. + + In contrast to Q_GLOBAL_STATIC where the type is only meant to be destroyed at + program exit, here the actual lifetime of the type is bound to the lifetime of + the QCoreApplication. This makes it ideal to store semi-static QObjects, which + should also be destroyed once the QCoreApplication is destroyed. This means the + type will get deleted once the QCoreApplication emits the destroyed signal. + It is permitted for the object to be recreated when it's accessed again, if + a new QCoreApplication has also been created. + + Since the value is bound to the QCoreApplication, it should only ever be + accessed if there is a valid QCoreApplication::instance(). Accessing this + object before QCoreApplication is created or after it's destroyed will + produce warnings and may have unpredictable behavior. + + The typical use of this macro is as follows, in a global context (that is, + outside of any function bodies): + + \code + Q_APPLICATION_STATIC(MyQObjectType, staticType, "some string", function()) + \endcode + + Do note that the arguments passed in variadic fashion to this macro are + evaluated every time the object is constructed, so in the above example, + the function \c{function} will be called more than once if the object is + recreated. + + Aside from the value also being bound to the lifetime of the QCoreApplication, + this macro behaves identically to Q_GLOBAL_STATIC(). Please see that macro's + documentation for more information. + + \section1 Threading guarantees + + The Q_APPLICATION_STATIC macro ensures that the object is initialized only + once (per lifetime of a QCoreApplication), even if multiple threads try to + concurrently access the object. This is done by providing a per-object + mutex; application and library developers need to be aware that their + object will be constructed with this mutex locked and therefore must not + reenter the same object's initialization, or a deadlock will occur. + + There is no thread-safety on the destruction of the object: user code must + not access this object once the QCoreApplication destructor starts to run. + User code must arrange to ensure this does not happen, such as by not + accessing it once the main thread's event loop has exited. + + Like Q_GLOBAL_STATIC, Q_APPLICATION_STATIC provides no thread-safety + guarantees for accesses to the object once creation is finished. It is up + to user code to ensure that no racy data accesses happen. + + In case the object created by this operation is a QObject, its associated + thread will be the one that succeeded in creating it. It will be destroyed + by the main thread, so a \l{QObject::}{moveToThread()} to the main thread + or to no thread before destruction is adviseable. Doing so from the + constructor of the class in question is a sensible solution if one can't + guarantee that the main thread will be the one to initialize the object. + + \omit + \section1 Implementation details + See \l Q_GLOBAL_STATIC implementation details for an introduction. + + Q_APPLICATION_STATIC uses the same \l QGlobalStatic public class that + Q_GLOBAL_STATIC does, but instead uses a QtGlobalStatic::ApplicationHolder + template class as the template parameter. The differences to + QtGlobalStatic::Holder are: + + \list + \li The ApplicationHolder class is empty. Unlike Holder, the storage is + provided as a \c {static inline} member, simply so that the static + member reset() function can access it without having to save the + pointer in a lambda. + + \li The ApplicationHolder constructor is trivial; initialization of the + type is instead deferred to the \c pointer() function. This means the + C++11 thread-safe initialization of statics does not protect the + object. + + \li Instead, ApplicationHolder provides a mutex (implemented as a \c + {static inline} member of type \l QBasicMutex) and locks it before + constructing or destructing the object. + + \li After constructing the object, it will QObject::connect() the + QCoreApplication::destroyed() signal to a function that will in turn + destroy the object. + + \li The destructor will destroy the object if the application is + exiting without first destroying the QCoreApplication object (i.e., a + call to \c ::exit) or this Q_APPLICATION_STATIC is part of a plugin + that is being unloaded. + \endlist + + \endomit + + \sa Q_GLOBAL_STATIC, QGlobalStatic +*/ |