summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qglobalstatic.cpp
blob: 352d775e9a736eb891f435c8e12630a0ba3156c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
/****************************************************************************
**
** Copyright (C) 2013 Intel Corporation.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $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.
*/