diff --git a/FWCore/Concurrency/interface/WaitingTaskHolder.h b/FWCore/Concurrency/interface/WaitingTaskHolder.h index 9b813900fe4f2..ad8df7a6b96fe 100644 --- a/FWCore/Concurrency/interface/WaitingTaskHolder.h +++ b/FWCore/Concurrency/interface/WaitingTaskHolder.h @@ -83,7 +83,7 @@ namespace edm { /** Use in the case where you need to inform the parent task of a failure before some other child task which may be run later reports a different, but related failure. You must later call doneWaiting - in the same thread passing the same exceptoin. + in the same thread passing the same exception. */ void presetTaskAsFailed(std::exception_ptr iExcept) noexcept { if (iExcept) { diff --git a/FWCore/Concurrency/interface/WaitingTaskWithArenaHolder.h b/FWCore/Concurrency/interface/WaitingTaskWithArenaHolder.h index 7151586edb0a4..255376d9bdeb8 100644 --- a/FWCore/Concurrency/interface/WaitingTaskWithArenaHolder.h +++ b/FWCore/Concurrency/interface/WaitingTaskWithArenaHolder.h @@ -60,6 +60,12 @@ namespace edm { // the task. doneWaiting can be called from a non-TBB thread. void doneWaiting(std::exception_ptr iExcept); + // Use in the case where you need to inform the parent task of a + // failure before some other child task which may be run later + // reports a different, but related failure. You must later call + // doneWaiting in the same thread passing the same exception. + void presetTaskAsFailed(std::exception_ptr iExcept) noexcept; + // This next function is useful if you know from the context that // m_arena (which is set when the constructor was executes) is the // same arena in which you want to execute the doneWaiting function. diff --git a/FWCore/Concurrency/interface/WaitingThreadPool.h b/FWCore/Concurrency/interface/WaitingThreadPool.h index affca59422964..2d68693a4e63b 100644 --- a/FWCore/Concurrency/interface/WaitingThreadPool.h +++ b/FWCore/Concurrency/interface/WaitingThreadPool.h @@ -34,7 +34,10 @@ namespace edm { convertException::wrap([&func]() { func(); }); } catch (cms::Exception& e) { e.addContext(errorContext()); - holder.doneWaiting(std::current_exception()); + // doneWaiting() is intentionally not called here. The + // reference count decrement must be done only in + // threadLoop() (see the comment there) + holder.presetTaskAsFailed(std::current_exception()); } }; thisPtr_ = std::move(thisPtr); diff --git a/FWCore/Concurrency/src/WaitingTaskWithArenaHolder.cc b/FWCore/Concurrency/src/WaitingTaskWithArenaHolder.cc index c6cf192800885..5eeb0e75e5e46 100644 --- a/FWCore/Concurrency/src/WaitingTaskWithArenaHolder.cc +++ b/FWCore/Concurrency/src/WaitingTaskWithArenaHolder.cc @@ -90,6 +90,12 @@ namespace edm { } } + void WaitingTaskWithArenaHolder::presetTaskAsFailed(std::exception_ptr iExcept) noexcept { + if (iExcept) { + m_task->dependentTaskFailed(iExcept); + } + } + // This next function is useful if you know from the context that // m_arena (which is set when the constructor was executes) is the // same arena in which you want to execute the doneWaiting function.