1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QTCONCURRENT_RUNBASE_H |
5 | #define QTCONCURRENT_RUNBASE_H |
6 | |
7 | #include <QtConcurrent/qtconcurrent_global.h> |
8 | |
9 | #ifndef QT_NO_CONCURRENT |
10 | |
11 | #include <QtCore/qfuture.h> |
12 | #include <QtCore/qrunnable.h> |
13 | #include <QtCore/qthreadpool.h> |
14 | |
15 | #include <type_traits> |
16 | #include <utility> |
17 | |
18 | QT_BEGIN_NAMESPACE |
19 | |
20 | |
21 | #ifndef Q_QDOC |
22 | |
23 | namespace QtConcurrent { |
24 | |
25 | template <typename T> |
26 | struct SelectSpecialization |
27 | { |
28 | template <class Normal, class Void> |
29 | struct Type { typedef Normal type; }; |
30 | }; |
31 | |
32 | template <> |
33 | struct SelectSpecialization<void> |
34 | { |
35 | template <class Normal, class Void> |
36 | struct Type { typedef Void type; }; |
37 | }; |
38 | |
39 | struct TaskStartParameters |
40 | { |
41 | QThreadPool *threadPool = QThreadPool::globalInstance(); |
42 | int priority = 0; |
43 | }; |
44 | |
45 | template <typename T> |
46 | class RunFunctionTaskBase : public QRunnable |
47 | { |
48 | public: |
49 | QFuture<T> start() |
50 | { |
51 | return start(TaskStartParameters()); |
52 | } |
53 | |
54 | QFuture<T> start(const TaskStartParameters ¶meters) |
55 | { |
56 | promise.setThreadPool(parameters.threadPool); |
57 | promise.setRunnable(this); |
58 | promise.reportStarted(); |
59 | QFuture<T> theFuture = promise.future(); |
60 | |
61 | if (parameters.threadPool) { |
62 | parameters.threadPool->start(this, parameters.priority); |
63 | } else { |
64 | promise.reportCanceled(); |
65 | promise.reportFinished(); |
66 | delete this; |
67 | } |
68 | return theFuture; |
69 | } |
70 | |
71 | // For backward compatibility |
72 | QFuture<T> start(QThreadPool *pool) { return start({pool, 0}); } |
73 | |
74 | void run() override |
75 | { |
76 | if (promise.isCanceled()) { |
77 | promise.reportFinished(); |
78 | return; |
79 | } |
80 | #ifndef QT_NO_EXCEPTIONS |
81 | try { |
82 | #endif |
83 | runFunctor(); |
84 | #ifndef QT_NO_EXCEPTIONS |
85 | } catch (QException &e) { |
86 | promise.reportException(e); |
87 | } catch (...) { |
88 | promise.reportException(QUnhandledException(std::current_exception())); |
89 | } |
90 | #endif |
91 | promise.reportFinished(); |
92 | } |
93 | |
94 | protected: |
95 | virtual void runFunctor() = 0; |
96 | |
97 | QFutureInterface<T> promise; |
98 | }; |
99 | |
100 | } //namespace QtConcurrent |
101 | |
102 | #endif //Q_QDOC |
103 | |
104 | QT_END_NAMESPACE |
105 | |
106 | #endif // QT_NO_CONCURRENT |
107 | |
108 | #endif |
109 | |