|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the QtCore module of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qthread.h" |
|
43 #include "qthreadstorage.h" |
|
44 #include "qmutex.h" |
|
45 #include "qmutexpool_p.h" |
|
46 #include "qreadwritelock.h" |
|
47 #include "qabstracteventdispatcher.h" |
|
48 |
|
49 #include <qeventloop.h> |
|
50 #include <qhash.h> |
|
51 |
|
52 #include "qthread_p.h" |
|
53 #include "private/qcoreapplication_p.h" |
|
54 |
|
55 /* |
|
56 #ifdef Q_OS_WIN32 |
|
57 # include "qt_windows.h" |
|
58 #else |
|
59 # include <unistd.h> |
|
60 # include <netinet/in.h> |
|
61 # include <sys/utsname.h> |
|
62 # include <sys/socket.h> |
|
63 */ |
|
64 /* |
|
65 # elif defined(Q_OS_HPUX) |
|
66 # include <sys/pstat.h> |
|
67 # elif defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_MAC) |
|
68 # include <sys/sysctl.h> |
|
69 # endif |
|
70 #endif |
|
71 */ |
|
72 |
|
73 QT_BEGIN_NAMESPACE |
|
74 |
|
75 /* |
|
76 QThreadData |
|
77 */ |
|
78 |
|
79 QThreadData::QThreadData(int initialRefCount) |
|
80 : _ref(initialRefCount), thread(0), |
|
81 quitNow(false), loopLevel(0), eventDispatcher(0), canWait(true) |
|
82 { |
|
83 // fprintf(stderr, "QThreadData %p created\n", this); |
|
84 } |
|
85 |
|
86 QThreadData::~QThreadData() |
|
87 { |
|
88 Q_ASSERT(_ref == 0); |
|
89 |
|
90 // In the odd case that Qt is running on a secondary thread, the main |
|
91 // thread instance will have been dereffed asunder because of the deref in |
|
92 // QThreadData::current() and the deref in the pthread_destroy. To avoid |
|
93 // crashing during QCoreApplicationData's global static cleanup we need to |
|
94 // safeguard the main thread here.. This fix is a bit crude, but it solves |
|
95 // the problem... |
|
96 if (this->thread == QCoreApplicationPrivate::theMainThread) { |
|
97 QCoreApplicationPrivate::theMainThread = 0; |
|
98 } |
|
99 |
|
100 QThread *t = thread; |
|
101 thread = 0; |
|
102 delete t; |
|
103 |
|
104 for (int i = 0; i < postEventList.size(); ++i) { |
|
105 const QPostEvent &pe = postEventList.at(i); |
|
106 if (pe.event) { |
|
107 --pe.receiver->d_func()->postedEvents; |
|
108 pe.event->posted = false; |
|
109 delete pe.event; |
|
110 } |
|
111 } |
|
112 |
|
113 // fprintf(stderr, "QThreadData %p destroyed\n", this); |
|
114 } |
|
115 |
|
116 void QThreadData::ref() |
|
117 { |
|
118 #ifndef QT_NO_THREAD |
|
119 (void) _ref.ref(); |
|
120 Q_ASSERT(_ref != 0); |
|
121 #endif |
|
122 } |
|
123 |
|
124 void QThreadData::deref() |
|
125 { |
|
126 #ifndef QT_NO_THREAD |
|
127 if (!_ref.deref()) |
|
128 delete this; |
|
129 #endif |
|
130 } |
|
131 |
|
132 /* |
|
133 QAdoptedThread |
|
134 */ |
|
135 |
|
136 QAdoptedThread::QAdoptedThread(QThreadData *data) |
|
137 : QThread(*new QThreadPrivate(data)) |
|
138 { |
|
139 // thread should be running and not finished for the lifetime |
|
140 // of the application (even if QCoreApplication goes away) |
|
141 #ifndef QT_NO_THREAD |
|
142 d_func()->running = true; |
|
143 d_func()->finished = false; |
|
144 init(); |
|
145 #endif |
|
146 |
|
147 // fprintf(stderr, "new QAdoptedThread = %p\n", this); |
|
148 } |
|
149 |
|
150 QAdoptedThread::~QAdoptedThread() |
|
151 { |
|
152 #ifndef QT_NO_THREAD |
|
153 QThreadPrivate::finish(this); |
|
154 #endif |
|
155 // fprintf(stderr, "~QAdoptedThread = %p\n", this); |
|
156 } |
|
157 |
|
158 QThread *QAdoptedThread::createThreadForAdoption() |
|
159 { |
|
160 QScopedPointer<QThread> t(new QAdoptedThread(0)); |
|
161 t->moveToThread(t.data()); |
|
162 return t.take(); |
|
163 } |
|
164 |
|
165 void QAdoptedThread::run() |
|
166 { |
|
167 // this function should never be called |
|
168 qFatal("QAdoptedThread::run(): Internal error, this implementation should never be called."); |
|
169 } |
|
170 #ifndef QT_NO_THREAD |
|
171 /* |
|
172 QThreadPrivate |
|
173 */ |
|
174 |
|
175 QThreadPrivate::QThreadPrivate(QThreadData *d) |
|
176 : QObjectPrivate(), running(false), finished(false), terminated(false), |
|
177 stackSize(0), priority(QThread::InheritPriority), data(d) |
|
178 { |
|
179 #if defined (Q_OS_UNIX) |
|
180 thread_id = 0; |
|
181 #elif defined (Q_WS_WIN) |
|
182 handle = 0; |
|
183 id = 0; |
|
184 waiters = 0; |
|
185 #endif |
|
186 #if defined (Q_WS_WIN) || defined (Q_OS_SYMBIAN) |
|
187 terminationEnabled = true; |
|
188 terminatePending = false; |
|
189 #endif |
|
190 |
|
191 if (!data) |
|
192 data = new QThreadData; |
|
193 } |
|
194 |
|
195 QThreadPrivate::~QThreadPrivate() |
|
196 { |
|
197 data->deref(); |
|
198 } |
|
199 |
|
200 /*! |
|
201 \class QThread |
|
202 \brief The QThread class provides platform-independent threads. |
|
203 |
|
204 \ingroup thread |
|
205 |
|
206 A QThread represents a separate thread of control within the |
|
207 program; it shares data with all the other threads within the |
|
208 process but executes independently in the way that a separate |
|
209 program does on a multitasking operating system. Instead of |
|
210 starting in \c main(), QThreads begin executing in run(). By |
|
211 default, run() starts the event loop by calling exec() (see |
|
212 below). To create your own threads, subclass QThread and |
|
213 reimplement run(). For example: |
|
214 |
|
215 \snippet doc/src/snippets/code/src_corelib_thread_qthread.cpp 0 |
|
216 |
|
217 This will create a QTcpSocket in the thread and then execute the |
|
218 thread's event loop. Use the start() method to begin execution. |
|
219 Execution ends when you return from run(), just as an application |
|
220 does when it leaves main(). QThread will notifiy you via a signal |
|
221 when the thread is started(), finished(), and terminated(), or |
|
222 you can use isFinished() and isRunning() to query the state of |
|
223 the thread. Use wait() to block until the thread has finished |
|
224 execution. |
|
225 |
|
226 Each thread gets its own stack from the operating system. The |
|
227 operating system also determines the default size of the stack. |
|
228 You can use setStackSize() to set a custom stack size. |
|
229 |
|
230 Each QThread can have its own event loop. You can start the event |
|
231 loop by calling exec(); you can stop it by calling exit() or |
|
232 quit(). Having an event loop in a thread makes it possible to |
|
233 connect signals from other threads to slots in this thread, using |
|
234 a mechanism called \l{Qt::QueuedConnection}{queued |
|
235 connections}. It also makes it possible to use classes that |
|
236 require the event loop, such as QTimer and QTcpSocket, in the |
|
237 thread. Note, however, that it is not possible to use any widget |
|
238 classes in the thread. |
|
239 |
|
240 In extreme cases, you may want to forcibly terminate() an |
|
241 executing thread. However, doing so is dangerous and discouraged. |
|
242 Please read the documentation for terminate() and |
|
243 setTerminationEnabled() for detailed information. |
|
244 |
|
245 The static functions currentThreadId() and currentThread() return |
|
246 identifiers for the currently executing thread. The former |
|
247 returns a platform specific ID for the thread; the latter returns |
|
248 a QThread pointer. |
|
249 |
|
250 QThread also provides platform independent sleep functions in |
|
251 varying resolutions. Use sleep() for full second resolution, |
|
252 msleep() for millisecond resolution, and usleep() for microsecond |
|
253 resolution. |
|
254 |
|
255 \sa {Thread Support in Qt}, QThreadStorage, QMutex, QSemaphore, QWaitCondition, |
|
256 {Mandelbrot Example}, {Semaphores Example}, {Wait Conditions Example} |
|
257 */ |
|
258 |
|
259 /*! |
|
260 \fn Qt::HANDLE QThread::currentThreadId() |
|
261 |
|
262 Returns the thread handle of the currently executing thread. |
|
263 |
|
264 \warning The handle returned by this function is used for internal |
|
265 purposes and should not be used in any application code. |
|
266 |
|
267 \warning On Windows, the returned value is a pseudo-handle for the |
|
268 current thread. It can't be used for numerical comparison. i.e., |
|
269 this function returns the DWORD (Windows-Thread ID) returned by |
|
270 the Win32 function getCurrentThreadId(), not the HANDLE |
|
271 (Windows-Thread HANDLE) returned by the Win32 function |
|
272 getCurrentThread(). |
|
273 */ |
|
274 |
|
275 /*! |
|
276 \fn int QThread::idealThreadCount() |
|
277 |
|
278 Returns the ideal number of threads that can be run on the system. This is done querying |
|
279 the number of processor cores, both real and logical, in the system. This function returns -1 |
|
280 if the number of processor cores could not be detected. |
|
281 */ |
|
282 |
|
283 /*! |
|
284 \fn void QThread::yieldCurrentThread() |
|
285 |
|
286 Yields execution of the current thread to another runnable thread, |
|
287 if any. Note that the operating system decides to which thread to |
|
288 switch. |
|
289 */ |
|
290 |
|
291 /*! |
|
292 \fn void QThread::start(Priority priority) |
|
293 |
|
294 Begins execution of the thread by calling run(), which should be |
|
295 reimplemented in a QThread subclass to contain your code. The |
|
296 operating system will schedule the thread according to the \a |
|
297 priority parameter. If the thread is already running, this |
|
298 function does nothing. |
|
299 |
|
300 The effect of the \a priority parameter is dependent on the |
|
301 operating system's scheduling policy. In particular, the \a priority |
|
302 will be ignored on systems that do not support thread priorities |
|
303 (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler |
|
304 for more details). |
|
305 |
|
306 \sa run(), terminate() |
|
307 */ |
|
308 |
|
309 /*! |
|
310 \fn void QThread::started() |
|
311 |
|
312 This signal is emitted when the thread starts executing. |
|
313 |
|
314 \sa finished(), terminated() |
|
315 */ |
|
316 |
|
317 /*! |
|
318 \fn void QThread::finished() |
|
319 |
|
320 This signal is emitted when the thread has finished executing. |
|
321 |
|
322 \sa started(), terminated() |
|
323 */ |
|
324 |
|
325 /*! |
|
326 \fn void QThread::terminated() |
|
327 |
|
328 This signal is emitted when the thread is terminated. |
|
329 |
|
330 \sa started(), finished() |
|
331 */ |
|
332 |
|
333 /*! |
|
334 \enum QThread::Priority |
|
335 |
|
336 This enum type indicates how the operating system should schedule |
|
337 newly created threads. |
|
338 |
|
339 \value IdlePriority scheduled only when no other threads are |
|
340 running. |
|
341 |
|
342 \value LowestPriority scheduled less often than LowPriority. |
|
343 \value LowPriority scheduled less often than NormalPriority. |
|
344 |
|
345 \value NormalPriority the default priority of the operating |
|
346 system. |
|
347 |
|
348 \value HighPriority scheduled more often than NormalPriority. |
|
349 \value HighestPriority scheduled more often than HighPriority. |
|
350 |
|
351 \value TimeCriticalPriority scheduled as often as possible. |
|
352 |
|
353 \value InheritPriority use the same priority as the creating |
|
354 thread. This is the default. |
|
355 */ |
|
356 |
|
357 /*! |
|
358 Returns a pointer to a QThread which represents the currently |
|
359 executing thread. |
|
360 */ |
|
361 QThread *QThread::currentThread() |
|
362 { |
|
363 QThreadData *data = QThreadData::current(); |
|
364 Q_ASSERT(data != 0); |
|
365 return data->thread; |
|
366 } |
|
367 |
|
368 /*! |
|
369 Constructs a new thread with the given \a parent. The thread does |
|
370 not begin executing until start() is called. |
|
371 |
|
372 \sa start() |
|
373 */ |
|
374 QThread::QThread(QObject *parent) |
|
375 : QObject(*(new QThreadPrivate), parent) |
|
376 { |
|
377 Q_D(QThread); |
|
378 // fprintf(stderr, "QThreadData %p created for thread %p\n", d->data, this); |
|
379 d->data->thread = this; |
|
380 } |
|
381 |
|
382 /*! \internal |
|
383 */ |
|
384 QThread::QThread(QThreadPrivate &dd, QObject *parent) |
|
385 : QObject(dd, parent) |
|
386 { |
|
387 Q_D(QThread); |
|
388 // fprintf(stderr, "QThreadData %p taken from private data for thread %p\n", d->data, this); |
|
389 d->data->thread = this; |
|
390 } |
|
391 |
|
392 /*! |
|
393 Destroys the thread. |
|
394 |
|
395 Note that deleting a QThread object will not stop the execution |
|
396 of the thread it represents. Deleting a running QThread (i.e. |
|
397 isFinished() returns false) will probably result in a program |
|
398 crash. You can wait() on a thread to make sure that it has |
|
399 finished. |
|
400 */ |
|
401 QThread::~QThread() |
|
402 { |
|
403 Q_D(QThread); |
|
404 { |
|
405 QMutexLocker locker(&d->mutex); |
|
406 if (d->running && !d->finished) |
|
407 qWarning("QThread: Destroyed while thread is still running"); |
|
408 |
|
409 d->data->thread = 0; |
|
410 } |
|
411 } |
|
412 |
|
413 /*! |
|
414 Returns true if the thread is finished; otherwise returns false. |
|
415 |
|
416 \sa isRunning() |
|
417 */ |
|
418 bool QThread::isFinished() const |
|
419 { |
|
420 Q_D(const QThread); |
|
421 QMutexLocker locker(&d->mutex); |
|
422 return d->finished; |
|
423 } |
|
424 |
|
425 /*! |
|
426 Returns true if the thread is running; otherwise returns false. |
|
427 |
|
428 \sa isFinished() |
|
429 */ |
|
430 bool QThread::isRunning() const |
|
431 { |
|
432 Q_D(const QThread); |
|
433 QMutexLocker locker(&d->mutex); |
|
434 return d->running; |
|
435 } |
|
436 |
|
437 /*! |
|
438 Sets the maximum stack size for the thread to \a stackSize. If \a |
|
439 stackSize is greater than zero, the maximum stack size is set to |
|
440 \a stackSize bytes, otherwise the maximum stack size is |
|
441 automatically determined by the operating system. |
|
442 |
|
443 \warning Most operating systems place minimum and maximum limits |
|
444 on thread stack sizes. The thread will fail to start if the stack |
|
445 size is outside these limits. |
|
446 |
|
447 \sa stackSize() |
|
448 */ |
|
449 void QThread::setStackSize(uint stackSize) |
|
450 { |
|
451 Q_D(QThread); |
|
452 QMutexLocker locker(&d->mutex); |
|
453 Q_ASSERT_X(!d->running, "QThread::setStackSize", |
|
454 "cannot change stack size while the thread is running"); |
|
455 d->stackSize = stackSize; |
|
456 } |
|
457 |
|
458 /*! |
|
459 Returns the maximum stack size for the thread (if set with |
|
460 setStackSize()); otherwise returns zero. |
|
461 |
|
462 \sa setStackSize() |
|
463 */ |
|
464 uint QThread::stackSize() const |
|
465 { |
|
466 Q_D(const QThread); |
|
467 QMutexLocker locker(&d->mutex); |
|
468 return d->stackSize; |
|
469 } |
|
470 |
|
471 /*! |
|
472 Enters the event loop and waits until exit() is called, returning the value |
|
473 that was passed to exit(). The value returned is 0 if exit() is called via |
|
474 quit(). |
|
475 |
|
476 It is necessary to call this function to start event handling. |
|
477 |
|
478 \sa quit(), exit() |
|
479 */ |
|
480 int QThread::exec() |
|
481 { |
|
482 Q_D(QThread); |
|
483 QMutexLocker locker(&d->mutex); |
|
484 d->data->quitNow = false; |
|
485 QEventLoop eventLoop; |
|
486 locker.unlock(); |
|
487 int returnCode = eventLoop.exec(); |
|
488 return returnCode; |
|
489 } |
|
490 |
|
491 /*! |
|
492 Tells the thread's event loop to exit with a return code. |
|
493 |
|
494 After calling this function, the thread leaves the event loop and |
|
495 returns from the call to QEventLoop::exec(). The |
|
496 QEventLoop::exec() function returns \a returnCode. |
|
497 |
|
498 By convention, a \a returnCode of 0 means success, any non-zero value |
|
499 indicates an error. |
|
500 |
|
501 Note that unlike the C library function of the same name, this |
|
502 function \e does return to the caller -- it is event processing |
|
503 that stops. |
|
504 |
|
505 This function does nothing if the thread does not have an event |
|
506 loop. |
|
507 |
|
508 \sa quit() QEventLoop |
|
509 */ |
|
510 void QThread::exit(int returnCode) |
|
511 { |
|
512 Q_D(QThread); |
|
513 QMutexLocker locker(&d->mutex); |
|
514 d->data->quitNow = true; |
|
515 for (int i = 0; i < d->data->eventLoops.size(); ++i) { |
|
516 QEventLoop *eventLoop = d->data->eventLoops.at(i); |
|
517 eventLoop->exit(returnCode); |
|
518 } |
|
519 } |
|
520 |
|
521 /*! |
|
522 Tells the thread's event loop to exit with return code 0 (success). |
|
523 Equivalent to calling QThread::exit(0). |
|
524 |
|
525 This function does nothing if the thread does not have an event |
|
526 loop. |
|
527 |
|
528 \sa exit() QEventLoop |
|
529 */ |
|
530 void QThread::quit() |
|
531 { exit(); } |
|
532 |
|
533 /*! |
|
534 The starting point for the thread. After calling start(), the |
|
535 newly created thread calls this function. The default |
|
536 implementation simply calls exec(). |
|
537 |
|
538 You can reimplemented this function to do other useful |
|
539 work. Returning from this method will end the execution of the |
|
540 thread. |
|
541 |
|
542 \sa start() wait() |
|
543 */ |
|
544 void QThread::run() |
|
545 { |
|
546 (void) exec(); |
|
547 } |
|
548 |
|
549 /*! \internal |
|
550 Initializes the QThread system. |
|
551 */ |
|
552 #if defined (Q_OS_WIN) |
|
553 void qt_create_tls(); |
|
554 #endif |
|
555 |
|
556 void QThread::initialize() |
|
557 { |
|
558 if (qt_global_mutexpool) |
|
559 return; |
|
560 qt_global_mutexpool = QMutexPool::instance(); |
|
561 |
|
562 #if defined (Q_OS_WIN) |
|
563 qt_create_tls(); |
|
564 #endif |
|
565 } |
|
566 |
|
567 |
|
568 /*! \internal |
|
569 Cleans up the QThread system. |
|
570 */ |
|
571 void QThread::cleanup() |
|
572 { |
|
573 qt_global_mutexpool = 0; |
|
574 } |
|
575 |
|
576 /*! |
|
577 \fn bool QThread::finished() const |
|
578 |
|
579 Use isFinished() instead. |
|
580 */ |
|
581 |
|
582 /*! |
|
583 \fn bool QThread::running() const |
|
584 |
|
585 Use isRunning() instead. |
|
586 */ |
|
587 |
|
588 /*! \fn void QThread::setPriority(Priority priority) |
|
589 \since 4.1 |
|
590 |
|
591 This function sets the \a priority for a running thread. If the |
|
592 thread is not running, this function does nothing and returns |
|
593 immediately. Use start() to start a thread with a specific |
|
594 priority. |
|
595 |
|
596 The \a priority argument can be any value in the \c |
|
597 QThread::Priority enum except for \c InheritPriorty. |
|
598 |
|
599 The effect of the \a priority parameter is dependent on the |
|
600 operating system's scheduling policy. In particular, the \a priority |
|
601 will be ignored on systems that do not support thread priorities |
|
602 (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler |
|
603 for more details). |
|
604 |
|
605 \sa Priority priority() start() |
|
606 */ |
|
607 |
|
608 /*! |
|
609 \since 4.1 |
|
610 |
|
611 Returns the priority for a running thread. If the thread is not |
|
612 running, this function returns \c InheritPriority. |
|
613 |
|
614 \sa Priority setPriority() start() |
|
615 */ |
|
616 QThread::Priority QThread::priority() const |
|
617 { |
|
618 Q_D(const QThread); |
|
619 QMutexLocker locker(&d->mutex); |
|
620 return d->priority; |
|
621 } |
|
622 |
|
623 /*! |
|
624 \fn void QThread::sleep(unsigned long secs) |
|
625 |
|
626 Forces the current thread to sleep for \a secs seconds. |
|
627 |
|
628 \sa msleep(), usleep() |
|
629 */ |
|
630 |
|
631 /*! |
|
632 \fn void QThread::msleep(unsigned long msecs) |
|
633 |
|
634 Causes the current thread to sleep for \a msecs milliseconds. |
|
635 |
|
636 \sa sleep(), usleep() |
|
637 */ |
|
638 |
|
639 /*! |
|
640 \fn void QThread::usleep(unsigned long usecs) |
|
641 |
|
642 Causes the current thread to sleep for \a usecs microseconds. |
|
643 |
|
644 \sa sleep(), msleep() |
|
645 */ |
|
646 |
|
647 /*! |
|
648 \fn void QThread::terminate() |
|
649 |
|
650 Terminates the execution of the thread. The thread may or may not |
|
651 be terminated immediately, depending on the operating systems |
|
652 scheduling policies. Use QThread::wait() after terminate() for |
|
653 synchronous termination. |
|
654 |
|
655 When the thread is terminated, all threads waiting for the thread |
|
656 to finish will be woken up. |
|
657 |
|
658 \warning This function is dangerous and its use is discouraged. |
|
659 The thread can be terminate at any point in its code path. |
|
660 Threads can be terminated while modifying data. There is no |
|
661 chance for the thread to cleanup after itself, unlock any held |
|
662 mutexes, etc. In short, use this function only if absolutely |
|
663 necessary. |
|
664 |
|
665 Termination can be explicitly enabled or disabled by calling |
|
666 QThread::setTerminationEnabled(). Calling this function while |
|
667 termination is disabled results in the termination being |
|
668 deferred, until termination is re-enabled. See the documentation |
|
669 of QThread::setTerminationEnabled() for more information. |
|
670 |
|
671 \sa setTerminationEnabled() |
|
672 */ |
|
673 |
|
674 /*! |
|
675 \fn bool QThread::wait(unsigned long time) |
|
676 |
|
677 Blocks the thread until either of these conditions is met: |
|
678 |
|
679 \list |
|
680 \o The thread associated with this QThread object has finished |
|
681 execution (i.e. when it returns from \l{run()}). This function |
|
682 will return true if the thread has finished. It also returns |
|
683 true if the thread has not been started yet. |
|
684 \o \a time milliseconds has elapsed. If \a time is ULONG_MAX (the |
|
685 default), then the wait will never timeout (the thread must |
|
686 return from \l{run()}). This function will return false if the |
|
687 wait timed out. |
|
688 \endlist |
|
689 |
|
690 This provides similar functionality to the POSIX \c |
|
691 pthread_join() function. |
|
692 |
|
693 \sa sleep(), terminate() |
|
694 */ |
|
695 |
|
696 /*! |
|
697 \fn void QThread::setTerminationEnabled(bool enabled) |
|
698 |
|
699 Enables or disables termination of the current thread based on the |
|
700 \a enabled parameter. The thread must have been started by |
|
701 QThread. |
|
702 |
|
703 When \a enabled is false, termination is disabled. Future calls |
|
704 to QThread::terminate() will return immediately without effect. |
|
705 Instead, the termination is deferred until termination is enabled. |
|
706 |
|
707 When \a enabled is true, termination is enabled. Future calls to |
|
708 QThread::terminate() will terminate the thread normally. If |
|
709 termination has been deferred (i.e. QThread::terminate() was |
|
710 called with termination disabled), this function will terminate |
|
711 the calling thread \e immediately. Note that this function will |
|
712 not return in this case. |
|
713 |
|
714 \sa terminate() |
|
715 */ |
|
716 |
|
717 #else // QT_NO_THREAD |
|
718 |
|
719 QThread::QThread(QObject *parent) |
|
720 : QObject(*(new QThreadPrivate), (QObject*)0){ |
|
721 Q_D(QThread); |
|
722 d->data->thread = this; |
|
723 } |
|
724 |
|
725 QThread *QThread::currentThread() |
|
726 { |
|
727 return QThreadData::current()->thread; |
|
728 } |
|
729 |
|
730 QThreadData* QThreadData::current() |
|
731 { |
|
732 static QThreadData *data = 0; // reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key)); |
|
733 if (!data) { |
|
734 QScopedPointer<QThreadData> newdata(new QThreadData); |
|
735 newdata->thread = new QAdoptedThread(newdata.data()); |
|
736 data = newdata.take(); |
|
737 data->deref(); |
|
738 } |
|
739 return data; |
|
740 } |
|
741 |
|
742 /*! \internal |
|
743 */ |
|
744 QThread::QThread(QThreadPrivate &dd, QObject *parent) |
|
745 : QObject(dd, parent) |
|
746 { |
|
747 Q_D(QThread); |
|
748 // fprintf(stderr, "QThreadData %p taken from private data for thread %p\n", d->data, this); |
|
749 d->data->thread = this; |
|
750 } |
|
751 |
|
752 #endif // QT_NO_THREAD |
|
753 |
|
754 QT_END_NAMESPACE |