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 |