From 9856b0e46e8081ddf7ae889ccdd902d997dec1db Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 11 Oct 2020 21:21:38 +0300 Subject: [PATCH] Add some workariunds for crashes on exit without closing all clients. GitOrigin-RevId: 5c74e9fe6951b6a8eb65d6c1e5ddf7bf8e0c8163 --- td/telegram/Client.cpp | 17 ++++++++++++----- tdactor/td/actor/impl/Scheduler.cpp | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/td/telegram/Client.cpp b/td/telegram/Client.cpp index e8aa89870..b9b428e78 100644 --- a/td/telegram/Client.cpp +++ b/td/telegram/Client.cpp @@ -176,9 +176,11 @@ class ClientManager::Impl final { } } while (!tds_.empty() && !ExitGuard::is_exited()) { - receive(10); + receive(0.1); + } + if (!ExitGuard::is_exited()) { // prevent closing of schedulers from already killed by OS threads + concurrent_scheduler_->finish(); } - concurrent_scheduler_->finish(); } private: @@ -380,7 +382,9 @@ class MultiImpl { Scheduler::instance()->finish(); } scheduler_thread_.join(); - concurrent_scheduler_->finish(); + if (!ExitGuard::is_exited()) { // prevent closing of schedulers from already killed by OS threads + concurrent_scheduler_->finish(); + } } private: @@ -519,11 +523,14 @@ class ClientManager::Impl final { Impl(Impl &&) = delete; Impl &operator=(Impl &&) = delete; ~Impl() { + if (ExitGuard::is_exited()) { + return; + } for (auto &it : impls_) { close_impl(it.first); } while (!impls_.empty() && !ExitGuard::is_exited()) { - receive(10); + receive(0.1); } } @@ -571,7 +578,7 @@ class Client::Impl final { ~Impl() { multi_impl_->close(td_id_); while (!ExitGuard::is_exited()) { - auto response = receiver_.receive(10.0); + auto response = receiver_.receive(0.1); if (response.object == nullptr && response.client_id != 0 && response.request_id == 0) { break; } diff --git a/tdactor/td/actor/impl/Scheduler.cpp b/tdactor/td/actor/impl/Scheduler.cpp index 39cb4661e..ca8f58fb6 100644 --- a/tdactor/td/actor/impl/Scheduler.cpp +++ b/tdactor/td/actor/impl/Scheduler.cpp @@ -111,6 +111,7 @@ void Scheduler::ServiceActor::tear_down() { /*** SchedlerGuard ***/ SchedulerGuard::SchedulerGuard(Scheduler *scheduler, bool lock) : scheduler_(scheduler) { if (lock) { + // the next check can fail if OS killed the scheduler's thread without releasing the guard CHECK(!scheduler_->has_guard_); scheduler_->has_guard_ = true; }