summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qapplicationstatic.qdoc
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qapplicationstatic.qdoc')
-rw-r--r--src/corelib/kernel/qapplicationstatic.qdoc109
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
+*/