boost :: asio :: basic_waitable_timer пользовательские часы - PullRequest
0 голосов
/ 19 ноября 2018

Я хотел бы создать собственные часы, которые можно установить вручную и использовать с boost::asio::basic_waitable_timer

Я пробовал следующее:

class my_clock {
public:
    using duration = std::chrono::nanoseconds;
    using time_point = std::chrono::time_point<std::chrono::system_clock>;
    static time_point now() {
       return n;
    }
    static void set_now(time_point now) {
        n = now;
    }
private:
    static time_point n;

};
my_clock::time_point my_clock::n = my_clock::time_point();

Затем используйте его следующим образом:

boost::asio::io_context ctx;
auto now = std::chrono::system_clock::now();
my_clock::set_now(now);
auto next_expire = now + std::chrono::milliseconds(10);
boost::asio::basic_waitable_timer<my_clock> ctimer(ctx);
ctimer.expires_at(next_expire);

int count = 0;
ctimer.async_wait([&](const boost::asio::error_code& ec) {
    count++;
});
ctx.run_one();
// count == 0
my_clock::set_now(next_expire + std::chrono::seconds(1));
ctx.run();
// count == 1, except it's NOT

Есть ли какие-либо предложения о том, как таким способом ввести пользовательские часы в basic_waitiable_timer?

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

С помощью ответа @ sergiopm можно найти следующее решение:

class my_clock {
public:
    using duration = std::chrono::nanoseconds;
    using time_point = std::chrono::time_point<my_clock>;
    using rep = duration::rep;
    using period = duration::period;
    static constexpr bool is_steady = false;

    static time_point now() noexcept {
       return n;
    }
    static void set_now(time_point now) {
        n = now;
    }
private:
    static time_point n;
};

Затем необходимо переопределить черты ожидания waitable_timer, чтобы он не ожидал на настенных часах при опросе контекста io:

struct wait_traits
{
  static typename my_clock::duration to_wait_duration(
      const typename my_clock::duration& d)
  {
        return std::chrono::nanoseconds(0);
  }
};

Затем выполните упражнение следующим образом:

asio::io_context ctx;
auto now = my_clock::time_point(my_clock::duration(10));
my_clock::set_now(now);
asio::basic_waitable_timer<my_clock, wait_traits> ctimer(ctx);
auto next_expire = now + std::chrono::milliseconds(10);
ctimer.expires_at(next_expire);
ctimer.async_wait([&](const asio::error_code& ec) {
    future_period_count++;
    std::cout << "THIS HAPPENED" << std::endl;
});
ctx.poll_one();
REQUIRE(future_period_count == 0);
my_clock::set_now(next_expire + std::chrono::seconds(1));
ctx.run_one();
REQUIRE(future_period_count == 1);
0 голосов
/ 19 ноября 2018

Пока ваши часы удовлетворяют требованиям TrivialClock , вы сможете использовать их с basic_waitiable_timer .Несколько примеров:

...