CMS 3D CMS Logo

WaitingTaskWithArenaHolder.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Concurrency
4 // Class : WaitingTaskWithArenaHolder
5 //
6 // Original Author: W. David Dagenhart
7 // Created: 6 December 2017
8 
12 
13 namespace edm {
14 
16  }
17 
18  // Note that the arena will be the one containing the thread
19  // that runs this constructor. This is the arena where you
20  // eventually intend for the task to be spawned.
22  m_task(iTask),
23  m_arena(std::make_shared<tbb::task_arena>(tbb::task_arena::attach())) {
24 
25  m_task->increment_ref_count();
26  }
27 
29  if (m_task) {
30  doneWaiting(std::exception_ptr{});
31  }
32  }
33 
35  m_task(iHolder.m_task),
36  m_arena(iHolder.m_arena) {
37 
38  m_task->increment_ref_count();
39  }
40 
42  m_task(iOther.m_task),
43  m_arena(std::move(iOther.m_arena)) {
44 
45  iOther.m_task = nullptr;
46  }
47 
50  std::swap(m_task, tmp.m_task);
52  return *this;
53  }
54 
57  std::swap(m_task, tmp.m_task);
59  return *this;
60  }
61 
62  // This spawns the task. The arena is needed to get the task spawned
63  // into the correct arena of threads. Use of the arena allows doneWaiting
64  // to be called from a thread outside the arena of threads that will manage
65  // the task. doneWaiting can be called from a non-TBB thread.
66  void WaitingTaskWithArenaHolder::doneWaiting(std::exception_ptr iExcept) {
67  if (iExcept) {
68  m_task->dependentTaskFailed(iExcept);
69  }
70  if (0 == m_task->decrement_ref_count()) {
71  // The enqueue call will cause a worker thread to be created in
72  // the arena if there is not one already.
73  m_arena->enqueue( [m_task = m_task](){ tbb::task::spawn(*m_task); });
74  }
75  m_task = nullptr;
76  }
77 
78  // This next function is useful if you know from the context that
79  // m_arena (which is set when the constructor was executes) is the
80  // same arena in which you want to execute the doneWaiting function.
81  // It allows an optimization which avoids the enqueue step in the
82  // doneWaiting function.
83  //
84  // Be warned though that in general this function cannot be used.
85  // Spawning a task outside the correct arena could create a new separate
86  // arena with its own extra TBB worker threads if this function is used
87  // in an inappropriate context (and silently such that you might not notice
88  // the problem quickly).
89 
91  WaitingTaskHolder holder(m_task);
92  m_task->decrement_ref_count();
93  m_task = nullptr;
94  return holder;
95  }
96 }
WaitingTaskWithArenaHolder & operator=(const WaitingTaskWithArenaHolder &iRHS)
#define nullptr
void dependentTaskFailed(std::exception_ptr iPtr)
Called if waited for task failed.
Definition: WaitingTask.h:64
void doneWaiting(std::exception_ptr iExcept)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
HLT enums.
std::shared_ptr< tbb::task_arena > m_arena
def move(src, dest)
Definition: eostools.py:510