Esempio n. 1
0
  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);
  }