-
Type: Bug
-
Resolution: Unresolved
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
Labels:
-
Service Arch
-
ALL
-
The ScopedTaskExecutor wraps another "underlying" TaskExecutor that it forwards work to actually be executed on. When work is scheduled on the ScopedTaskExecutor after the underlying executor is shutdown, this invariant in TaskExecutor::schedule is triggered.
Here's a brief explanation as to why: say exec is a ScopedTaskExecutor. When exec->schedule(...) is called:
1) The member-of-pointer operator on ScopedTaskExecutor returns a TaskExecutor*, which actually points to a ScopedTaskExecutor::Impl, which inherits from TaskExecutor.
2) TaskExecutor::schedule is called, and then calls the member scheduleWork; because the actual type here is ScopedTaskExecutor::Impl, we use its definition of scheduleWork here
3) The ScopedTaskExecutor attempts to wrap the provided Task in a lambda here, where it captures the provided Task by forwarding it into the lambda. This will invoke the move assignment operator and invalidate the provided Task
4) The ScopedTaskExecutor attempts to schedule the wrapped Task on the underlying executor, which refuses because it is shutdown, and returns a bad status.
5) The ScopedTaskExecutor propagates the bad status up to TaskExecutor::schedule. However, it has broken the contract of scheduleWork, by returning a bad status (failing to schedule) and invalidating the provided Task. Therefore, the invariant is hit.