diff options
author | George Hazan <ghazan@miranda.im> | 2022-11-30 17:48:47 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2022-11-30 17:48:47 +0300 |
commit | 0ece30dc7c0e34b4c5911969b8fa99c33c6d023c (patch) | |
tree | 671325d3fec09b999411e4e3ab84ef8259261818 /protocols/Telegram/tdlib/td/tdactor/test/actors_bugs.cpp | |
parent | 46c53ffc6809c67e4607e99951a2846c382b63b2 (diff) |
Telegram: update for TDLIB
Diffstat (limited to 'protocols/Telegram/tdlib/td/tdactor/test/actors_bugs.cpp')
-rw-r--r-- | protocols/Telegram/tdlib/td/tdactor/test/actors_bugs.cpp | 93 |
1 files changed, 79 insertions, 14 deletions
diff --git a/protocols/Telegram/tdlib/td/tdactor/test/actors_bugs.cpp b/protocols/Telegram/tdlib/td/tdactor/test/actors_bugs.cpp index f4267f2818..0720f0ed6f 100644 --- a/protocols/Telegram/tdlib/td/tdactor/test/actors_bugs.cpp +++ b/protocols/Telegram/tdlib/td/tdactor/test/actors_bugs.cpp @@ -1,38 +1,39 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "td/utils/tests.h" - -#include "td/actor/Timeout.h" +#include "td/actor/actor.h" +#include "td/actor/ConcurrentScheduler.h" +#include "td/actor/MultiTimeout.h" -using namespace td; +#include "td/utils/common.h" +#include "td/utils/logging.h" +#include "td/utils/Random.h" +#include "td/utils/tests.h" TEST(MultiTimeout, bug) { - ConcurrentScheduler sched; - int threads_n = 0; - sched.init(threads_n); + td::ConcurrentScheduler sched(0, 0); sched.start(); - std::unique_ptr<MultiTimeout> multi_timeout; + td::unique_ptr<td::MultiTimeout> multi_timeout; struct Data { - MultiTimeout *multi_timeout; + td::MultiTimeout *multi_timeout; }; Data data; { - auto guard = sched.get_current_guard(); - multi_timeout = std::make_unique<MultiTimeout>(); + auto guard = sched.get_main_guard(); + multi_timeout = td::make_unique<td::MultiTimeout>("MultiTimeout"); data.multi_timeout = multi_timeout.get(); - multi_timeout->set_callback([](void *void_data, int64 key) { + multi_timeout->set_callback([](void *void_data, td::int64 key) { auto &data = *static_cast<Data *>(void_data); if (key == 1) { data.multi_timeout->cancel_timeout(key + 1); data.multi_timeout->set_timeout_in(key + 2, 1); } else { - Scheduler::instance()->finish(); + td::Scheduler::instance()->finish(); } }); multi_timeout->set_callback_data(&data); @@ -45,3 +46,67 @@ TEST(MultiTimeout, bug) { } sched.finish(); } + +class TimeoutManager final : public td::Actor { + static td::int32 count; + + public: + TimeoutManager() { + count++; + + test_timeout_.set_callback(on_test_timeout_callback); + test_timeout_.set_callback_data(static_cast<void *>(this)); + } + TimeoutManager(const TimeoutManager &) = delete; + TimeoutManager &operator=(const TimeoutManager &) = delete; + TimeoutManager(TimeoutManager &&) = delete; + TimeoutManager &operator=(TimeoutManager &&) = delete; + ~TimeoutManager() final { + count--; + LOG(INFO) << "Destroy TimeoutManager"; + } + + static void on_test_timeout_callback(void *timeout_manager_ptr, td::int64 id) { + CHECK(count >= 0); + if (count == 0) { + LOG(ERROR) << "Receive timeout after manager was closed"; + return; + } + + auto manager = static_cast<TimeoutManager *>(timeout_manager_ptr); + send_closure_later(manager->actor_id(manager), &TimeoutManager::test_timeout); + } + + void test_timeout() { + CHECK(count > 0); + // we must yield scheduler, so run_main breaks immediately, if timeouts are handled immediately + td::Scheduler::instance()->yield(); + } + + td::MultiTimeout test_timeout_{"TestTimeout"}; +}; + +td::int32 TimeoutManager::count; + +TEST(MultiTimeout, Destroy) { + td::ConcurrentScheduler sched(0, 0); + + auto timeout_manager = sched.create_actor_unsafe<TimeoutManager>(0, "TimeoutManager"); + TimeoutManager *manager = timeout_manager.get().get_actor_unsafe(); + sched.start(); + int cnt = 100; + while (sched.run_main(cnt == 100 || cnt <= 0 ? 0.001 : 10)) { + auto guard = sched.get_main_guard(); + cnt--; + if (cnt > 0) { + for (int i = 0; i < 2; i++) { + manager->test_timeout_.set_timeout_in(td::Random::fast(0, 1000000000), td::Random::fast(2, 5) / 1000.0); + } + } else if (cnt == 0) { + timeout_manager.reset(); + } else if (cnt == -10) { + td::Scheduler::instance()->finish(); + } + } + sched.finish(); +} |