Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into master-integration
[qt-netbsd.git] / src / corelib / concurrent / qtconcurrentexception.cpp
blobe7f4674ce6e8c63c9371cc23378b764646da91d8
1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 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.
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.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
42 #include "qtconcurrentexception.h"
44 #ifndef QT_NO_QFUTURE
45 #ifndef QT_NO_EXCEPTIONS
47 QT_BEGIN_NAMESPACE
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
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
61 caught by reference:
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:
70 \list
71 \o QFuture::waitForFinished()
72 \o QFuture::result()
73 \o QFuture::resultAt()
74 \o QFuture::results()
75 \endlist
78 /*!
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
85 /*!
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
92 /*!
93 \class QtConcurrent::UnhandledException
95 \brief The UnhandledException class represents an unhandled exception in a worker thread.
96 \since 4.4
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
107 \internal
111 \fn QtConcurrent::UnhandledException::clone() const
112 \internal
115 namespace QtConcurrent
118 void Exception::raise() const
120 Exception e = *this;
121 throw e;
124 Exception *Exception::clone() const
126 return new Exception(*this);
129 void UnhandledException::raise() const
131 UnhandledException e = *this;
132 throw e;
135 Exception *UnhandledException::clone() const
137 return new UnhandledException(*this);
140 #ifndef qdoc
142 namespace internal {
144 class Base
146 public:
147 Base(Exception *exception)
148 : exception(exception), refCount(1), hasThrown(false) { }
149 ~Base() { delete exception; }
151 Exception *exception;
152 QAtomicInt refCount;
153 bool hasThrown;
156 ExceptionHolder::ExceptionHolder(Exception *exception)
157 : base(new Base(exception)) {}
159 ExceptionHolder::ExceptionHolder(const ExceptionHolder &other)
160 : base(other.base)
162 base->refCount.ref();
165 void ExceptionHolder::operator=(const ExceptionHolder &other)
167 if (base == other.base)
168 return;
170 if (base->refCount.deref() == false)
171 delete base;
173 base = other.base;
174 base->refCount.ref();
177 ExceptionHolder::~ExceptionHolder()
179 if (base->refCount.deref() == 0)
180 delete base;
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. */
207 if (hasException()
208 #ifndef Q_CC_MINGW
209 && std::uncaught_exception() == false
210 #endif
212 exceptionHolder.base->hasThrown = true;
213 exceptionHolder.exception()->raise();
217 bool ExceptionStore::hasThrown() const { return exceptionHolder.base->hasThrown; }
219 } // namespace internal
221 #endif //qdoc
223 } // namespace QtConcurrent
225 QT_END_NAMESPACE
227 #endif // QT_NO_EXCEPTIONS
228 #endif // QT_NO_CONCURRENT