Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/QtCore/qthreadstorage.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Copyright (C) 2016 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 // Qt-Security score:significant reason:default
0004 
0005 #ifndef QTHREADSTORAGE_H
0006 #define QTHREADSTORAGE_H
0007 
0008 #include <QtCore/qglobal.h>
0009 
0010 #if !QT_CONFIG(thread)
0011 #include <memory>
0012 #endif
0013 
0014 QT_BEGIN_NAMESPACE
0015 
0016 #if QT_CONFIG(thread)
0017 
0018 template <bool ShouldWarn> struct QThreadStorageTraits
0019 {
0020     static constexpr void warnAboutTrivial() {}
0021 };
0022 template <> struct QThreadStorageTraits<true>
0023 {
0024 #ifndef Q_NO_THREAD_STORAGE_TRIVIAL_WARNING
0025     Q_DECL_DEPRECATED_X("QThreadStorage used with a trivial non-pointer type; consider using thread_local")
0026 #endif
0027     static constexpr void warnAboutTrivial() noexcept {}
0028 };
0029 
0030 class Q_CORE_EXPORT QThreadStorageData
0031 {
0032 public:
0033     explicit QThreadStorageData(void (*func)(void *));
0034     ~QThreadStorageData();
0035 
0036     void** get() const;
0037     void** set(void* p);
0038 
0039     int id;
0040 };
0041 
0042 // pointer specialization
0043 template <typename T>
0044 inline
0045 T *&qThreadStorage_localData(QThreadStorageData &d, T **)
0046 {
0047     void **v = d.get();
0048     if (!v) v = d.set(nullptr);
0049     return *(reinterpret_cast<T**>(v));
0050 }
0051 
0052 template <typename T>
0053 inline
0054 T *qThreadStorage_localData_const(const QThreadStorageData &d, T **)
0055 {
0056     void **v = d.get();
0057     return v ? *(reinterpret_cast<T**>(v)) : 0;
0058 }
0059 
0060 template <typename T>
0061 inline
0062 void qThreadStorage_setLocalData(QThreadStorageData &d, T **t)
0063 { (void) d.set(*t); }
0064 
0065 template <typename T>
0066 inline
0067 void qThreadStorage_deleteData(void *d, T **)
0068 { delete static_cast<T *>(d); }
0069 
0070 // value-based specialization
0071 template <typename T>
0072 inline
0073 T &qThreadStorage_localData(QThreadStorageData &d, T *)
0074 {
0075     void **v = d.get();
0076     if (!v) v = d.set(new T());
0077     return *(reinterpret_cast<T*>(*v));
0078 }
0079 
0080 template <typename T>
0081 inline
0082 T qThreadStorage_localData_const(const QThreadStorageData &d, T *)
0083 {
0084     void **v = d.get();
0085     return v ? *(reinterpret_cast<T*>(*v)) : T();
0086 }
0087 
0088 template <typename T>
0089 inline
0090 void qThreadStorage_setLocalData(QThreadStorageData &d, T *t)
0091 { (void) d.set(new T(*t)); }
0092 
0093 template <typename T>
0094 inline
0095 void qThreadStorage_deleteData(void *d, T *)
0096 { delete static_cast<T *>(d); }
0097 
0098 template <class T>
0099 class QThreadStorage
0100 {
0101 private:
0102     using Trait = QThreadStorageTraits<std::is_trivially_default_constructible_v<T> &&
0103                                        std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>>;
0104     QThreadStorageData d;
0105 
0106     Q_DISABLE_COPY(QThreadStorage)
0107 
0108     static inline void deleteData(void *x)
0109     { qThreadStorage_deleteData(x, reinterpret_cast<T*>(0)); }
0110 
0111 public:
0112     inline QThreadStorage() : d(deleteData) { Trait::warnAboutTrivial(); }
0113     inline ~QThreadStorage() { }
0114 
0115     inline bool hasLocalData() const
0116     { return d.get() != nullptr; }
0117 
0118     inline T& localData()
0119     { return qThreadStorage_localData(d, reinterpret_cast<T*>(0)); }
0120     inline T localData() const
0121     { return qThreadStorage_localData_const(d, reinterpret_cast<T*>(0)); }
0122 
0123     inline void setLocalData(T t)
0124     { qThreadStorage_setLocalData(d, &t); }
0125 };
0126 
0127 #else // !QT_CONFIG(thread)
0128 
0129 template <typename T, typename U>
0130 inline bool qThreadStorage_hasLocalData(const std::unique_ptr<T, U> &data)
0131 {
0132     return !!data;
0133 }
0134 
0135 template <typename T, typename U>
0136 inline bool qThreadStorage_hasLocalData(const std::unique_ptr<T*, U> &data)
0137 {
0138     return !!data ? *data != nullptr : false;
0139 }
0140 
0141 template <typename T>
0142 inline void qThreadStorage_deleteLocalData(T *t)
0143 {
0144     delete t;
0145 }
0146 
0147 template <typename T>
0148 inline void qThreadStorage_deleteLocalData(T **t)
0149 {
0150     delete *t;
0151     delete t;
0152 }
0153 
0154 template <class T>
0155 class QThreadStorage
0156 {
0157 private:
0158     struct ScopedPointerThreadStorageDeleter
0159     {
0160         void operator()(T *t) const noexcept
0161         {
0162             if (t == nullptr)
0163                 return;
0164             qThreadStorage_deleteLocalData(t);
0165         }
0166     };
0167     std::unique_ptr<T, ScopedPointerThreadStorageDeleter> data;
0168 
0169 public:
0170     QThreadStorage() = default;
0171     ~QThreadStorage() = default;
0172     QThreadStorage(const QThreadStorage &rhs) = delete;
0173     QThreadStorage &operator=(const QThreadStorage &rhs) = delete;
0174 
0175     inline bool hasLocalData() const
0176     {
0177         return qThreadStorage_hasLocalData(data);
0178     }
0179 
0180     inline T &localData()
0181     {
0182         if (!data)
0183             data.reset(new T());
0184         return *data;
0185     }
0186 
0187     inline T localData() const
0188     {
0189         return !!data ? *data : T();
0190     }
0191 
0192     inline void setLocalData(T t)
0193     {
0194         data.reset(new T(t));
0195     }
0196 };
0197 
0198 #endif // QT_CONFIG(thread)
0199 
0200 QT_END_NAMESPACE
0201 
0202 #endif // QTHREADSTORAGE_H