source: trunk/src/corelib/concurrent/qtconcurrentthreadengine.cpp@ 5

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

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 5.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 "qtconcurrentthreadengine.h"
43
44#ifndef QT_NO_CONCURRENT
45
46QT_BEGIN_NAMESPACE
47
48namespace QtConcurrent {
49
50ThreadEngineBase::ThreadEngineBase()
51:futureInterface(0), threadPool(QThreadPool::globalInstance())
52{
53 setAutoDelete(false);
54}
55
56ThreadEngineBase::~ThreadEngineBase() {}
57
58void ThreadEngineBase::startSingleThreaded()
59{
60 start();
61 while (threadFunction() != ThreadFinished)
62 ;
63 finish();
64}
65
66void ThreadEngineBase::startBlocking()
67{
68 start();
69 semaphore.acquire();
70 startThreads();
71
72 bool throttled = false;
73#ifndef QT_NO_EXCEPTIONS
74 try {
75#endif
76 while (threadFunction() == ThrottleThread) {
77 if (threadThrottleExit()) {
78 throttled = true;
79 break;
80 }
81 }
82#ifndef QT_NO_EXCEPTIONS
83 } catch (QtConcurrent::Exception &e) {
84 handleException(e);
85 } catch (...) {
86 handleException(QtConcurrent::UnhandledException());
87 }
88#endif
89
90 if (throttled == false) {
91 semaphore.release();
92 }
93
94 semaphore.wait();
95 finish();
96 exceptionStore.throwPossibleException();
97}
98
99void ThreadEngineBase::startThread()
100{
101 startThreadInternal();
102}
103
104bool ThreadEngineBase::isCanceled()
105{
106 if (futureInterface)
107 return futureInterface->isCanceled();
108 else
109 return false;
110}
111
112void ThreadEngineBase::waitForResume()
113{
114 if (futureInterface)
115 futureInterface->waitForResume();
116}
117
118bool ThreadEngineBase::isProgressReportingEnabled()
119{
120 // If we don't have a QFuture, there is no-one to report the progress to.
121 return (futureInterface != 0);
122}
123
124void ThreadEngineBase::setProgressValue(int progress)
125{
126 if (futureInterface)
127 futureInterface->setProgressValue(progress);
128}
129
130void ThreadEngineBase::setProgressRange(int minimum, int maximum)
131{
132 if (futureInterface)
133 futureInterface->setProgressRange(minimum, maximum);
134}
135
136bool ThreadEngineBase::startThreadInternal()
137{
138 if (this->isCanceled())
139 return false;
140
141 semaphore.acquire();
142 if (!threadPool->tryStart(this)) {
143 semaphore.release();
144 return false;
145 }
146 return true;
147}
148
149void ThreadEngineBase::startThreads()
150{
151 while (shouldStartThread() && startThreadInternal())
152 ;
153}
154
155void ThreadEngineBase::threadExit()
156{
157 const bool asynchronous = futureInterface != 0;
158 const int lastThread = (semaphore.release() == 0);
159
160 if (lastThread && asynchronous)
161 this->asynchronousFinish();
162}
163
164// Called by a worker thread that wants to be throttled. If the current number
165// of running threads is larger than one the thread is allowed to exit and
166// this function returns one.
167bool ThreadEngineBase::threadThrottleExit()
168{
169 return semaphore.releaseUnlessLast();
170}
171
172void ThreadEngineBase::run() // implements QRunnable.
173{
174 if (this->isCanceled()) {
175 threadExit();
176 return;
177 }
178
179 startThreads();
180
181#ifndef QT_NO_EXCEPTIONS
182 try {
183#endif
184 while (threadFunction() == ThrottleThread) {
185 // threadFunction returning ThrottleThread means it that the user
186 // struct wants to be throttled by making a worker thread exit.
187 // Respect that request unless this is the only worker thread left
188 // running, in which case it has to keep going.
189 if (threadThrottleExit())
190 return;
191 }
192
193#ifndef QT_NO_EXCEPTIONS
194 } catch (QtConcurrent::Exception &e) {
195 handleException(e);
196 } catch (...) {
197 handleException(QtConcurrent::UnhandledException());
198 }
199#endif
200 threadExit();
201}
202
203#ifndef QT_NO_EXCEPTIONS
204
205void ThreadEngineBase::handleException(const QtConcurrent::Exception &exception)
206{
207 if (futureInterface)
208 futureInterface->reportException(exception);
209 else
210 exceptionStore.setException(exception);
211}
212#endif
213
214
215} // namepsace QtConcurrent
216
217QT_END_NAMESPACE
218
219#endif // QT_NO_CONCURRENT
Note: See TracBrowser for help on using the repository browser.