source: trunk/src/corelib/thread/qthread.cpp@ 497

Last change on this file since 497 was 69, checked in by Dmitry A. Kuminov, 16 years ago

corelib: OS/2: Ported QThread (#13).

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