source: trunk/src/corelib/concurrent/qtconcurrentexception.cpp@ 769

Last change on this file since 769 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 6.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** 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 have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qtconcurrentexception.h"
43
44#ifndef QT_NO_QFUTURE
45#ifndef QT_NO_EXCEPTIONS
46
47QT_BEGIN_NAMESPACE
48
49/*!
50 \class QtConcurrent::Exception
51 \brief The Exception class provides a base class for exceptions that can transferred across threads.
52 \since 4.4
53
54 Qt Concurrent supports throwing and catching exceptions across thread
55 boundaries, provided that the exception inherit from QtConcurrent::Exception
56 and implement two helper functions:
57
58 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp 0
59
60 QtConcurrent::Exception subclasses must be thrown by value and
61 caught by reference:
62
63 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp 1
64
65 If you throw an exception that is not a subclass of QtConcurrent::Exception,
66 the Qt Concurrent functions will throw a QtConcurrent::UnhandledException
67 in the receiver thread.
68
69 When using QFuture, transferred exceptions willl be thrown when calling the following functions:
70 \list
71 \o QFuture::waitForFinished()
72 \o QFuture::result()
73 \o QFuture::resultAt()
74 \o QFuture::results()
75 \endlist
76*/
77
78/*!
79 \fn QtConcurrent::Exception::raise() const
80 In your QtConcurrent::Exception subclass, reimplement raise() like this:
81
82 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp 2
83*/
84
85/*!
86 \fn QtConcurrent::Exception::clone() const
87 In your QtConcurrent::Exception subclass, reimplement clone() like this:
88
89 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp 3
90*/
91
92/*!
93 \class QtConcurrent::UnhandledException
94
95 \brief The UnhandledException class represents an unhandled exception in a worker thread.
96 \since 4.4
97
98 If a worker thread throws an exception that is not a subclass of QtConcurrent::Exception,
99 the Qt Concurrent functions will throw a QtConcurrent::UnhandledException
100 on the receiver thread side.
101
102 Inheriting from this class is not supported.
103*/
104
105/*!
106 \fn QtConcurrent::UnhandledException::raise() const
107 \internal
108*/
109
110/*!
111 \fn QtConcurrent::UnhandledException::clone() const
112 \internal
113*/
114
115namespace QtConcurrent
116{
117
118void Exception::raise() const
119{
120 Exception e = *this;
121 throw e;
122}
123
124Exception *Exception::clone() const
125{
126 return new Exception(*this);
127}
128
129void UnhandledException::raise() const
130{
131 UnhandledException e = *this;
132 throw e;
133}
134
135Exception *UnhandledException::clone() const
136{
137 return new UnhandledException(*this);
138}
139
140#ifndef qdoc
141
142namespace internal {
143
144class Base
145{
146public:
147 Base(Exception *exception)
148 : exception(exception), refCount(1), hasThrown(false) { }
149 ~Base() { delete exception; }
150
151 Exception *exception;
152 QAtomicInt refCount;
153 bool hasThrown;
154};
155
156ExceptionHolder::ExceptionHolder(Exception *exception)
157: base(new Base(exception)) {}
158
159ExceptionHolder::ExceptionHolder(const ExceptionHolder &other)
160: base(other.base)
161{
162 base->refCount.ref();
163}
164
165void ExceptionHolder::operator=(const ExceptionHolder &other)
166{
167 if (base == other.base)
168 return;
169
170 if (base->refCount.deref() == false)
171 delete base;
172
173 base = other.base;
174 base->refCount.ref();
175}
176
177ExceptionHolder::~ExceptionHolder()
178{
179 if (base->refCount.deref() == 0)
180 delete base;
181}
182
183Exception *ExceptionHolder::exception() const
184{
185 return base->exception;
186}
187
188void ExceptionStore::setException(const Exception &e)
189{
190 if (hasException() == false)
191 exceptionHolder = ExceptionHolder(e.clone());
192}
193
194bool ExceptionStore::hasException() const
195{
196 return (exceptionHolder.exception() != 0);
197}
198
199ExceptionHolder ExceptionStore::exception()
200{
201 return exceptionHolder;
202}
203
204void ExceptionStore::throwPossibleException()
205{
206 /* On win32-g++, with GCC 3.4.2 std::uncaught_exception() isn't reliable. */
207 if (hasException()
208#ifndef Q_CC_MINGW
209 && std::uncaught_exception() == false
210#endif
211 ) {
212 exceptionHolder.base->hasThrown = true;
213 exceptionHolder.exception()->raise();
214 }
215}
216
217bool ExceptionStore::hasThrown() const { return exceptionHolder.base->hasThrown; }
218
219} // namespace internal
220
221#endif //qdoc
222
223} // namespace QtConcurrent
224
225QT_END_NAMESPACE
226
227#endif // QT_NO_EXCEPTIONS
228#endif // QT_NO_CONCURRENT
Note: See TracBrowser for help on using the repository browser.