1 /****************************************************************************
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtCore module of the Qt Toolkit.
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
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qtconcurrentexception.h"
45 #ifndef QT_NO_EXCEPTIONS
50 \class QtConcurrent::Exception
51 \brief The Exception class provides a base class for exceptions that can transferred across threads.
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:
58 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp 0
60 QtConcurrent::Exception subclasses must be thrown by value and
63 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp 1
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.
69 When using QFuture, transferred exceptions willl be thrown when calling the following functions:
71 \o QFuture::waitForFinished()
73 \o QFuture::resultAt()
79 \fn QtConcurrent::Exception::raise() const
80 In your QtConcurrent::Exception subclass, reimplement raise() like this:
82 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp 2
86 \fn QtConcurrent::Exception::clone() const
87 In your QtConcurrent::Exception subclass, reimplement clone() like this:
89 \snippet doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp 3
93 \class QtConcurrent::UnhandledException
95 \brief The UnhandledException class represents an unhandled exception in a worker thread.
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.
102 Inheriting from this class is not supported.
106 \fn QtConcurrent::UnhandledException::raise() const
111 \fn QtConcurrent::UnhandledException::clone() const
115 namespace QtConcurrent
118 void Exception::raise() const
124 Exception
*Exception::clone() const
126 return new Exception(*this);
129 void UnhandledException::raise() const
131 UnhandledException e
= *this;
135 Exception
*UnhandledException::clone() const
137 return new UnhandledException(*this);
147 Base(Exception
*exception
)
148 : exception(exception
), refCount(1), hasThrown(false) { }
149 ~Base() { delete exception
; }
151 Exception
*exception
;
156 ExceptionHolder::ExceptionHolder(Exception
*exception
)
157 : base(new Base(exception
)) {}
159 ExceptionHolder::ExceptionHolder(const ExceptionHolder
&other
)
162 base
->refCount
.ref();
165 void ExceptionHolder::operator=(const ExceptionHolder
&other
)
167 if (base
== other
.base
)
170 if (base
->refCount
.deref() == false)
174 base
->refCount
.ref();
177 ExceptionHolder::~ExceptionHolder()
179 if (base
->refCount
.deref() == 0)
183 Exception
*ExceptionHolder::exception() const
185 return base
->exception
;
188 void ExceptionStore::setException(const Exception
&e
)
190 if (hasException() == false)
191 exceptionHolder
= ExceptionHolder(e
.clone());
194 bool ExceptionStore::hasException() const
196 return (exceptionHolder
.exception() != 0);
199 ExceptionHolder
ExceptionStore::exception()
201 return exceptionHolder
;
204 void ExceptionStore::throwPossibleException()
206 /* On win32-g++, with GCC 3.4.2 std::uncaught_exception() isn't reliable. */
209 && std::uncaught_exception() == false
212 exceptionHolder
.base
->hasThrown
= true;
213 exceptionHolder
.exception()->raise();
217 bool ExceptionStore::hasThrown() const { return exceptionHolder
.base
->hasThrown
; }
219 } // namespace internal
223 } // namespace QtConcurrent
227 #endif // QT_NO_EXCEPTIONS
228 #endif // QT_NO_CONCURRENT