| Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/corelib/thread/qthreadstorage.cpp |
| Switch to Source code | Preprocessed file |
| Line | Source | Count |
|---|---|---|
| 1 | - | |
| 2 | - | |
| 3 | - | |
| 4 | - | |
| 5 | - | |
| 6 | - | |
| 7 | static QBasicMutex destructorsMutex; | - |
| 8 | typedef QVector<void (*)(void *)> DestructorMap; | - |
| 9 | namespace { namespace Q_QGS_destructors { typedef DestructorMap Type; QBasicAtomicInt guard = { QtGlobalStatic::Uninitialized }; __attribute__((visibility("hidden"))) inline Type *innerFunction() { struct HolderBase { ~HolderBase() noexcept { if (guard.load() == QtGlobalStatic::Initialized) guard.store(QtGlobalStatic::Destroyed); } }; static struct Holder : public HolderBase { Type value; Holder() noexcept(noexcept(Type ())) : value () { guard.store(QtGlobalStatic::Initialized); } } holder; return &holder.value; } } } static QGlobalStatic<DestructorMap, Q_QGS_destructors::innerFunction, Q_QGS_destructors::guard> destructors; | - |
| 10 | - | |
| 11 | QThreadStorageData::QThreadStorageData(void (*func)(void *)) | - |
| 12 | { | - |
| 13 | QMutexLocker locker(&destructorsMutex); | - |
| 14 | DestructorMap *destr = destructors(); | - |
| 15 | if (!destr) { | - |
| 16 | QThreadData *data = QThreadData::current(); | - |
| 17 | id = data->tls.count(); | - |
| 18 | if(false)QMessageLogger(__FILE__, 8692, __PRETTY_FUNCTION__).debug("QThreadStorageData: Allocated id %d, destructor %p cannot be stored", id, func); dead code: QMessageLogger(__FILE__, 92, __PRETTY_FUNCTION__).debug("QThreadStorageData: Allocated id %d, destructor %p cannot be stored", id, func); | - |
| 19 | return; | - |
| 20 | } | - |
| 21 | for (id = 0; id < destr->count(); id++) { | - |
| 22 | if (destr->at(id) == 0) | - |
| 23 | break; | - |
| 24 | } | - |
| 25 | if (id == destr->count()) { | - |
| 26 | destr->append(func); | - |
| 27 | } else { | - |
| 28 | (*destr)[id] = func; | - |
| 29 | } | - |
| 30 | if(false)QMessageLogger(__FILE__, 98104, __PRETTY_FUNCTION__).debug("QThreadStorageData: Allocated id %d, destructor %p", id, func); dead code: QMessageLogger(__FILE__, 104, __PRETTY_FUNCTION__).debug("QThreadStorageData: Allocated id %d, destructor %p", id, func); | - |
| 31 | } | - |
| 32 | - | |
| 33 | QThreadStorageData::~QThreadStorageData() | - |
| 34 | { | - |
| 35 | if(false)QMessageLogger(__FILE__, 103109, __PRETTY_FUNCTION__).debug("QThreadStorageData: Released id %d", id); dead code: QMessageLogger(__FILE__, 109, __PRETTY_FUNCTION__).debug("QThreadStorageData: Released id %d", id); | - |
| 36 | QMutexLocker locker(&destructorsMutex); | - |
| 37 | if (destructors()) | - |
| 38 | (*destructors())[id] = 0; | - |
| 39 | } | - |
| 40 | - | |
| 41 | void **QThreadStorageData::get() const | - |
| 42 | { | - |
| 43 | QThreadData *data = QThreadData::current(); | - |
| 44 | if (!data) { | - |
| 45 | QMessageLogger(__FILE__, 113119, __PRETTY_FUNCTION__).warning("QThreadStorage::get: QThreadStorage can only be used with threads started with QThread"); | - |
| 46 | return 0; | - |
| 47 | } | - |
| 48 | QVector<void *> &tls = data->tls; | - |
| 49 | if (tls.size() <= id) | - |
| 50 | tls.resize(id + 1); | - |
| 51 | void **v = &tls[id]; | - |
| 52 | - | |
| 53 | if(false)QMessageLogger(__FILE__, 121127, __PRETTY_FUNCTION__).debug("QThreadStorageData: Returning storage %d, data %p, for thread %p", dead code: QMessageLogger(__FILE__, 127, __PRETTY_FUNCTION__).debug("QThreadStorageData: Returning storage %d, data %p, for thread %p", id, *v, data->thread.load()); | - |
| 54 | id, dead code: QMessageLogger(__FILE__, 127, __PRETTY_FUNCTION__).debug("QThreadStorageData: Returning storage %d, data %p, for thread %p", id, *v, data->thread.load()); | - |
| 55 | *v, dead code: QMessageLogger(__FILE__, 127, __PRETTY_FUNCTION__).debug("QThreadStorageData: Returning storage %d, data %p, for thread %p", id, *v, data->thread.load()); | - |
| 56 | data->thread.load()); dead code: QMessageLogger(__FILE__, 127, __PRETTY_FUNCTION__).debug("QThreadStorageData: Returning storage %d, data %p, for thread %p", id, *v, data->thread.load()); | - |
| 57 | - | |
| 58 | return *v ? v : 0; | - |
| 59 | } | - |
| 60 | - | |
| 61 | void **QThreadStorageData::set(void *p) | - |
| 62 | { | - |
| 63 | QThreadData *data = QThreadData::current(); | - |
| 64 | if (!data) { | - |
| 65 | QMessageLogger(__FILE__, 133139, __PRETTY_FUNCTION__).warning("QThreadStorage::set: QThreadStorage can only be used with threads started with QThread"); | - |
| 66 | return 0; | - |
| 67 | } | - |
| 68 | QVector<void *> &tls = data->tls; | - |
| 69 | if (tls.size() <= id) | - |
| 70 | tls.resize(id + 1); | - |
| 71 | - | |
| 72 | void *&value = tls[id]; | - |
| 73 | - | |
| 74 | if (value != 0) { | - |
| 75 | if(false)QMessageLogger(__FILE__, 143149, __PRETTY_FUNCTION__).debug("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p", dead code: QMessageLogger(__FILE__, 149, __PRETTY_FUNCTION__).debug("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p", id, value, data->thread.load()); | - |
| 76 | id, dead code: QMessageLogger(__FILE__, 149, __PRETTY_FUNCTION__).debug("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p", id, value, data->thread.load()); | - |
| 77 | value, dead code: QMessageLogger(__FILE__, 149, __PRETTY_FUNCTION__).debug("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p", id, value, data->thread.load()); | - |
| 78 | data->thread.load()); dead code: QMessageLogger(__FILE__, 149, __PRETTY_FUNCTION__).debug("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p", id, value, data->thread.load()); | - |
| 79 | - | |
| 80 | QMutexLocker locker(&destructorsMutex); | - |
| 81 | DestructorMap *destr = destructors(); | - |
| 82 | void (*destructor)(void *) = destr ? destr->value(id) : 0; | - |
| 83 | locker.unlock(); | - |
| 84 | - | |
| 85 | void *q = value; | - |
| 86 | value = 0; | - |
| 87 | - | |
| 88 | if (destructor) | - |
| 89 | destructor(q); | - |
| 90 | } | - |
| 91 | - | |
| 92 | - | |
| 93 | value = p; | - |
| 94 | if(false)QMessageLogger(__FILE__, 162168, __PRETTY_FUNCTION__).debug("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread.load(), p); dead code: QMessageLogger(__FILE__, 168, __PRETTY_FUNCTION__).debug("QThreadStorageData: Set storage %d for thread %p to %p", id, data->thread.load(), p); | - |
| 95 | return &value; | - |
| 96 | } | - |
| 97 | - | |
| 98 | void QThreadStorageData::finish(void **p) | - |
| 99 | { | - |
| 100 | QVector<void *> *tls = reinterpret_cast<QVector<void *> *>(p); | - |
| 101 | if (!tls || tls->isEmpty() || !destructors()) | - |
| 102 | return; | - |
| 103 | - | |
| 104 | if(false)QMessageLogger(__FILE__, 172178, __PRETTY_FUNCTION__).debug("QThreadStorageData: Destroying storage for thread %p", QThread::currentThread()); dead code: QMessageLogger(__FILE__, 178, __PRETTY_FUNCTION__).debug("QThreadStorageData: Destroying storage for thread %p", QThread::currentThread()); | - |
| 105 | while (!tls->isEmpty()) { | - |
| 106 | void *&value = tls->last(); | - |
| 107 | void *q = value; | - |
| 108 | value = 0; | - |
| 109 | int i = tls->size() - 1; | - |
| 110 | tls->resize(i); | - |
| 111 | - | |
| 112 | if (!q) { | - |
| 113 | - | |
| 114 | continue; | - |
| 115 | } | - |
| 116 | - | |
| 117 | QMutexLocker locker(&destructorsMutex); | - |
| 118 | void (*destructor)(void *) = destructors()->value(i); | - |
| 119 | locker.unlock(); | - |
| 120 | - | |
| 121 | if (!destructor) { | - |
| 122 | if (QThread::currentThread()) | - |
| 123 | QMessageLogger(__FILE__, 191197, __PRETTY_FUNCTION__).warning("QThreadStorage: Thread %p exited after QThreadStorage %d destroyed", | - |
| 124 | QThread::currentThread(), i); | - |
| 125 | continue; | - |
| 126 | } | - |
| 127 | destructor(q); | - |
| 128 | - | |
| 129 | if (tls->size() > i) { | - |
| 130 | - | |
| 131 | (*tls)[i] = 0; | - |
| 132 | } | - |
| 133 | } | - |
| 134 | tls->clear(); | - |
| 135 | } | - |
| 136 | - | |
| Switch to Source code | Preprocessed file |