diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-11 15:39:15 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-06-17 06:48:10 +0000 |
commit | 8b080e59c5019112f5699db5c2c101f76b3da88f (patch) | |
tree | a26ca81c6f6e3396c663e316b9bfa751ff3e298a /src/corelib/global/qglobalstatic.cpp | |
parent | 9d90bbd7b14db17a64e6a664e6f98b58efa97747 (diff) |
rename qglobalstatic.cpp -> qglobalstatic.qdoc
it contains no code.
Change-Id: Ie8a43abb2db3d040f7046206adf2bf555960dd9c
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/global/qglobalstatic.cpp')
-rw-r--r-- | src/corelib/global/qglobalstatic.cpp | 522 |
1 files changed, 0 insertions, 522 deletions
diff --git a/src/corelib/global/qglobalstatic.cpp b/src/corelib/global/qglobalstatic.cpp deleted file mode 100644 index d1c522a79a..0000000000 --- a/src/corelib/global/qglobalstatic.cpp +++ /dev/null @@ -1,522 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglobalstatic.h" - -/*! - \macro Q_GLOBAL_STATIC(Type, VariableName) - \since 5.1 - \relates QGlobalStatic - - Creates a global and static object of type \l QGlobalStatic, of name \a - VariableName and that behaves as a pointer to \a Type. The object created - by Q_GLOBAL_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. - - The typical use of this macro is as follows, in a global context (that is, - outside of any function bodies): - - \code - Q_GLOBAL_STATIC(MyType, staticType) - \endcode - - This macro is intended to replace global static objects that are not POD - (Plain Old Data, or in C++11 terms, not made of a trivial type), hence the - name. For example, the following C++ code creates a global static: - - \code - static MyType staticType; - \endcode - - Compared to Q_GLOBAL_STATIC, and assuming that \c MyType is a class or - struct that has a constructor, a destructor, or is otherwise non-POD, the - above has the following drawbacks: - - \list - \li it requires load-time initialization of \c MyType (that is, the - default constructor for \c MyType is called when the library or - application is loaded); - - \li the type will be initialized even if it is never used; - - \li the order of initialization and destruction among different - translation units is not determined, leading to possible uses before - initialization or after destruction; - - \li if it is found inside a function (that is, not global), it will be - initialized on first use, but many current compilers (as of 2013) do - not guarantee that the initialization will be thread-safe; - \endlist - - The Q_GLOBAL_STATIC macro solves all of the above problems by guaranteeing - thread-safe initialization on first use and allowing the user to query for - whether the type has already been destroyed, to avoid the - use-after-destruction problem (see QGlobalStatic::isDestroyed()). - - \section1 Constructor and Destructor - - For Q_GLOBAL_STATIC, the type \c Type must be publicly - default-constructible and publicly destructible. For - Q_GLOBAL_STATIC_WITH_ARGS(), there must be a public constructor that - matches the arguments passed. - - It is not possible to use Q_GLOBAL_STATIC with types that have protected or - private default constructors or destructors (for Q_GLOBAL_STATIC_WITH_ARGS(), - a protected or private constructor matching the arguments). If the type in - question has those members as protected, it is possible to overcome the - issue by deriving from the type and creating public a constructor and - destructor. If the type has them as private, a friend declaration is - necessary before deriving. - - For example, the following is enough to create \c MyType based on a - previously-defined \c MyOtherType which has a protected default constructor - and/or a protected destructor (or has them as private, but that defines \c - MyType as a friend). - - \code - class MyType : public MyOtherType { }; - Q_GLOBAL_STATIC(MyType, staticType) - \endcode - - No body for \c MyType is required since the destructor is an implicit - member and so is the default constructor if no other constructors are - defined. For use with Q_GLOBAL_STATIC_WITH_ARGS(), however, a suitable - constructor body is necessary: - - \code - class MyType : public MyOtherType - { - public: - MyType(int i) : MyOtherType(i) {} - }; - Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42)) - \endcode - - Alternatively, if the compiler supports C++11 inheriting constructors, one could write: - - \code - class MyType : public MyOtherType - { - public: - using MyOtherType::MyOtherType; - }; - Q_GLOBAL_STATIC_WITH_ARGS(MyType, staticType, (42)) - \endcode - - \section1 Placement - - The Q_GLOBAL_STATIC macro creates a type that is necessarily static, at the - global scope. It is not possible to place the Q_GLOBAL_STATIC macro inside - a function (doing so will result in compilation errors). - - More importantly, this macro should be placed in source files, never in - headers. Since the resulting object is has static linkage, if the macro is - placed in a header and included by multiple source files, the object will - be defined multiple times and will not cause linking errors. Instead, each - translation unit will refer to a different object, which could lead to - subtle and hard-to-track errors. - - \section1 Non-recommended uses - - Note that the macro is not recommended for use with types that are POD or - that have C++11 constexpr constructors (trivially constructible and - destructible). For those types, it is still recommended to use regular - static, whether global or function-local. - - This macro will work, but it will add unnecessary overhead. - - \section1 Reentrancy, Thread-safety, Deadlocks, and Exception-safety on Construction - - The Q_GLOBAL_STATIC macro creates an object that initializes itself on - first use in a thread-safe manner: if multiple threads attempt to - initialize the object at the same time, only one thread will proceed to - initialize, while all other threads wait for completion. - - If the initialization process throws an exception, the initialization is - deemed not complete and will be attempted again when control reaches any - use of the object. If there are any threads waiting for initialization, one - of them will be woken up to attempt to initialize. - - The macro makes no guarantee about reentrancy from the same thread. If the - global static object is accessed directly or indirectly from inside the - constructor, a deadlock will surely happen. - - In addition, if two Q_GLOBAL_STATIC objects are being initialized on two - different threads and each one's initialization sequence accesses the - other, a deadlock might happen. For that reason, it is recommended to keep - global static constructors simple or, failing that, to ensure that there's - no cross-dependency of uses of global static during construction. - - \section1 Destruction - - If the object is never used during the lifetime of the program, aside from - the QGlobalStatic::exists() and QGlobalStatic::isDestroyed() functions, the - contents of type \a Type will not be created and there will not be any - exit-time operation. - - If the object is created, it will be destroyed at exit-time, similar to the - C \c atexit function. On most systems, in fact, the destructor will also be - called if the library or plugin is unloaded from memory before exit. - - Since the destruction is meant to happen at program exit, no thread-safety - is provided. This includes the case of plugin or library unload. In - addition, since destructors are not supposed to throw exceptions, no - exception safety is provided either. - - However, reentrancy is permitted: during destruction, it is possible to - access the global static object and the pointer returned will be the same - as it was before destruction began. After the destruction has completed, - accessing the global static object is not permitted, except as noted in the - \l QGlobalStatic API. - - \omit - \section1 Compatibility with Qt 4 and Qt 5.0 - - This macro, in its current form and behavior, was introduced in Qt 5.1. - Prior to that version, Qt had another macro with the same name that was - private API. This section is not meant to document how to use - Q_GLOBAL_STATIC in those versions, but instead to serve as a porting guide - for Qt code that used those macros. - - The Qt 4 Q_GLOBAL_STATIC macro differed in behavior in the following ways: - - \list - \li the object created was not of type \l QGlobalStatic, but instead - it was a function that returned a pointer to \a Type; that means the - \l QGlobalStatic API was not present; - - \li the initialization was thread-safe, but not guaranteed to be - unique: instead, if N threads tried to initialize the object at the - same time, N objects would be created on the heap and N-1 would be - destroyed; - - \li the object was always created on the heap. - \endlist - - \section1 Implementation Details - - Q_GLOBAL_STATIC is implemented by creating a QBasicAtomicInt called the \c - guard and a free, inline function called \c innerFunction. The guard - variable is initialized to value 0 (chosen so that the guard can be placed - in the .bss section of the binary file), which denotes that construction - has not yet taken place (uninitialized). The inner function is implemented - by the helper macro Q_GLOBAL_STATIC_INTERNAL. - - Both the guard variable and the inner function are passed as template - parameters to QGlobalStatic, along with the type \a Type. Both should also - have static linkage or be placed inside an anonymous namespace, so that the - visibility of Q_GLOBAL_STATIC is that of a global static. To permit - multiple Q_GLOBAL_STATIC per translation unit, the guard variable and the - inner function must have unique names, which can be accomplished by - concatenating with \a VariableName or by placing them in a namespace that - has \a VariableName as part of the name. To simplify and improve - readability on Q_GLOBAL_STATIC_INTERNAL, we chose the namespace solution. - It's also required for C++98 builds, since static symbols cannot be used as - template parameters. - - The guard variable can assume the following values: - - \list - \li -2: object was once initialized but has been destroyed already; - \li -1: object was initialized and is still valid; - \li 0: object was not initialized yet; - \li +1: object is being initialized and any threads encountering this - value must wait for completion (not used in the current implementation). - \endlist - - Collectively, all positive values indicate that the initialization is - progressing and must be waited on, whereas all negative values indicate - that the initialization has terminated and must not be attempted again. - Positive values are not used in the current implementation, but were in - earlier versions. They could be used again in the future. - - The QGlobalStatic::exists() and QGlobalStatic::isDestroyed() functions - operate solely on the guard variable: the former returns \c true if the guard - is negative, whereas the latter returns \c true only if it is -2. - - The Q_GLOBAL_STATIC_INTERNAL macro implements the actual construction and - destruction. There are two implementations of it: one for compilers that - support thread-safe initialization of function-local statics and one for - compilers that don't. Thread-safe initialization is required by C++11 in - [stmt.decl], but as of the time of this writing, only compilers based on - the IA-64 C++ ABI implemented it properly. The implementation requiring - thread-safe initialization is also used on the Qt bootstrapped tools, which - define QT_NO_THREAD. - - The implementation requiring thread-safe initialization from the compiler - is the simplest: it creates the \a Type object as a function-local static - and returns its address. The actual object is actually inside a holder - structure so holder's destructor can set the guard variable to the value -2 - (destroyed) when the type has finished destruction. Since we need to set - the guard \b after the destruction has finished, this code needs to be in a - base struct's destructor. And it only sets to -2 (destroyed) if it finds - the guard at -1 (initialized): this is done to ensure that the guard isn't - set to -2 in the event the type's constructor threw an exception. A holder - structure is used to avoid creating two statics, which the ABI might - require duplicating the thread-safe control structures for. - - The other implementation is similar to Qt 4's Q_GLOBAL_STATIC, but unlike - that one, it uses a \l QBasicMutex to provide locking. It is also more - efficient memory-wise. It use a simple double-checked locking of the mutex - and then creates the contents on the heap. After that, it creates a - function-local structure called "Cleanup", whose destructor will be run at - program exit and will actually destroy the contents. - - \endomit - - \sa Q_GLOBAL_STATIC_WITH_ARGS(), QGlobalStatic -*/ - -/*! - \macro Q_GLOBAL_STATIC_WITH_ARGS(Type, VariableName, Arguments) - \since 5.1 - \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. The object created by Q_GLOBAL_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. - - The typical use of this macro is as follows, in a global context (that is, - outside of any function bodies): - - \code - Q_GLOBAL_STATIC_WITH_ARGS(MyType, 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_GLOBAL_STATIC(). Please - see that macro's documentation for more information. - - \sa Q_GLOBAL_STATIC(), QGlobalStatic -*/ - -/*! - \class QGlobalStatic - \threadsafe - \inmodule QtCore - \since 5.1 - \brief The QGlobalStatic class is used to implement a global static object - - The QGlobalStatic class is the front-end API exported when - Q_GLOBAL_STATIC() is used. See the documentation for the macro for a - discussion on when to use it and its requirements. - - Normally, you will never use this class directly, but instead you will use - the Q_GLOBAL_STATIC() or Q_GLOBAL_STATIC_WITH_ARGS() macros, as - follows: - - \code - Q_GLOBAL_STATIC(MyType, staticType) - \endcode - - The above example creates an object of type QGlobalStatic called \c - staticType. After the above declaration, the \c staticType object may be - used as if it were a pointer, guaranteed to be initialized exactly once. In - addition to the use as a pointer, the object offers two methods to - determine the current status of the global: exists() and isDestroyed(). - - \sa Q_GLOBAL_STATIC(), Q_GLOBAL_STATIC_WITH_ARGS() -*/ - -/*! - \typedef QGlobalStatic::Type - - This type is equivalent to the \c Type parameter passed to the - Q_GLOBAL_STATIC() or Q_GLOBAL_STATIC_WITH_ARGS() macros. It is used in the - return types of some functions. -*/ - -/*! - \fn bool QGlobalStatic::isDestroyed() const - - This function returns \c true if the global static object has already - completed destruction (that is, if the destructor for the type has already - returned). In specific, note that this function returns \c false if - the destruction is still in progress. - - Once this function has returned true once, it will never return - false again until either the program is restarted or the plugin or library - containing the global static is unloaded and reloaded. - - This function is safe to call at any point in the program execution: it - cannot fail and cannot cause a deadlock. Additionally, it will not cause - the contents to be created if they have not yet been created. - - This function is useful in code that may be executed at program shutdown, - to determine whether the contents may still be accessed or not. - - \omit - Due to the non-atomic nature of destruction, it's possible that - QGlobalStatic::isDestroyed might return false for a short time after the - destructor has finished. However, since the destructor is only run in an - environment where concurrent multithreaded access is impossible, no one can - see that state. (omitted because it's useless information) - \endomit - - \sa exists() -*/ - -/*! - \fn bool QGlobalStatic::exists() const - - This function returns \c true if the global static object has already - completed initialization (that is, if the constructor for the type has - already returned). In specific, note that this function returns \c false if - the initialization is still in progress. - - Once this function has returned true once, it will never return false again - until either the program is restarted or the plugin or library containing - the global static is unloaded and reloaded. - - This function is safe to call at any point in the program execution: it - cannot fail and cannot cause a deadlock. Additionally, it will not cause - the contents to be created if they have not yet been created. - - This function is useful if one can determine the initial conditions of the - global static object and would prefer to avoid a possibly expensive - construction operation. - - For example, in the following code sample, this function is used to - short-circuit the creation of the global static called \c globalState and - returns a default value: - - \code - Q_GLOBAL_STATIC(MyType, globalState) - QString someState() - { - if (globalState.exists()) - return globalState->someState; - return QString(); - } - \endcode - - \b{Thread-safety notice:} this function is thread-safe in the sense that it - may be called from any thread at any time and will always return a valid - reply. But due to the non-atomic nature of construction, this function may - return false for a short time after the construction has completed. - - \b{Memory ordering notice:} this function does not impose any memory - ordering guarantees. That is instead provided by the accessor functions - that return the pointer or reference to the contents. If you bypass the - accessor functions and attempt to access some global state set by the - constructor, be sure to use the correct memory ordering semantics provided - by \l QAtomicInt or \l QAtomicPointer. - - \sa isDestroyed() -*/ - -/*! - \fn QGlobalStatic::operator Type*() - - This function returns the address of the contents of this global static. If - the contents have not yet been created, they will be created thread-safely - by this function. If the contents have already been destroyed, this - function will return a null pointer. - - This function can be used, for example, to store the pointer to the - contents of the global static in a local variable, thus avoiding multiple - calls to the function. The implementation of Q_GLOBAL_STATIC() is quite - efficient already, but in performance-critical sections it might be useful - to help the compiler a little. For example: - - \code - Q_GLOBAL_STATIC(MyType, globalState) - QString someState() - { - MyType *state = globalState; - if (!state) { - // we're in a post-destruction state - return QString(); - } - if (state->condition) - return state->value1; - else - return state->value2; - } - \endcode - - \sa operator->(), operator*() -*/ - -/*! - \fn Type *QGlobalStatic::operator()() - \deprecated - - This function returns the address of the contents of this global static. If - the contents have not yet been created, they will be created thread-safely - by this function. If the contents have already been destroyed, this - function will return a null pointer. - - This function is equivalent to \l {operator Type *()}. It is provided for - compatibility with the private Q_GLOBAL_STATIC implementation that existed - in Qt 4.x and 5.0. New code should avoid using it and should instead treat - the object as a smart pointer. -*/ - -/*! - \fn Type *QGlobalStatic::operator->() - - This function returns the address of the contents of this global static. If - the contents have not yet been created, they will be created thread-safely - by this function. - - This function does not check if the contents have already been destroyed and - will never return null. If this function is called after the object has - been destroyed, it will return a dangling pointer that should not be - dereferenced. -*/ - -/*! - \fn Type &QGlobalStatic::operator*() - - This function returns a reference to the contents of this global static. If - the contents have not yet been created, they will be created thread-safely - by this function. - - This function does not check if the contents have already been destroyed. - If this function is called after the object has been destroyed, it will - return an invalid reference that must not be used. -*/ |