13 YACLIB_DEBUG(_jobs.load(std::memory_order_relaxed) != Mark(),
"Strand not empty in dtor");
21 return _executor->
Alive();
25 auto*
expected = _jobs.load(std::memory_order_relaxed);
28 }
while (!_jobs.compare_exchange_weak(
expected, &job, std::memory_order_acq_rel, std::memory_order_relaxed));
31 _executor->Submit(*
this);
36 auto*
node = _jobs.exchange(
nullptr, std::memory_order_acquire);
43 }
while (
node !=
nullptr);
46 static_cast<Job*
>(prev)->Call();
48 }
while (prev !=
nullptr);
49 if (_jobs.load(std::memory_order_relaxed) ==
node &&
50 _jobs.compare_exchange_strong(
node, Mark(), std::memory_order_release, std::memory_order_relaxed)) {
51 static_cast<Job&
>(*this).DecRef();
58 auto*
node = _jobs.exchange(Mark(), std::memory_order_acq_rel);
61 static_cast<Job*
>(
node)->Drop();
63 }
while (
node !=
nullptr);
64 static_cast<Job&
>(*this).DecRef();
67detail::Node* Strand::Mark()
noexcept {
68 return static_cast<Node*
>(
this);
virtual bool Alive() const noexcept=0
Return true if executor still alive, that means job passed to submit will be Call.
virtual void Submit(Job &job) noexcept=0
Submit given job.
virtual void IncRef() noexcept
Increments reference counter.
Callable that can be executed in an IExecutor.
bool Alive() const noexcept final
Return true if executor still alive, that means job passed to submit will be Call.
Type Tag() const noexcept final
Return type of this executor.
void Submit(Job &job) noexcept final
Submit given job.
~Strand() noexcept override
#define YACLIB_DEBUG(cond, message)
IExecutorPtr MakeStrand(IExecutorPtr e)
Strand is the asynchronous analogue of a mutex.
Contract< V, E > MakeContract()
Creates related future and promise.