Loading...
Searching...
No Matches
dispatcher.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_WORK_DISPATCHER_H
8#define PXR_BASE_WORK_DISPATCHER_H
9
11
12#include "pxr/pxr.h"
13#include "pxr/base/work/api.h"
14#include "pxr/base/work/impl.h"
16
19
20#include <functional>
21#include <type_traits>
22#include <utility>
23
24PXR_NAMESPACE_OPEN_SCOPE
25
26// The Work_Dispatcher interface, specialized with a dispatcher impl template
27// argument.
28//
29// Clients expected to use the WorkDispatcher type instead.
30template <class Impl>
31class Work_Dispatcher
32{
33protected:
34 // Prevent construction of the work dispatcher base class.
35 WORK_API Work_Dispatcher();
36
37public:
39 WORK_API ~Work_Dispatcher() noexcept;
40
41 Work_Dispatcher(Work_Dispatcher const &) = delete;
42 Work_Dispatcher &operator=(Work_Dispatcher const &) = delete;
43
44#ifdef doxygen
45
56 template <class Callable, class A1, class A2, ... class AN>
57 void Run(Callable &&c, A1 &&a1, A2 &&a2, ... AN &&aN);
58
59#else // doxygen
60
61 template <class Callable>
62 inline void Run(Callable &&c) {
63 _dispatcher.Run(
64 _InvokerTask<typename std::remove_reference<Callable>::type>(
65 std::forward<Callable>(c), &_errors));
66 }
67
68 template <class Callable, class A0, class ... Args>
69 inline void Run(Callable &&c, A0 &&a0, Args&&... args) {
70 Run(std::bind(std::forward<Callable>(c),
71 std::forward<A0>(a0),
72 std::forward<Args>(args)...));
73 }
74
75#endif // doxygen
76
78 WORK_API void Wait();
79
90 WORK_API void Cancel();
91
94 WORK_API bool IsCancelled() const;
95
96private:
97 typedef tbb::concurrent_vector<TfErrorTransport> _ErrorTransports;
98
99 // Function invoker helper that wraps the invocation with an ErrorMark so we
100 // can transmit errors that occur back to the thread that Wait() s for tasks
101 // to complete.
102 template <class Fn>
103 struct _InvokerTask {
104 explicit _InvokerTask(Fn &&fn, _ErrorTransports *err)
105 : _fn(std::move(fn)), _errors(err) {}
106
107 explicit _InvokerTask(Fn const &fn, _ErrorTransports *err)
108 : _fn(fn), _errors(err) {}
109
110 // Ensure only moves happen, no copies.
111 _InvokerTask(_InvokerTask &&other) = default;
112 _InvokerTask(const _InvokerTask &other) = delete;
113 _InvokerTask &operator=(const _InvokerTask &other) = delete;
114
115 void operator()() const {
116 TfErrorMark m;
117 _fn();
118 if (!m.IsClean())
119 Work_Dispatcher::_TransportErrors(m, _errors);
120 }
121 private:
122 Fn _fn;
123 _ErrorTransports *_errors;
124 };
125
126 // Helper function that removes errors from \p m and stores them in a new
127 // entry in \p errors.
128 WORK_API static void
129 _TransportErrors(const TfErrorMark &m, _ErrorTransports *errors);
130
131 // WorkDispatcher implementation
132 Impl _dispatcher;
133 std::atomic<bool> _isCancelled;
134
135 // The error transports we use to transmit errors in other threads back to
136 // this thread.
137 _ErrorTransports _errors;
138
139 // Concurrent calls to Wait() have to serialize certain cleanup operations.
140 std::atomic_flag _waitCleanupFlag;
141};
142
175 : public Work_Dispatcher<PXR_WORK_IMPL_NS::WorkImpl_Dispatcher>
176{};
177
178// Wrapper class for non-const tasks.
179template <class Fn>
180struct Work_DeprecatedMutableTask {
181 explicit Work_DeprecatedMutableTask(Fn &&fn)
182 : _fn(std::move(fn)) {}
183
184 explicit Work_DeprecatedMutableTask(Fn const &fn)
185 : _fn(fn) {}
186
187 // Ensure only moves happen, no copies.
188 Work_DeprecatedMutableTask
189 (Work_DeprecatedMutableTask &&other) = default;
190 Work_DeprecatedMutableTask
191 (const Work_DeprecatedMutableTask &other) = delete;
192 Work_DeprecatedMutableTask
193 &operator= (const Work_DeprecatedMutableTask &other) = delete;
194
195 void operator()() const {
196 _fn();
197 }
198private:
199 mutable Fn _fn;
200};
201
202// Wrapper function to convert non-const tasks to a Work_DeprecatedMutableTask.
203// When adding new tasks refrain from using this wrapper, instead ensure the
204// call operator of the task is const such that it is compatible with oneTBB.
205template <typename Fn>
206Work_DeprecatedMutableTask<typename std::remove_reference_t<Fn>>
207WorkMakeDeprecatedMutableTask(Fn &&fn) {
208 return Work_DeprecatedMutableTask<typename std::remove_reference_t<Fn>>
209 (std::forward<Fn>(fn));
210}
211
213
214PXR_NAMESPACE_CLOSE_SCOPE
215
216#endif // PXR_BASE_WORK_DISPATCHER_H
Class used to record the end of the error-list.
Definition: errorMark.h:48
bool IsClean() const
Return true if no new errors were posted in this thread since the last call to SetMark(),...
Definition: errorMark.h:82
A work dispatcher runs concurrent tasks.
Definition: dispatcher.h:176
STL namespace.