Skip to content

Commit

Permalink
Check for active handles using io_context::run_one
Browse files Browse the repository at this point in the history
  • Loading branch information
NikitaNikolaenko committed Jul 27, 2022
1 parent 985e45b commit 6acbfa5
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 29 deletions.
42 changes: 19 additions & 23 deletions eventuals/event-loop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,31 +163,20 @@ EventLoop::EventLoop()
// do about that except 'RunForever()' or application-level
// synchronization).
uv_check_init(&loop_, &check_);
uv_check_init(&loop_, &asio_check_);

check_.data = this;
asio_check_.data = this;

uv_check_start(&check_, [](uv_check_t* check) {
((EventLoop*) check->data)->Check();
});

uv_check_start(&asio_check_, [](uv_check_t* check) {
((EventLoop*) check->data)->AsioCheck();
// Poll ASIO handles before scheduling.
((EventLoop*) check->data)->AsioPoll();
((EventLoop*) check->data)->Check(); // Schedules waiters.
});

// NOTE: we unreference 'check_' so that when we run the event
// loop it's presence doesn't factor into whether or not the loop is
// considered alive.
uv_unref((uv_handle_t*) &check_);

// TODO: we should consider event loop to be alive
// while this check is running.
// Before we find a better way to determine if there are
// still pending jobs in the asio io_context,
// we will just unreference this check.
uv_unref((uv_handle_t*) &asio_check_);

uv_async_init(&loop_, &async_, nullptr);

// NOTE: see comments in 'RunUntil()' as to why we don't unreference
Expand All @@ -202,9 +191,6 @@ EventLoop::~EventLoop() {
uv_check_stop(&check_);
uv_close((uv_handle_t*) &check_, nullptr);

uv_check_stop(&asio_check_);
uv_close((uv_handle_t*) &asio_check_, nullptr);

uv_close((uv_handle_t*) &async_, nullptr);

// NOTE: ideally we can just run 'uv_run()' once now in order to
Expand All @@ -229,14 +215,21 @@ EventLoop::~EventLoop() {
static constexpr size_t ITERATIONS = 100000;
size_t iterations = ITERATIONS;

auto alive = Alive();
CHECK(uv_loop_alive(&loop_))
<< "should still have check and async handles to close";

CHECK(alive) << "should still have check and async handles to close";
size_t active_handles = 0;

do {
alive = uv_run(&loop_, UV_RUN_NOWAIT);
active_handles = uv_run(&loop_, UV_RUN_NOWAIT);

if (alive && --iterations == 0) {
// Is needed for the following 'io_context.run()'.
io_context_.restart();

// BLOCKS! Returns 0 ONLY if there are no active handles left.
active_handles += io_context_.run_one();

if (active_handles > 0 && --iterations == 0) {
std::ostringstream out;

out << "destructing EventLoop with active handles:\n";
Expand Down Expand Up @@ -274,9 +267,12 @@ EventLoop::~EventLoop() {

LOG(WARNING) << out.str();

// NOTE: there's currently no way for us to print out active
// ASIO handles.

iterations = ITERATIONS;
}
} while (alive);
} while (active_handles > 0);

CHECK_EQ(uv_loop_close(&loop_), 0);
}
Expand Down Expand Up @@ -397,7 +393,7 @@ void EventLoop::Check() {

////////////////////////////////////////////////////////////////////////

void EventLoop::AsioCheck() {
void EventLoop::AsioPoll() {
io_context().restart();
io_context().poll();
}
Expand Down
7 changes: 1 addition & 6 deletions eventuals/event-loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -527,10 +527,6 @@ class EventLoop final : public Scheduler {
template <typename E>
[[nodiscard]] auto Schedule(std::string&& name, E e);

bool Alive() {
return uv_loop_alive(&loop_);
}

bool Running() {
return running_.load();
}
Expand Down Expand Up @@ -1060,11 +1056,10 @@ class EventLoop final : public Scheduler {

void Check();

void AsioCheck();
void AsioPoll();

uv_loop_t loop_ = {};
uv_check_t check_ = {};
uv_check_t asio_check_ = {};
uv_async_t async_ = {};

asio::io_context io_context_;
Expand Down

0 comments on commit 6acbfa5

Please sign in to comment.