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.qdoc157
1 files changed, 84 insertions, 73 deletions
diff --git a/src/corelib/kernel/qapplicationstatic.qdoc b/src/corelib/kernel/qapplicationstatic.qdoc
index 4d203a78ae..5cbac65df9 100644
--- a/src/corelib/kernel/qapplicationstatic.qdoc
+++ b/src/corelib/kernel/qapplicationstatic.qdoc
@@ -1,98 +1,109 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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)
+ \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 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.
+ 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.
- However, as long as the actual holder is still in the initialized state, the
- type will be recreated when it's accessed again once a new QCoreApplication
- has been created.
+ 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().
+ 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)
+ 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.
- \sa Q_APPLICATION_STATIC_WITH_ARGS(), QGlobalStatic
-*/
-
-/*!
- \macro Q_APPLICATION_STATIC_WITH_ARGS(Type, VariableName, Arguments)
- \since 6.3
- \relates QGlobalStatic
-
- Creates a global and static object of type \l QGlobalStatic, of name \a
- VariableName, initialized by the arguments \a 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_WITH_ARGS
- 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.
-
- Since the value is bound to the QCoreApplication it should only ever be accessed,
- if there is a valid QCoreApplication::instance().
-
- The typical use of this macro is as follows, in a global context (that is,
- outside of any function bodies):
-
- \code
- Q_APPLICATION_STATIC_WITH_ARGS(MyQObjectType, staticType, (42, "Hello", "World"))
- \endcode
-
- The \a Arguments macro parameter must always include the parentheses or, if
- C++11 uniform initialization is allowed, the braces.
-
- Aside from the actual initialization of the contents with the supplied
- arguments, this macro behaves identically to Q_APPLICATION_STATIC(). Please
- see that macro's documentation for more information.
-
- \sa Q_APPLICATION_STATIC(), QGlobalStatic
+ \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
*/