IIRC, the Asio implementation checks to see if the current thread already holds a lock, and if so, adopts the current lock and enqueues any child tasks that are created and processes them after the user-provided function returns, to avoid deadlock in the case that Jonathan outlines here. On Wed, Mar 22, 2023 at 7:32 AM Jonathan Wakely via Libstdc++ < libstdc++@gcc.gnu.org> wrote: > On Tue, 23 Mar 2021 at 16:39, Jonathan Wakely wrote: > > > On 12/03/21 13:21 +0100, Alessio G. B. via Libstdc++ wrote: > > >I expanded the implementation of the class strand of the Networking > > >TS. Essentially, I > > >implemented a token system so each thread knows when it can execute; > > >the system is organized > > >with 2 integers moving as a clock. > > > > Thanks for this patch. I'm not sure when I'll have time to review it, > > and it might not be in time for the upcoming GCC 11 release. But the > > patch has been received and will get reviewed, thanks. > > > > Well I didn't think it would take me two years, sorry about that :-( > > + template > + void > + invoke(unsigned int token, _Func&& __f) > + { > + std::unique_lock __lock(_M_mutex); > + > + _M_cv.wait(__lock, > + [token, next_token = _M_next_token]() > + { return token == next_token; }); > + > + try { decay_t<_Func>{std::forward<_Func>(__f)}(); } > + catch(...) { } > + > + _M_next_token++; > + > + __lock.unlock(); > + > + _M_cv.notify_all(); > + } > > It looks like this will run a user-provided function while holding the > mutex lock. Won't that deadlock if the task added to the strand adds > another task to the same strand? Is that forbidden by some requirement in > the TS that I've forgotten? > >