1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qexception.h"
41#include "QtCore/qshareddata.h"
42
43#if !defined(QT_NO_EXCEPTIONS) || defined(Q_CLANG_QDOC)
44
45QT_BEGIN_NAMESPACE
46
47/*!
48 \class QException
49 \inmodule QtCore
50 \brief The QException class provides a base class for exceptions that can be transferred across threads.
51 \since 5.0
52
53 Qt Concurrent supports throwing and catching exceptions across thread
54 boundaries, provided that the exception inherits from QException
55 and implements two helper functions:
56
57 \snippet code/src_corelib_thread_qexception.cpp 0
58
59 QException subclasses must be thrown by value and
60 caught by reference:
61
62 \snippet code/src_corelib_thread_qexception.cpp 1
63
64 If you throw an exception that is not a subclass of QException,
65 the Qt functions will throw a QUnhandledException
66 in the receiver thread.
67
68 When using QFuture, transferred exceptions will be thrown when calling the following functions:
69 \list
70 \li QFuture::waitForFinished()
71 \li QFuture::result()
72 \li QFuture::resultAt()
73 \li QFuture::results()
74 \endlist
75*/
76
77/*!
78 \fn QException::raise() const
79 In your QException subclass, reimplement raise() like this:
80
81 \snippet code/src_corelib_thread_qexception.cpp 2
82*/
83
84/*!
85 \fn QException::clone() const
86 In your QException subclass, reimplement clone() like this:
87
88 \snippet code/src_corelib_thread_qexception.cpp 3
89*/
90
91/*!
92 \class QUnhandledException
93 \inmodule QtCore
94
95 \brief The UnhandledException class represents an unhandled exception in a worker thread.
96 \since 5.0
97
98 If a worker thread throws an exception that is not a subclass of QException,
99 the Qt functions will throw a QUnhandledException
100 on the receiver thread side.
101
102 Inheriting from this class is not supported.
103*/
104
105/*!
106 \fn QUnhandledException::raise() const
107 \internal
108*/
109
110/*!
111 \fn QUnhandledException::clone() const
112 \internal
113*/
114
115QException::~QException() noexcept
116{
117}
118
119void QException::raise() const
120{
121 QException e = *this;
122 throw e;
123}
124
125QException *QException::clone() const
126{
127 return new QException(*this);
128}
129
130QUnhandledException::~QUnhandledException() noexcept
131{
132}
133
134void QUnhandledException::raise() const
135{
136 QUnhandledException e = *this;
137 throw e;
138}
139
140QUnhandledException *QUnhandledException::clone() const
141{
142 return new QUnhandledException(*this);
143}
144
145#if !defined(Q_CLANG_QDOC)
146
147namespace QtPrivate {
148
149void ExceptionStore::setException(const QException &e)
150{
151 Q_ASSERT(!hasException());
152 try {
153 e.raise();
154 } catch (...) {
155 exceptionHolder = std::current_exception();
156 }
157}
158
159void ExceptionStore::setException(std::exception_ptr e)
160{
161 Q_ASSERT(!hasException());
162 exceptionHolder = e;
163}
164
165bool ExceptionStore::hasException() const
166{
167 return !!exceptionHolder;
168}
169
170std::exception_ptr ExceptionStore::exception() const
171{
172 return exceptionHolder;
173}
174
175void ExceptionStore::throwPossibleException()
176{
177 if (hasException())
178 std::rethrow_exception(exceptionHolder);
179}
180
181} // namespace QtPrivate
182
183#endif //Q_CLANG_QDOC
184
185QT_END_NAMESPACE
186
187#endif // QT_NO_EXCEPTIONS
188