std::pair<size_t, duration_t> synchronized_reset(Mutex& mtx, CondVar& cv, TimeDuration const& timeout) { ACTX_ASSERTS(!blocked()); if (timeout <= TimeDuration::zero()) { auto c = reset(); return std::make_pair(c, TimeDuration::zero()); } if (timeout >= (TimeDuration::max)()) { auto nw = eclipse_clock_t::now(); auto c = pri_synchronized_reset(mtx, cv); return std::make_pair(c, eclipse_clock_t::now() - nw); } auto c = reset(); if (c != 0) { return std::make_pair(c, TimeDuration::zero()); } std::unique_lock<Mutex> guard{mtx}; block(); auto _ = gsl::finally([this]() {unblock(); }); c = reset(); if (c != 0) { return std::make_pair(c, TimeDuration::zero()); } auto const timeout_dur = std::chrono::duration_cast<duration_t>(timeout); auto curr_timeout = timeout_dur; auto final_eclipse = TimeDuration::zero(); while (c == 0) { auto bt = eclipse_clock_t::now(); auto status = cv.wait_for(guard, curr_timeout); if (status == std::cv_status::timeout) { c = reset(); final_eclipse = timeout_dur; break; } else { auto eclipse = eclipse_clock_t::now() - bt; c = reset(); final_eclipse += eclipse; if (eclipse >= curr_timeout) { break; } curr_timeout -= eclipse; } } return std::make_pair(c, final_eclipse); }