File indexing completed on 2025-07-30 08:46:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef __TBB_task_handle_H
0019 #define __TBB_task_handle_H
0020
0021 #include "_config.h"
0022 #include "_task.h"
0023 #include "_small_object_pool.h"
0024 #include "_utils.h"
0025 #include <memory>
0026
0027 namespace tbb {
0028 namespace detail {
0029
0030 namespace d1 { class task_group_context; class wait_context; struct execution_data; }
0031 namespace d2 {
0032
0033 class task_handle;
0034
0035 class task_handle_task : public d1::task {
0036 std::uint64_t m_version_and_traits{};
0037 d1::wait_context& m_wait_ctx;
0038 d1::task_group_context& m_ctx;
0039 d1::small_object_allocator m_allocator;
0040 public:
0041 void finalize(const d1::execution_data* ed = nullptr) {
0042 if (ed) {
0043 m_allocator.delete_object(this, *ed);
0044 } else {
0045 m_allocator.delete_object(this);
0046 }
0047 }
0048
0049 task_handle_task(d1::wait_context& wo, d1::task_group_context& ctx, d1::small_object_allocator& alloc)
0050 : m_wait_ctx(wo)
0051 , m_ctx(ctx)
0052 , m_allocator(alloc) {
0053 suppress_unused_warning(m_version_and_traits);
0054 }
0055
0056 ~task_handle_task() override {
0057 m_wait_ctx.release();
0058 }
0059
0060 d1::task_group_context& ctx() const { return m_ctx; }
0061 };
0062
0063
0064 class task_handle {
0065 struct task_handle_task_finalizer_t{
0066 void operator()(task_handle_task* p){ p->finalize(); }
0067 };
0068 using handle_impl_t = std::unique_ptr<task_handle_task, task_handle_task_finalizer_t>;
0069
0070 handle_impl_t m_handle = {nullptr};
0071 public:
0072 task_handle() = default;
0073 task_handle(task_handle&&) = default;
0074 task_handle& operator=(task_handle&&) = default;
0075
0076 explicit operator bool() const noexcept { return static_cast<bool>(m_handle); }
0077
0078 friend bool operator==(task_handle const& th, std::nullptr_t) noexcept;
0079 friend bool operator==(std::nullptr_t, task_handle const& th) noexcept;
0080
0081 friend bool operator!=(task_handle const& th, std::nullptr_t) noexcept;
0082 friend bool operator!=(std::nullptr_t, task_handle const& th) noexcept;
0083
0084 private:
0085 friend struct task_handle_accessor;
0086
0087 task_handle(task_handle_task* t) : m_handle {t}{};
0088
0089 d1::task* release() {
0090 return m_handle.release();
0091 }
0092 };
0093
0094 struct task_handle_accessor {
0095 static task_handle construct(task_handle_task* t) { return {t}; }
0096 static d1::task* release(task_handle& th) { return th.release(); }
0097 static d1::task_group_context& ctx_of(task_handle& th) {
0098 __TBB_ASSERT(th.m_handle, "ctx_of does not expect empty task_handle.");
0099 return th.m_handle->ctx();
0100 }
0101 };
0102
0103 inline bool operator==(task_handle const& th, std::nullptr_t) noexcept {
0104 return th.m_handle == nullptr;
0105 }
0106 inline bool operator==(std::nullptr_t, task_handle const& th) noexcept {
0107 return th.m_handle == nullptr;
0108 }
0109
0110 inline bool operator!=(task_handle const& th, std::nullptr_t) noexcept {
0111 return th.m_handle != nullptr;
0112 }
0113
0114 inline bool operator!=(std::nullptr_t, task_handle const& th) noexcept {
0115 return th.m_handle != nullptr;
0116 }
0117
0118 }
0119 }
0120 }
0121
0122 #endif