1 /* 2 SPDX-FileCopyrightText: 2009 Nokia Corporation and /or its subsidiary(-ies). 3 Contact: Qt Software Information (qt-info@nokia.com) 4 5 This file is part of the QtCore module of the Qt Toolkit. 6 7 $QT_BEGIN_LICENSE:LGPL$ 8 Commercial Usage 9 Licensees holding valid Qt Commercial licenses may use this file in 10 accordance with the Qt Commercial License Agreement provided with the 11 Software or, alternatively, in accordance with the terms contained in 12 a written agreement between you and Nokia. 13 14 GNU Lesser General Public License Usage 15 Alternatively, this file may be used under the terms of the GNU Lesser 16 General Public License version 2.1 as published by the Free Software 17 Foundation and appearing in the file LICENSE.LGPL included in the 18 packaging of this file. Please review the following information to 19 ensure the GNU Lesser General Public License version 2.1 requirements 20 will be met: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 21 22 In addition, as a special exception, Nokia gives you certain 23 additional rights. These rights are described in the Nokia Qt LGPL 24 Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 25 package. 26 27 GNU General Public License Usage 28 Alternatively, this file may be used under the terms of the GNU 29 General Public License version 3.0 as published by the Free Software 30 Foundation and appearing in the file LICENSE.GPL included in the 31 packaging of this file. Please review the following information to 32 ensure the GNU General Public License version 3.0 requirements will be 33 met: https://www.gnu.org/licenses/gpl-3.0.html. 34 35 If you are unsure which license is appropriate for your use, please 36 contact the sales department at qt-sales@nokia.com. 37 $QT_END_LICENSE$ 38 39 */ 40 41 #ifndef QTHREAD_P_H 42 #define QTHREAD_P_H 43 44 // 45 // W A R N I N G 46 // ------------- 47 // 48 // This file is not part of the Qt API. It exists purely as an 49 // implementation detail. This header file may change from version to 50 // version without notice, or even be removed. 51 // 52 // We mean it. 53 // 54 // 55 56 #include "qplatformdefs.h" 57 #include "QtCore/qthread.h" 58 #include "QtCore/QtCore/QMutex" 59 #include "QtCore/qstack.h" 60 #include "QtCore/QtCore/QWaitCondition" 61 #include "QtCore/QtCore/QMap" 62 #include "private/qobject_p.h" 63 64 QT_BEGIN_NAMESPACE 65 66 class QAbstractEventDispatcher; 67 class QEventLoop; 68 69 class QPostEvent 70 { 71 public: 72 QObject *receiver; 73 QEvent *event; 74 int priority; QPostEvent()75 inline QPostEvent() 76 : receiver(0), event(0), priority(0) 77 { } QPostEvent(QObject * r,QEvent * e,int p)78 inline QPostEvent(QObject *r, QEvent *e, int p) 79 : receiver(r), event(e), priority(p) 80 { } 81 }; 82 inline bool operator<(int priority, const QPostEvent &pe) 83 { 84 return pe.priority < priority; 85 } 86 inline bool operator<(const QPostEvent &pe, int priority) 87 { 88 return priority < pe.priority; 89 } 90 91 class QPostEventList : public QList<QPostEvent> 92 { 93 public: 94 // recursion == recursion count for sendPostedEvents() 95 int recursion; 96 97 // sendOffset == the current event to start sending 98 int startOffset; 99 // insertionOffset == set by sendPostedEvents to tell postEvent() where to start insertions 100 int insertionOffset; 101 102 QMutex mutex; 103 QPostEventList()104 inline QPostEventList() 105 : QList<QPostEvent>(), recursion(0), startOffset(0), insertionOffset(0) 106 { } 107 }; 108 109 class Q_CORE_EXPORT QThreadData 110 { 111 QAtomicInt _ref; 112 113 public: 114 QThreadData(int initialRefCount = 1); 115 ~QThreadData(); 116 117 static QThreadData *current(); 118 static QThreadData *get2(QThread *thread); 119 120 void ref(); 121 void deref(); 122 123 QThread *thread; 124 bool quitNow; 125 int loopLevel; 126 QAbstractEventDispatcher *eventDispatcher; 127 QStack<QEventLoop *> eventLoops; 128 QPostEventList postEventList; 129 bool canWait; 130 QMap<int, void *> tls; 131 132 QMutex mutex; 133 }; 134 135 #ifndef QT_NO_THREAD 136 class QThreadPrivate : public QObjectPrivate 137 { 138 Q_DECLARE_PUBLIC(QThread) 139 140 public: 141 QThreadPrivate(QThreadData *d = 0); 142 ~QThreadPrivate(); 143 144 mutable QMutex mutex; 145 146 bool running; 147 bool finished; 148 bool terminated; 149 150 uint stackSize; 151 QThread::Priority priority; 152 153 static QThread *threadForId(int id); 154 155 #ifdef Q_OS_UNIX 156 pthread_t thread_id; 157 QWaitCondition thread_done; 158 159 static void *start(void *arg); 160 static void finish(void *arg); 161 #endif 162 163 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) 164 HANDLE handle; 165 unsigned int id; 166 int waiters; 167 bool terminationEnabled, terminatePending; 168 169 static unsigned int __stdcall start(void *); 170 static void finish(void *, bool lockAnyway=true); 171 #endif // Q_OS_WIN32 172 173 QThreadData *data; 174 175 static void createEventDispatcher(QThreadData *data); 176 }; 177 178 // thread wrapper for the main() thread 179 class QAdoptedThread : public QThread 180 { 181 Q_DECLARE_PRIVATE(QThread) 182 183 public: 184 QAdoptedThread(QThreadData *data = 0); 185 ~QAdoptedThread(); 186 void init(); 187 188 static QThread *createThreadForAdoption(); 189 private: 190 void run(); 191 }; 192 193 #else // QT_NO_THREAD 194 195 class QThreadPrivate : public QObjectPrivate 196 { 197 public: QThreadPrivate()198 QThreadPrivate() : data(QThreadData::current()) {} ~QThreadPrivate()199 ~QThreadPrivate() { } 200 201 QThreadData *data; 202 setCurrentThread(QThread *)203 static void setCurrentThread(QThread*) {} threadForId(int)204 static QThread *threadForId(int) { return QThread::currentThread(); } 205 static void createEventDispatcher(QThreadData *data); 206 207 Q_DECLARE_PUBLIC(QThread) 208 }; 209 210 #endif // QT_NO_THREAD 211 212 QT_END_NAMESPACE 213 214 #endif // QTHREAD_P_H 215