Skip to content

Commit

Permalink
Add wait_one_for and wait_one_until api
Browse files Browse the repository at this point in the history
  • Loading branch information
shuai132 committed Jun 24, 2024
1 parent af0128d commit 372886c
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 9 deletions.
4 changes: 2 additions & 2 deletions asio/include/asio/detail/impl/scheduler.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,10 @@ std::size_t scheduler::run_one(asio::error_code& ec)
return do_run_one(lock, this_thread, ec);
}

std::size_t scheduler::wait_event(long usec, asio::error_code &ec)
void scheduler::wait_event(long usec, asio::error_code &ec)
{
task_->mask_wait_only();
return wait_one(usec, ec);
wait_one(usec, ec);
}

std::size_t scheduler::wait_one(long usec, asio::error_code& ec)
Expand Down
2 changes: 1 addition & 1 deletion asio/include/asio/detail/scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class scheduler
ASIO_DECL std::size_t poll_one(asio::error_code& ec);

// Wait until timeout, interrupted, or one operation event.
ASIO_DECL std::size_t wait_event(long usec, asio::error_code& ec);
ASIO_DECL void wait_event(long usec, asio::error_code& ec);

// Interrupt the event processing loop.
ASIO_DECL void stop();
Expand Down
25 changes: 25 additions & 0 deletions asio/include/asio/impl/io_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,31 @@ std::size_t io_context::run_one_until(
return 0;
}

template <typename Rep, typename Period>
void io_context::wait_one_for(const chrono::duration<Rep, Period>& rel_time)
{
this->wait_one_until(chrono::steady_clock::now() + rel_time);
}

template <typename Clock, typename Duration>
void io_context::wait_one_until(
const chrono::time_point<Clock, Duration> &abs_time)
{
typename Clock::time_point now = Clock::now();
if (now < abs_time) {
typename Clock::duration rel_time = abs_time - now;
if (rel_time > chrono::seconds(1))
rel_time = chrono::seconds(1);

asio::error_code ec;
impl_.wait_event(
static_cast<long>(
chrono::duration_cast<chrono::microseconds>(rel_time).count()),
ec);
asio::detail::throw_error(ec);
}
}

#if !defined(ASIO_NO_DEPRECATED)

inline void io_context::reset()
Expand Down
24 changes: 24 additions & 0 deletions asio/include/asio/io_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,30 @@ class io_context
ASIO_DECL count_type poll_one(asio::error_code& ec);
#endif // !defined(ASIO_NO_DEPRECATED)

/// Run the io_context object's event processing loop for a specified duration
/// do not execute any handler, just wait.
/**
* The wait_one_for() function blocks until one handler has been dispatched,
* until the io_context has been stopped, or until the specified duration has
* elapsed.
*
* @param rel_time The duration for which the call may block.
*/
template <typename Rep, typename Period>
void wait_one_for(const chrono::duration<Rep, Period>& rel_time);

/// Run the io_context object's event processing loop until a specified time
/// do not execute any handler, just wait.
/**
* The wait_one_until() function blocks until one handler has been dispatched,
* until the io_context has been stopped, or until the specified time has
* been reached.
*
* @param abs_time The time point until which the call may block.
*/
template <typename Clock, typename Duration>
void wait_one_until(const chrono::time_point<Clock, Duration>& abs_time);

/// Stop the io_context object's event processing loop.
/**
* This function does not block, but instead simply signals the io_context to
Expand Down
43 changes: 43 additions & 0 deletions asio/src/examples/cpp11/other_eventloop/with_asio.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "asio.hpp"

#if __has_include("log.h")
#include "log.h"
#else
#define LOG printf
#endif

int main() {
asio::io_context io_context_main;
io_context_main.dispatch([] { LOG("main thread"); });

std::thread([&] {
LOG("other thread");
asio::io_context io_context_other;

asio::steady_timer asio_timer(io_context_other);
std::function<void()> start_asio_timer;
start_asio_timer = [&] {
asio_timer.expires_after(asio::chrono::milliseconds(1000));
asio_timer.async_wait([&](const asio::error_code &ec) {
LOG("asio Timer fired!");
start_asio_timer();
});
};
start_asio_timer();

for (;;) {
LOG("wait_event...");
io_context_other.wait_one_for(std::chrono::minutes(1));
std::promise<void> promise;
io_context_main.dispatch([&] {
io_context_other.poll_one();
promise.set_value();
});
promise.get_future().get();
}
}).detach();

asio::io_context::work work(io_context_main);
io_context_main.run();
return 0;
}
12 changes: 6 additions & 6 deletions asio/src/examples/cpp11/other_eventloop/with_libuv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
#include <iostream>
#include <uv.h>

//#define USE_LOG
#ifdef USE_LOG
#if __has_include("log.h")
#include "log.h"
#else
#define LOG printf
Expand All @@ -13,6 +12,7 @@ int main() {
uv_loop_t *loop = uv_default_loop();
static asio::io_context io_context;
asio::io_context::work work(io_context);
LOG("main thread\n");

uv_timer_t timer_req;
uv_timer_init(loop, &timer_req);
Expand All @@ -33,6 +33,7 @@ int main() {

static std::condition_variable async_done;
std::mutex async_done_lock;

uv_async_t async;
uv_async_init(loop, &async, [](uv_async_t *handle) {
io_context.poll_one();
Expand All @@ -41,10 +42,9 @@ int main() {

std::thread([&] {
for (;;) {
LOG("wait_event...");
asio::error_code ec;
auto &service = asio::use_service<asio::detail::scheduler>(io_context);
service.wait_event(INTMAX_MAX, ec);
LOG("wait_event...\n");
io_context.wait_one_for(std::chrono::minutes(1));

uv_async_send(&async);
std::unique_lock<std::mutex> lock(async_done_lock);
async_done.wait(lock);
Expand Down

0 comments on commit 372886c

Please sign in to comment.