From 70f737372963e72324943aac04491ada844b1c9f Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 21 Jun 2022 20:06:39 +0300 Subject: [PATCH 01/38] Pretend that statistics is collected at least for a second on start. --- tdutils/td/utils/TimedStat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tdutils/td/utils/TimedStat.h b/tdutils/td/utils/TimedStat.h index ad11444a7..f22129566 100644 --- a/tdutils/td/utils/TimedStat.h +++ b/tdutils/td/utils/TimedStat.h @@ -18,7 +18,7 @@ template class TimedStat { public: TimedStat(double duration, double now) - : duration_(duration), current_(), current_timestamp_(now), next_(), next_timestamp_(now) { + : duration_(duration), current_(), current_timestamp_(now - 1), next_(), next_timestamp_(now) { } TimedStat() : TimedStat(0, 0) { } From 3f763f6fc526bbed7899cfecbe0fa86109a0a5c5 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 22 Jun 2022 16:15:56 +0300 Subject: [PATCH 02/38] Add more logging. --- td/telegram/MessageEntity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/td/telegram/MessageEntity.cpp b/td/telegram/MessageEntity.cpp index b569f6112..1f8be2831 100644 --- a/td/telegram/MessageEntity.cpp +++ b/td/telegram/MessageEntity.cpp @@ -4248,7 +4248,7 @@ vector> get_input_message_entities(co break; case MessageEntity::Type::MentionName: { auto r_input_user = contacts_manager->get_input_user(entity.user_id); - LOG_CHECK(r_input_user.is_ok()) << source << ' ' << r_input_user.error(); + LOG_CHECK(r_input_user.is_ok()) << source << ' ' << entity.user_id << ' ' << r_input_user.error(); result.push_back(make_tl_object(entity.offset, entity.length, r_input_user.move_as_ok())); break; From 6572d02dbdd537d86bb73bb287ac073fd5f39993 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 23 Jun 2022 14:06:06 +0300 Subject: [PATCH 03/38] Use current time as update date if it is unknown. --- td/telegram/UpdatesManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 4fbe74252..763aa057a 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1719,7 +1719,7 @@ void UpdatesManager::on_pending_updates(vectorunix_time() : date; LOG(INFO) << "Process short " << oneline(to_string(update)); // don't need promise for short update downcast_call(*update, OnUpdate(this, update, Promise())); From 365984286485bc9b4e8d322acf34aa8a9e61e4ad Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 23 Jun 2022 16:36:58 +0300 Subject: [PATCH 04/38] Fix updateNotificationGroup. --- td/telegram/NotificationManager.cpp | 37 ++++++++++++++++------------- td/telegram/NotificationManager.h | 2 +- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index 108dfd243..85cc37766 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -445,7 +445,7 @@ NotificationManager::NotificationGroups::iterator NotificationManager::get_group if (last_group_key.last_notification_date != 0) { send_remove_group_update(last_group_key, groups_[last_group_key], vector()); } - send_add_group_update(group_key, group); + send_add_group_update(group_key, group, "get_group_force"); } } return add_group(std::move(group_key), std::move(group), "get_group_force"); @@ -464,6 +464,7 @@ int32 NotificationManager::load_message_notification_groups_from_database(int32 return 0; } + VLOG(notifications) << "Trying to load up to " << limit << " notification groups from database"; vector group_keys = td_->messages_manager_->get_message_notification_group_keys_from_database( last_loaded_notification_group_key_, limit); last_loaded_notification_group_key_ = @@ -677,7 +678,7 @@ void NotificationManager::add_notifications_to_group_begin(NotificationGroups::i // need to remove last notification group to not exceed max_notification_group_count_ send_remove_group_update(last_group_key, groups_[last_group_key], vector()); } - send_add_group_update(group_key, group); + send_add_group_update(group_key, group, "add_notifications_to_group_begin"); } vector new_notifications; @@ -714,7 +715,7 @@ void NotificationManager::add_notifications_to_group_begin(NotificationGroups::i if (!added_notifications.empty()) { add_update_notification_group(td_api::make_object( - group_key.group_id.get(), get_notification_group_type_object(group.type), group_key.dialog_id.get(), 0, true, + group_key.group_id.get(), get_notification_group_type_object(group.type), group_key.dialog_id.get(), 0, 0, group.total_count, std::move(added_notifications), vector())); } } @@ -1445,7 +1446,7 @@ td_api::object_ptr NotificationManager::get_rem } return td_api::make_object( group_key.group_id.get(), get_notification_group_type_object(group.type), group_key.dialog_id.get(), - group_key.dialog_id.get(), true, group.total_count, vector>(), + group_key.dialog_id.get(), 0, group.total_count, vector>(), std::move(removed_notification_ids)); } @@ -1459,8 +1460,9 @@ void NotificationManager::send_remove_group_update(const NotificationGroupKey &g } } -void NotificationManager::send_add_group_update(const NotificationGroupKey &group_key, const NotificationGroup &group) { - VLOG(notifications) << "Add " << group_key.group_id; +void NotificationManager::send_add_group_update(const NotificationGroupKey &group_key, const NotificationGroup &group, + const char *source) { + VLOG(notifications) << "Add " << group_key.group_id << " from " << source; auto total_size = group.notifications.size(); auto added_size = min(total_size, max_notification_group_size_); vector> added_notifications; @@ -1474,7 +1476,7 @@ void NotificationManager::send_add_group_update(const NotificationGroupKey &grou if (!added_notifications.empty()) { add_update_notification_group(td_api::make_object( - group_key.group_id.get(), get_notification_group_type_object(group.type), group_key.dialog_id.get(), 0, true, + group_key.group_id.get(), get_notification_group_type_object(group.type), group_key.dialog_id.get(), 0, 0, group.total_count, std::move(added_notifications), vector())); } } @@ -1532,7 +1534,7 @@ void NotificationManager::flush_pending_notifications(NotificationGroupId group_ removed_group_id = last_group_key.group_id; send_remove_group_update(last_group_key, groups_[last_group_key], vector()); } - send_add_group_update(group_key, group); + send_add_group_update(group_key, group, "flush_pending_notifications"); } DialogId notification_settings_dialog_id; @@ -1727,8 +1729,8 @@ void NotificationManager::on_notifications_removed( if (final_group_key.last_notification_date == 0 && group.total_count == 0) { // send update about empty invisible group anyway add_update_notification_group(td_api::make_object( - group_key.group_id.get(), get_notification_group_type_object(group.type), group_key.dialog_id.get(), 0, true, - 0, vector>(), vector())); + group_key.group_id.get(), get_notification_group_type_object(group.type), group_key.dialog_id.get(), 0, 0, 0, + vector>(), vector())); } else { VLOG(notifications) << "There is no need to send updateNotificationGroup about " << group_key.group_id; } @@ -1736,14 +1738,14 @@ void NotificationManager::on_notifications_removed( if (is_updated) { // group is still visible add_update_notification_group(td_api::make_object( - group_key.group_id.get(), get_notification_group_type_object(group.type), group_key.dialog_id.get(), 0, true, + group_key.group_id.get(), get_notification_group_type_object(group.type), group_key.dialog_id.get(), 0, 0, group.total_count, std::move(added_notifications), std::move(removed_notification_ids))); } else { // group needs to be removed send_remove_group_update(group_key, group, std::move(removed_notification_ids)); if (last_group_key.last_notification_date != 0) { // need to add new last notification group - send_add_group_update(last_group_key, groups_[last_group_key]); + send_add_group_update(last_group_key, groups_[last_group_key], "on_notifications_removed"); } } } @@ -1762,8 +1764,8 @@ void NotificationManager::on_notifications_removed( } if (last_loaded_notification_group_key_ < last_group_key) { - load_message_notification_groups_from_database(td::max(static_cast(max_notification_group_count_), 10) / 2, - true); + auto limit = td::max(static_cast(max_notification_group_count_), static_cast(10)) / 2; + load_message_notification_groups_from_database(limit, true); } } @@ -2411,7 +2413,7 @@ void NotificationManager::on_notification_group_count_max_changed(bool send_upda } if (is_increased) { - send_add_group_update(group_key, group); + send_add_group_update(group_key, group, "on_notification_group_count_max_changed"); } else { send_remove_group_update(group_key, group, vector()); } @@ -2430,7 +2432,8 @@ void NotificationManager::on_notification_group_count_max_changed(bool send_upda max_notification_group_count_ = new_max_notification_group_count_size_t; if (is_increased && last_loaded_notification_group_key_ < get_last_updated_group_key()) { - load_message_notification_groups_from_database(td::max(new_max_notification_group_count, 5), true); + auto limit = td::max(new_max_notification_group_count, static_cast(5)); + load_message_notification_groups_from_database(limit, true); } } @@ -2505,7 +2508,7 @@ void NotificationManager::on_notification_group_size_max_changed() { if (!is_destroyed_) { auto update = td_api::make_object( group_key.group_id.get(), get_notification_group_type_object(group.type), group_key.dialog_id.get(), - group_key.dialog_id.get(), true, group.total_count, std::move(added_notifications), + group_key.dialog_id.get(), 0, group.total_count, std::move(added_notifications), std::move(removed_notification_ids)); VLOG(notifications) << "Send " << as_notification_update(update.get()); send_closure(G()->td(), &Td::send_update, std::move(update)); diff --git a/td/telegram/NotificationManager.h b/td/telegram/NotificationManager.h index 9ba19171a..69a3ddb6c 100644 --- a/td/telegram/NotificationManager.h +++ b/td/telegram/NotificationManager.h @@ -273,7 +273,7 @@ class NotificationManager final : public Actor { void send_remove_group_update(const NotificationGroupKey &group_key, const NotificationGroup &group, vector &&removed_notification_ids); - void send_add_group_update(const NotificationGroupKey &group_key, const NotificationGroup &group); + void send_add_group_update(const NotificationGroupKey &group_key, const NotificationGroup &group, const char *source); int32 get_notification_delay_ms(DialogId dialog_id, const PendingNotification ¬ification, int32 min_delay_ms) const; From 638b4346ca765c0088eb09fbbbea36c5ce834953 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 23 Jun 2022 17:05:43 +0300 Subject: [PATCH 05/38] Remove separate MessagesManager::on_update_scheduled_message_id. --- td/telegram/MessagesManager.cpp | 40 ++++++--------------------------- td/telegram/MessagesManager.h | 2 -- td/telegram/UpdatesManager.cpp | 26 +++++++++++---------- 3 files changed, 21 insertions(+), 47 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index ff5091b81..3756d2b25 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -28982,16 +28982,17 @@ void MessagesManager::on_imported_message_attachments_uploaded(int64 random_id, } bool MessagesManager::on_update_message_id(int64 random_id, MessageId new_message_id, const string &source) { - if (!new_message_id.is_valid() || !new_message_id.is_server()) { + if (!new_message_id.is_valid() && !new_message_id.is_valid_scheduled()) { LOG(ERROR) << "Receive " << new_message_id << " in updateMessageId with random_id " << random_id << " from " << source; return false; } + CHECK(new_message_id.is_any_server()); auto it = being_sent_messages_.find(random_id); if (it == being_sent_messages_.end()) { // update about a new message sent from other device or a service message - LOG(INFO) << "Receive not send outgoing " << new_message_id << " with random_id = " << random_id; + LOG(INFO) << "Receive not sent outgoing " << new_message_id << " with random_id = " << random_id; return true; } @@ -29007,38 +29008,11 @@ bool MessagesManager::on_update_message_id(int64 random_id, MessageId new_messag LOG(INFO) << "Save correspondence from " << new_message_id << " in " << dialog_id << " to " << old_message_id; CHECK(old_message_id.is_yet_unsent()); - update_message_ids_[FullMessageId(dialog_id, new_message_id)] = old_message_id; - return true; -} - -bool MessagesManager::on_update_scheduled_message_id(int64 random_id, ScheduledServerMessageId new_message_id, - const string &source) { - if (!new_message_id.is_valid()) { - LOG(ERROR) << "Receive " << new_message_id << " in updateMessageId with random_id " << random_id << " from " - << source; - return false; + if (new_message_id.is_scheduled()) { + update_scheduled_message_ids_[dialog_id][new_message_id.get_scheduled_server_message_id()] = old_message_id; + } else { + update_message_ids_[FullMessageId(dialog_id, new_message_id)] = old_message_id; } - - auto it = being_sent_messages_.find(random_id); - if (it == being_sent_messages_.end()) { - LOG(ERROR) << "Receive not send outgoing " << new_message_id << " with random_id = " << random_id; - return false; - } - - auto dialog_id = it->second.get_dialog_id(); - auto old_message_id = it->second.get_message_id(); - - being_sent_messages_.erase(it); - - if (!have_message_force({dialog_id, old_message_id}, "on_update_scheduled_message_id")) { - delete_sent_message_on_server(dialog_id, MessageId(new_message_id, std::numeric_limits::max()), - old_message_id); - return true; - } - - LOG(INFO) << "Save correspondence from " << new_message_id << " in " << dialog_id << " to " << old_message_id; - CHECK(old_message_id.is_yet_unsent()); - update_scheduled_message_ids_[dialog_id][new_message_id] = old_message_id; return true; } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 26c18fd87..004953d53 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -288,8 +288,6 @@ class MessagesManager final : public Actor { bool on_update_message_id(int64 random_id, MessageId new_message_id, const string &source); - bool on_update_scheduled_message_id(int64 random_id, ScheduledServerMessageId new_message_id, const string &source); - void on_update_dialog_draft_message(DialogId dialog_id, tl_object_ptr &&draft_message); void on_update_dialog_is_pinned(FolderId folder_id, DialogId dialog_id, bool is_pinned); diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 763aa057a..28adf34e7 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1796,16 +1796,20 @@ void UpdatesManager::on_pending_updates(vectorget_id(); - if (constructor_id == telegram_api::updateNewMessage::ID || - constructor_id == telegram_api::updateNewChannelMessage::ID) { - ordinary_new_message_count++; - } else if (constructor_id == telegram_api::updateNewScheduledMessage::ID) { - scheduled_new_message_count++; - } else if (constructor_id == telegram_api::updateMessageID::ID) { + if (constructor_id == telegram_api::updateMessageID::ID) { update_message_id_count++; + } else { + update_count++; + if (constructor_id == telegram_api::updateNewMessage::ID || + constructor_id == telegram_api::updateNewChannelMessage::ID) { + ordinary_new_message_count++; + } else if (constructor_id == telegram_api::updateNewScheduledMessage::ID) { + scheduled_new_message_count++; + } } } } @@ -1835,15 +1839,13 @@ void UpdatesManager::on_pending_updates(vector(update); - bool success = false; + MessageId message_id; if (ordinary_new_message_count != 0) { - success = td_->messages_manager_->on_update_message_id( - sent_message_update->random_id_, MessageId(ServerMessageId(sent_message_update->id_)), source); + message_id = MessageId(ServerMessageId(sent_message_update->id_)); } else if (scheduled_new_message_count != 0) { - success = td_->messages_manager_->on_update_scheduled_message_id( - sent_message_update->random_id_, ScheduledServerMessageId(sent_message_update->id_), source); + message_id = MessageId(ScheduledServerMessageId(sent_message_update->id_), std::numeric_limits::max()); } - if (!success) { + if (!td_->messages_manager_->on_update_message_id(sent_message_update->random_id_, message_id, source)) { for (auto &debug_update : updates) { LOG(ERROR) << "Update: " << oneline(to_string(debug_update)); } From d29d508b846465dfcb681dcc6b3fed2ee5f41502 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 23 Jun 2022 22:00:48 +0300 Subject: [PATCH 06/38] Avoid MultiPromise usage if there is only one update to process. --- td/telegram/UpdatesManager.cpp | 86 +++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 21 deletions(-) diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 28adf34e7..61138ceff 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -63,6 +63,7 @@ #include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/Random.h" +#include "td/utils/ScopeGuard.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" #include "td/utils/Status.h" @@ -1826,11 +1827,29 @@ void UpdatesManager::on_pending_updates(vector &&result) mutable { - send_closure(actor_id, &UpdatesManager::on_pending_updates_processed, std::move(result), std::move(promise)); - }); - auto lock = mpas.get_promise(); + Promise lock; + auto use_mpas = need_postpone || update_count != 1; + auto get_promise = [&] { + if (use_mpas) { + return mpas.get_promise(); + } else { + CHECK(update_count != 0); + update_count--; + return std::move(promise); + } + }; + if (use_mpas) { + being_processed_updates_++; + mpas.add_promise([actor_id = create_reference(), promise = std::move(promise)](Result &&result) mutable { + send_closure(actor_id, &UpdatesManager::on_pending_updates_processed, std::move(result), std::move(promise)); + }); + lock = get_promise(); + } + SCOPE_EXIT { + if (!use_mpas && update_count == 1) { + promise.set_value(Unit()); + } + }; for (auto &update : updates) { if (update != nullptr) { @@ -1853,11 +1872,11 @@ void UpdatesManager::on_pending_updates(vector(update), mpas.get_promise()); + on_update(move_tl_object_as(update), get_promise()); update = nullptr; } if (id == telegram_api::updateEncryption::ID) { - on_update(move_tl_object_as(update), mpas.get_promise()); + on_update(move_tl_object_as(update), get_promise()); update = nullptr; } CHECK(need_postpone || !running_get_difference_); @@ -1873,7 +1892,7 @@ void UpdatesManager::on_pending_updates(vector> Promise &&promise) { tl_object_ptr update_pts_changed; + int32 update_count = 0; + for (auto &update : updates) { + if (update != nullptr) { + update_count++; + } + } + MultiPromiseActorSafe mpas{"OnProcessUpdatesMultiPromiseActor"}; - mpas.add_promise(std::move(promise)); - auto lock = mpas.get_promise(); + Promise lock; + auto use_mpas = update_count != 1; + auto get_promise = [&] { + if (use_mpas) { + return mpas.get_promise(); + } else { + CHECK(update_count != 0); + update_count--; + return std::move(promise); + } + }; + if (use_mpas) { + mpas.add_promise(std::move(promise)); + lock = get_promise(); + } + SCOPE_EXIT { + if (!use_mpas && update_count == 1) { + promise.set_value(Unit()); + } + }; /* for (auto &update : updates) { @@ -2013,7 +2057,7 @@ void UpdatesManager::process_updates(vector> // process updateReadChannelInbox before updateNewChannelMessage auto constructor_id = update->get_id(); if (constructor_id == telegram_api::updateReadChannelInbox::ID) { - on_update(move_tl_object_as(update), mpas.get_promise()); + on_update(move_tl_object_as(update), get_promise()); } } } @@ -2023,19 +2067,19 @@ void UpdatesManager::process_updates(vector> // process updateNewChannelMessage first auto constructor_id = update->get_id(); if (constructor_id == telegram_api::updateNewChannelMessage::ID) { - on_update(move_tl_object_as(update), mpas.get_promise()); + on_update(move_tl_object_as(update), get_promise()); continue; } // process updateNewScheduledMessage first if (constructor_id == telegram_api::updateNewScheduledMessage::ID) { - on_update(move_tl_object_as(update), mpas.get_promise()); + on_update(move_tl_object_as(update), get_promise()); continue; } // updateGroupCallConnection must be processed before updateGroupCall if (constructor_id == telegram_api::updateGroupCallConnection::ID) { - on_update(move_tl_object_as(update), mpas.get_promise()); + on_update(move_tl_object_as(update), get_promise()); continue; } @@ -2065,7 +2109,7 @@ void UpdatesManager::process_updates(vector> process_pts_update(std::move(update)); } else if (is_qts_update(update.get())) { - process_qts_update(std::move(update), 0, mpas.get_promise()); + process_qts_update(std::move(update), 0, get_promise()); } else if (update->get_id() == telegram_api::updateChannelTooLong::ID) { td_->messages_manager_->on_update_channel_too_long( move_tl_object_as(update), true); @@ -2076,12 +2120,12 @@ void UpdatesManager::process_updates(vector> for (auto &update : updates) { if (update != nullptr) { LOG(INFO) << "Process update " << to_string(update); - downcast_call(*update, OnUpdate(this, update, mpas.get_promise())); + downcast_call(*update, OnUpdate(this, update, get_promise())); CHECK(!running_get_difference_); } } if (update_pts_changed != nullptr) { - on_update(std::move(update_pts_changed), mpas.get_promise()); + on_update(std::move(update_pts_changed), get_promise()); } lock.set_value(Unit()); } From c51f283332d750761fa3c729365959d4fa9ef80e Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 24 Jun 2022 13:44:54 +0300 Subject: [PATCH 07/38] Improve logging. --- td/telegram/MessagesManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 3756d2b25..11773e938 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -36695,7 +36695,7 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab << ", max_notification_message_id = " << d->max_notification_message_id; if (d->messages != nullptr) { - CHECK(d->messages->message_id == last_message_id); + LOG_CHECK(d->messages->message_id == last_message_id) << d->debug_set_dialog_last_database_message_id; CHECK(d->messages->left == nullptr); CHECK(d->messages->right == nullptr); } From e2acc0ddab5c498f86d1e61648f59b9add56a1dc Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 24 Jun 2022 14:27:49 +0300 Subject: [PATCH 08/38] Support 7 new filter icons. --- td/generate/scheme/td_api.tl | 4 ++-- td/telegram/DialogFilter.cpp | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index bd5642228..99c925a11 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -975,7 +975,7 @@ chatTypeSecret secret_chat_id:int32 user_id:int53 = ChatType; //@description Represents a filter of user chats //@title The title of the filter; 1-12 characters without line feeds -//@icon_name The chosen icon name for short filter representation. If non-empty, must be one of "All", "Unread", "Unmuted", "Bots", "Channels", "Groups", "Private", "Custom", "Setup", "Cat", "Crown", "Favorite", "Flower", "Game", "Home", "Love", "Mask", "Party", "Sport", "Study", "Trade", "Travel", "Work". +//@icon_name The chosen icon name for short filter representation. If non-empty, must be one of "All", "Unread", "Unmuted", "Bots", "Channels", "Groups", "Private", "Custom", "Setup", "Cat", "Crown", "Favorite", "Flower", "Game", "Home", "Love", "Mask", "Party", "Sport", "Study", "Trade", "Travel", "Work", "Airplane", "Book", "Light", "Like", "Money", "Note", "Palette". //-If empty, use getChatFilterDefaultIconName to get default icon name for the filter //@pinned_chat_ids The chat identifiers of pinned chats in the filtered chat list. There can be up to GetOption("chat_filter_chosen_chat_count_max") pinned and always included non-secret chats and the same number of secret chats, but the limit can be increased with Telegram Premium //@included_chat_ids The chat identifiers of always included chats in the filtered chat list. There can be up to GetOption("chat_filter_chosen_chat_count_max") pinned and always included non-secret chats and the same number of secret chats, but the limit can be increased with Telegram Premium @@ -993,7 +993,7 @@ chatFilter title:string icon_name:string pinned_chat_ids:vector included_ //@description Contains basic information about a chat filter //@id Unique chat filter identifier //@title The title of the filter; 1-12 characters without line feeds -//@icon_name The chosen or default icon name for short filter representation. One of "All", "Unread", "Unmuted", "Bots", "Channels", "Groups", "Private", "Custom", "Setup", "Cat", "Crown", "Favorite", "Flower", "Game", "Home", "Love", "Mask", "Party", "Sport", "Study", "Trade", "Travel", "Work" +//@icon_name The chosen or default icon name for short filter representation. One of "All", "Unread", "Unmuted", "Bots", "Channels", "Groups", "Private", "Custom", "Setup", "Cat", "Crown", "Favorite", "Flower", "Game", "Home", "Love", "Mask", "Party", "Sport", "Study", "Trade", "Travel", "Work", "Airplane", "Book", "Light", "Like", "Money", "Note", "Palette" chatFilterInfo id:int32 title:string icon_name:string = ChatFilterInfo; //@description Describes a recommended chat filter @filter The chat filter @param_description Chat filter description diff --git a/td/telegram/DialogFilter.cpp b/td/telegram/DialogFilter.cpp index cafa924ef..14e59ffbc 100644 --- a/td/telegram/DialogFilter.cpp +++ b/td/telegram/DialogFilter.cpp @@ -448,15 +448,20 @@ void DialogFilter::init_icon_names() { "\xF0\x9F\x8C\xB9", "\xF0\x9F\x8E\xAE", "\xF0\x9F\x8F\xA0", "\xE2\x9D\xA4\xEF\xB8\x8F", "\xF0\x9F\x8E\xAD", "\xF0\x9F\x8D\xB8", "\xE2\x9A\xBD\xEF\xB8\x8F", "\xF0\x9F\x8E\x93", "\xF0\x9F\x93\x88", - "\xE2\x9C\x88\xEF\xB8\x8F", "\xF0\x9F\x92\xBC"}; + "\xE2\x9C\x88\xEF\xB8\x8F", "\xF0\x9F\x92\xBC", "\xF0\x9F\x9B\xAB", + "\xF0\x9F\x93\x95", "\xF0\x9F\x92\xA1", "\xF0\x9F\x91\x8C", + "\xF0\x9F\x92\xB0", "\xF0\x9F\x8E\xB5", "\xF0\x9F\x8E\xA8"}; vector icon_names{"All", "Unread", "Unmuted", "Bots", "Channels", "Groups", "Private", "Custom", "Setup", "Cat", "Crown", "Favorite", "Flower", "Game", "Home", "Love", - "Mask", "Party", "Sport", "Study", "Trade", "Travel", "Work"}; + "Mask", "Party", "Sport", "Study", "Trade", "Travel", "Work", "Airplane", + "Book", "Light", "Like", "Money", "Note", "Palette"}; + CHECK(emojis.size() == icon_names.size()); for (size_t i = 0; i < emojis.size(); i++) { remove_emoji_modifiers_in_place(emojis[i]); - emoji_to_icon_name_[emojis[i]] = icon_names[i]; - icon_name_to_emoji_[icon_names[i]] = emojis[i]; + bool is_inserted = emoji_to_icon_name_.emplace(emojis[i], icon_names[i]).second && + icon_name_to_emoji_.emplace(icon_names[i], emojis[i]).second; + CHECK(is_inserted); } return true; }(); From c4690c9ed35026d8c3e4bea84e90a0c5977d6758 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 24 Jun 2022 14:59:02 +0300 Subject: [PATCH 09/38] Add more logging. --- td/telegram/MessagesManager.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 11773e938..6dc87147f 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -36695,9 +36695,15 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab << ", max_notification_message_id = " << d->max_notification_message_id; if (d->messages != nullptr) { - LOG_CHECK(d->messages->message_id == last_message_id) << d->debug_set_dialog_last_database_message_id; - CHECK(d->messages->left == nullptr); - CHECK(d->messages->right == nullptr); + LOG_CHECK(d->messages->message_id == last_message_id) + << d->messages->message_id << ' ' << last_message_id << ' ' << d->debug_set_dialog_last_database_message_id + << ' ' << d->messages->debug_source; + LOG_CHECK(d->messages->left == nullptr) + << d->messages->left->message_id << ' ' << d->messages->message_id << ' ' << last_message_id << ' ' + << d->debug_set_dialog_last_database_message_id << ' ' << d->messages->debug_source; + LOG_CHECK(d->messages->right == nullptr) + << d->messages->right->message_id << ' ' << d->messages->message_id << ' ' << last_message_id << ' ' + << d->debug_set_dialog_last_database_message_id << ' ' << d->messages->debug_source; } // must be after update_dialog_pos, because uses d->order From 7153a17bd78c17232f202303c493f7c51ab22f40 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 24 Jun 2022 14:59:42 +0300 Subject: [PATCH 10/38] Don't check full local locations after loading file from database. --- td/telegram/files/FileManager.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/td/telegram/files/FileManager.cpp b/td/telegram/files/FileManager.cpp index b44fbc628..bd352fed9 100644 --- a/td/telegram/files/FileManager.cpp +++ b/td/telegram/files/FileManager.cpp @@ -1177,8 +1177,9 @@ Result FileManager::register_file(FileData &&data, FileLocationSource fi bool has_remote = data.remote_.type() == RemoteFileLocation::Type::Full; bool has_generate = data.generate_ != nullptr; if (data.local_.type() == LocalFileLocation::Type::Full && !force) { - if (file_location_source == FileLocationSource::FromBinlog || - file_location_source == FileLocationSource::FromDatabase) { + bool is_from_database = file_location_source == FileLocationSource::FromBinlog || + file_location_source == FileLocationSource::FromDatabase; + if (is_from_database) { PathView path_view(data.local_.full().path_); if (path_view.is_relative()) { data.local_.full().path_ = PSTRING() @@ -1186,16 +1187,18 @@ Result FileManager::register_file(FileData &&data, FileLocationSource fi } } - auto status = check_local_location(data.local_.full(), data.size_, skip_file_size_checks); - if (status.is_error()) { - LOG(INFO) << "Invalid " << data.local_.full() << ": " << status << " from " << source; - data.local_ = LocalFileLocation(); - if (data.remote_.type() == RemoteFileLocation::Type::Partial) { - data.remote_ = {}; - } + if (!is_from_database) { + auto status = check_local_location(data.local_.full(), data.size_, skip_file_size_checks); + if (status.is_error()) { + LOG(INFO) << "Invalid " << data.local_.full() << ": " << status << " from " << source; + data.local_ = LocalFileLocation(); + if (data.remote_.type() == RemoteFileLocation::Type::Partial) { + data.remote_ = {}; + } - if (!has_remote && !has_generate) { - return std::move(status); + if (!has_remote && !has_generate) { + return std::move(status); + } } } } From 9e1374548760c3c031b622b70be29deb9e85991f Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 24 Jun 2022 17:07:10 +0300 Subject: [PATCH 11/38] Add td_api::canPurchasePremium. --- td/generate/scheme/td_api.tl | 3 +++ td/telegram/Premium.cpp | 33 +++++++++++++++++++++++++++++++++ td/telegram/Premium.h | 2 ++ td/telegram/Td.cpp | 6 ++++++ td/telegram/Td.h | 2 ++ td/telegram/cli.cpp | 2 ++ 6 files changed, 48 insertions(+) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 99c925a11..9f88e8828 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -6403,6 +6403,9 @@ clickPremiumSubscriptionButton = Ok; //@description Returns state of Telegram Premium subscription and promotion videos for Premium features getPremiumState = PremiumState; +//@description Checks whether Telegram Premium purchase is possible. Must be called before in-store Premium purchase +canPurchasePremium = Ok; + //@description Accepts Telegram terms of services @terms_of_service_id Terms of service identifier acceptTermsOfService terms_of_service_id:string = Ok; diff --git a/td/telegram/Premium.cpp b/td/telegram/Premium.cpp index 1a625aef6..bfc2fbd44 100644 --- a/td/telegram/Premium.cpp +++ b/td/telegram/Premium.cpp @@ -138,6 +138,35 @@ class GetPremiumPromoQuery final : public Td::ResultHandler { } }; +class CanPurchasePremiumQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit CanPurchasePremiumQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(telegram_api::payments_canPurchasePremium())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.ok(); + if (result) { + return promise_.set_value(Unit()); + } + on_error(Status::Error(400, "Premium can't be purchased")); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + const vector &get_premium_limit_keys() { static const vector limit_keys{"channels", "saved_gifs", @@ -377,4 +406,8 @@ void get_premium_state(Td *td, Promise> td->create_handler(std::move(promise))->send(); } +void can_purchase_premium(Td *td, Promise &&promise) { + td->create_handler(std::move(promise))->send(); +} + } // namespace td diff --git a/td/telegram/Premium.h b/td/telegram/Premium.h index 7519cb7d9..3500787b7 100644 --- a/td/telegram/Premium.h +++ b/td/telegram/Premium.h @@ -31,4 +31,6 @@ void click_premium_subscription_button(Td *td, Promise &&promise); void get_premium_state(Td *td, Promise> &&promise); +void can_purchase_premium(Td *td, Promise &&promise); + } // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index d4ac5914c..ffc9910c9 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7892,6 +7892,12 @@ void Td::on_request(uint64 id, const td_api::getPremiumState &request) { get_premium_state(this, std::move(promise)); } +void Td::on_request(uint64 id, const td_api::canPurchasePremium &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + can_purchase_premium(this, std::move(promise)); +} + void Td::on_request(uint64 id, td_api::acceptTermsOfService &request) { CHECK_IS_USER(); CLEAN_INPUT_STRING(request.terms_of_service_id_); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 497ffbdd0..518fcb1f4 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -1307,6 +1307,8 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::getPremiumState &request); + void on_request(uint64 id, const td_api::canPurchasePremium &request); + void on_request(uint64 id, td_api::acceptTermsOfService &request); void on_request(uint64 id, const td_api::getCountries &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index beaef8f03..8a9bf6323 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2572,6 +2572,8 @@ class CliClient final : public Actor { send_request(td_api::make_object()); } else if (op == "gprs") { send_request(td_api::make_object()); + } else if (op == "cppr") { + send_request(td_api::make_object()); } else if (op == "atos") { send_request(td_api::make_object(args)); } else if (op == "gdli") { From 44cf82614256c98045f4d546f3c4673183d93db7 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 24 Jun 2022 17:07:48 +0300 Subject: [PATCH 12/38] Fix Like filter icon. --- td/telegram/DialogFilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/td/telegram/DialogFilter.cpp b/td/telegram/DialogFilter.cpp index 14e59ffbc..87716feee 100644 --- a/td/telegram/DialogFilter.cpp +++ b/td/telegram/DialogFilter.cpp @@ -449,7 +449,7 @@ void DialogFilter::init_icon_names() { "\xE2\x9D\xA4\xEF\xB8\x8F", "\xF0\x9F\x8E\xAD", "\xF0\x9F\x8D\xB8", "\xE2\x9A\xBD\xEF\xB8\x8F", "\xF0\x9F\x8E\x93", "\xF0\x9F\x93\x88", "\xE2\x9C\x88\xEF\xB8\x8F", "\xF0\x9F\x92\xBC", "\xF0\x9F\x9B\xAB", - "\xF0\x9F\x93\x95", "\xF0\x9F\x92\xA1", "\xF0\x9F\x91\x8C", + "\xF0\x9F\x93\x95", "\xF0\x9F\x92\xA1", "\xF0\x9F\x91\x8D", "\xF0\x9F\x92\xB0", "\xF0\x9F\x8E\xB5", "\xF0\x9F\x8E\xA8"}; vector icon_names{"All", "Unread", "Unmuted", "Bots", "Channels", "Groups", "Private", "Custom", "Setup", "Cat", "Crown", "Favorite", "Flower", "Game", "Home", "Love", From 2144d8fcd0fef944eefb44668e268aeaa2695873 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 24 Jun 2022 17:27:03 +0300 Subject: [PATCH 13/38] Add td_api::assignGooglePlayTransaction. --- td/generate/scheme/td_api.tl | 3 +++ td/telegram/Premium.cpp | 32 ++++++++++++++++++++++++++++++++ td/telegram/Premium.h | 2 ++ td/telegram/Td.cpp | 7 +++++++ td/telegram/Td.h | 2 ++ 5 files changed, 46 insertions(+) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 9f88e8828..d3520c4cb 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -6406,6 +6406,9 @@ getPremiumState = PremiumState; //@description Checks whether Telegram Premium purchase is possible. Must be called before in-store Premium purchase canPurchasePremium = Ok; +//@description Informs server about a Telegram Premium purchase through Google Play. For official applications only @purchase_token Google Play purchase token +assignGooglePlayTransaction purchase_token:string = Ok; + //@description Accepts Telegram terms of services @terms_of_service_id Terms of service identifier acceptTermsOfService terms_of_service_id:string = Ok; diff --git a/td/telegram/Premium.cpp b/td/telegram/Premium.cpp index bfc2fbd44..b6eb8ca64 100644 --- a/td/telegram/Premium.cpp +++ b/td/telegram/Premium.cpp @@ -17,6 +17,7 @@ #include "td/telegram/MessageEntity.h" #include "td/telegram/Td.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/UpdatesManager.h" #include "td/utils/algorithm.h" #include "td/utils/buffer.h" @@ -167,6 +168,33 @@ class CanPurchasePremiumQuery final : public Td::ResultHandler { } }; +class AssignPlayMarketTransactionQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit AssignPlayMarketTransactionQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const string &purchase_token) { + send_query(G()->net_query_creator().create(telegram_api::payments_assignPlayMarketTransaction(purchase_token))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for AssignPlayMarketTransactionQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + const vector &get_premium_limit_keys() { static const vector limit_keys{"channels", "saved_gifs", @@ -410,4 +438,8 @@ void can_purchase_premium(Td *td, Promise &&promise) { td->create_handler(std::move(promise))->send(); } +void assign_play_market_transaction(Td *td, const string &purchase_token, Promise &&promise) { + td->create_handler(std::move(promise))->send(purchase_token); +} + } // namespace td diff --git a/td/telegram/Premium.h b/td/telegram/Premium.h index 3500787b7..84a8a8b2f 100644 --- a/td/telegram/Premium.h +++ b/td/telegram/Premium.h @@ -33,4 +33,6 @@ void get_premium_state(Td *td, Promise> void can_purchase_premium(Td *td, Promise &&promise); +void assign_play_market_transaction(Td *td, const string &purchase_token, Promise &&promise); + } // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index ffc9910c9..60daf1db8 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7898,6 +7898,13 @@ void Td::on_request(uint64 id, const td_api::canPurchasePremium &request) { can_purchase_premium(this, std::move(promise)); } +void Td::on_request(uint64 id, td_api::assignGooglePlayTransaction &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.purchase_token_); + CREATE_OK_REQUEST_PROMISE(); + assign_play_market_transaction(this, request.purchase_token_, std::move(promise)); +} + void Td::on_request(uint64 id, td_api::acceptTermsOfService &request) { CHECK_IS_USER(); CLEAN_INPUT_STRING(request.terms_of_service_id_); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 518fcb1f4..7c59766d1 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -1309,6 +1309,8 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::canPurchasePremium &request); + void on_request(uint64 id, td_api::assignGooglePlayTransaction &request); + void on_request(uint64 id, td_api::acceptTermsOfService &request); void on_request(uint64 id, const td_api::getCountries &request); From e0605b20135d06d7a0b149c4ab0f0c060049bc9c Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 24 Jun 2022 18:14:00 +0300 Subject: [PATCH 14/38] Add td_api::assignAppStoreTransaction. --- td/generate/scheme/td_api.tl | 3 +++ td/telegram/Premium.cpp | 36 ++++++++++++++++++++++++++++++++++++ td/telegram/Premium.h | 2 ++ td/telegram/Td.cpp | 6 ++++++ td/telegram/Td.h | 2 ++ 5 files changed, 49 insertions(+) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index d3520c4cb..17ebb5280 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -6406,6 +6406,9 @@ getPremiumState = PremiumState; //@description Checks whether Telegram Premium purchase is possible. Must be called before in-store Premium purchase canPurchasePremium = Ok; +//@description Informs server about a Telegram Premium purchase through App Store. For official applications only @receipt App Store receipt @is_restore True, if this is restore of Premium purchase +assignAppStoreTransaction receipt:bytes is_restore:Bool = Ok; + //@description Informs server about a Telegram Premium purchase through Google Play. For official applications only @purchase_token Google Play purchase token assignGooglePlayTransaction purchase_token:string = Ok; diff --git a/td/telegram/Premium.cpp b/td/telegram/Premium.cpp index b6eb8ca64..56b44c69d 100644 --- a/td/telegram/Premium.cpp +++ b/td/telegram/Premium.cpp @@ -168,6 +168,38 @@ class CanPurchasePremiumQuery final : public Td::ResultHandler { } }; +class AssignAppStoreTransactionQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit AssignAppStoreTransactionQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const string &receipt, bool is_restore) { + int32 flags = 0; + if (is_restore) { + flags |= telegram_api::payments_assignAppStoreTransaction::RESTORE_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::payments_assignAppStoreTransaction(flags, false /*ignored*/, BufferSlice(receipt)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for AssignAppStoreTransactionQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + class AssignPlayMarketTransactionQuery final : public Td::ResultHandler { Promise promise_; @@ -438,6 +470,10 @@ void can_purchase_premium(Td *td, Promise &&promise) { td->create_handler(std::move(promise))->send(); } +void assign_app_store_transaction(Td *td, const string &receipt, bool is_restore, Promise &&promise) { + td->create_handler(std::move(promise))->send(receipt, is_restore); +} + void assign_play_market_transaction(Td *td, const string &purchase_token, Promise &&promise) { td->create_handler(std::move(promise))->send(purchase_token); } diff --git a/td/telegram/Premium.h b/td/telegram/Premium.h index 84a8a8b2f..9e5dfa9f2 100644 --- a/td/telegram/Premium.h +++ b/td/telegram/Premium.h @@ -33,6 +33,8 @@ void get_premium_state(Td *td, Promise> void can_purchase_premium(Td *td, Promise &&promise); +void assign_app_store_transaction(Td *td, const string &receipt, bool is_restore, Promise &&promise); + void assign_play_market_transaction(Td *td, const string &purchase_token, Promise &&promise); } // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 60daf1db8..836d2fbc8 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7898,6 +7898,12 @@ void Td::on_request(uint64 id, const td_api::canPurchasePremium &request) { can_purchase_premium(this, std::move(promise)); } +void Td::on_request(uint64 id, const td_api::assignAppStoreTransaction &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + assign_app_store_transaction(this, request.receipt_, request.is_restore_, std::move(promise)); +} + void Td::on_request(uint64 id, td_api::assignGooglePlayTransaction &request) { CHECK_IS_USER(); CLEAN_INPUT_STRING(request.purchase_token_); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 7c59766d1..0e4c33ef4 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -1309,6 +1309,8 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::canPurchasePremium &request); + void on_request(uint64 id, const td_api::assignAppStoreTransaction &request); + void on_request(uint64 id, td_api::assignGooglePlayTransaction &request); void on_request(uint64 id, td_api::acceptTermsOfService &request); From b97bd4848b191a5bb3bd976cb732bbf4911bb844 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 24 Jun 2022 19:00:29 +0300 Subject: [PATCH 15/38] Allow to inline BufferAllocator::track_buffer_slice. --- tdutils/td/utils/buffer.cpp | 3 --- tdutils/td/utils/buffer.h | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tdutils/td/utils/buffer.cpp b/tdutils/td/utils/buffer.cpp index f4ae97f95..f767e23ae 100644 --- a/tdutils/td/utils/buffer.cpp +++ b/tdutils/td/utils/buffer.cpp @@ -29,9 +29,6 @@ int64 BufferAllocator::get_buffer_slice_size() { return 0; } -void BufferAllocator::track_buffer_slice(int64 size) { -} - size_t BufferAllocator::get_buffer_mem() { return buffer_mem; } diff --git a/tdutils/td/utils/buffer.h b/tdutils/td/utils/buffer.h index 46ae24963..ec81c85ad 100644 --- a/tdutils/td/utils/buffer.h +++ b/tdutils/td/utils/buffer.h @@ -74,7 +74,8 @@ class BufferAllocator { private: friend class BufferSlice; - static void track_buffer_slice(int64 size); + static void track_buffer_slice(int64 size) { + } static ReaderPtr create_reader_fast(size_t size); From 08e60886f7bab8d1a8356960a63f319f8a860bb4 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 25 Jun 2022 09:26:30 +0300 Subject: [PATCH 16/38] Fix promise set in updates proxessing. --- td/telegram/UpdatesManager.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 61138ceff..0146ce6b8 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1921,6 +1921,7 @@ void UpdatesManager::on_pending_updates(vector result, Promise promise) { From 63d5a1f32a5cc06e7bc1495c06652e8cada9b29e Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 25 Jun 2022 21:15:03 +0300 Subject: [PATCH 17/38] Fix check. --- td/telegram/UpdatesManager.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 0146ce6b8..ba81f2d79 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1921,7 +1921,11 @@ void UpdatesManager::on_pending_updates(vector Date: Sat, 25 Jun 2022 21:22:02 +0300 Subject: [PATCH 18/38] Improve log messages. --- td/telegram/MessagesManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 6dc87147f..2caca46c7 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -37139,7 +37139,7 @@ void MessagesManager::update_dialog_lists( if (total_count != -1) { total_count += delta; if (total_count < 0) { - LOG(ERROR) << "Total chat count became negative after leaving " << dialog_id; + LOG(ERROR) << "Total chat count in " << dialog_list_id << " became negative after removing " << dialog_id; total_count = 0; } } @@ -37149,7 +37149,7 @@ void MessagesManager::update_dialog_lists( need_update_unread_chat_count = list.is_dialog_unread_count_inited_ && old_position.total_dialog_count != get_dialog_total_count(list); auto unread_count = d->server_unread_count + d->local_unread_count; - const char *change_source = was_in_list ? "on_dialog_leave" : "on_dialog_join"; + const char *change_source = was_in_list ? "on_dialog_remove" : "on_dialog_add"; if (unread_count != 0 && list.is_message_unread_count_inited_) { unread_count *= delta; From f62632fcbc9d2ac753fd355bafefd812867fe2ee Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 26 Jun 2022 17:11:27 +0300 Subject: [PATCH 19/38] Remove rarely used PromiseCreator::lambda with 2 lambdas. --- td/telegram/AuthManager.cpp | 22 ++++++++++------ td/telegram/DialogDb.cpp | 4 +-- td/telegram/MessagesDb.cpp | 5 ++-- td/telegram/MessagesManager.cpp | 44 ++++++++++++++++---------------- td/telegram/SecretChatActor.cpp | 8 +++--- tdactor/td/actor/PromiseFuture.h | 6 ----- 6 files changed, 46 insertions(+), 43 deletions(-) diff --git a/td/telegram/AuthManager.cpp b/td/telegram/AuthManager.cpp index fb34fb4dd..861afc1ec 100644 --- a/td/telegram/AuthManager.cpp +++ b/td/telegram/AuthManager.cpp @@ -77,8 +77,11 @@ void AuthManager::start_up() { if (state_ == State::LoggingOut) { send_log_out_query(); } else if (state_ == State::DestroyingKeys) { - G()->net_query_dispatcher().destroy_auth_keys( - PromiseCreator::lambda([](Unit) { send_closure_later(G()->td(), &Td::destroy); }, PromiseCreator::Ignore())); + G()->net_query_dispatcher().destroy_auth_keys(PromiseCreator::lambda([](Result result) { + if (result.is_ok()) { + send_closure_later(G()->td(), &Td::destroy); + } + })); } } void AuthManager::tear_down() { @@ -706,12 +709,15 @@ void AuthManager::destroy_auth_keys() { return; } update_state(State::DestroyingKeys); - auto promise = PromiseCreator::lambda( - [](Unit) { - G()->net_query_dispatcher().destroy_auth_keys(PromiseCreator::lambda( - [](Unit) { send_closure_later(G()->td(), &Td::destroy); }, PromiseCreator::Ignore())); - }, - PromiseCreator::Ignore()); + auto promise = PromiseCreator::lambda([](Result result) { + if (result.is_ok()) { + G()->net_query_dispatcher().destroy_auth_keys(PromiseCreator::lambda([](Result result) { + if (result.is_ok()) { + send_closure_later(G()->td(), &Td::destroy); + } + })); + } + }); G()->td_db()->get_binlog_pmc()->set("auth", "destroy"); G()->td_db()->get_binlog_pmc()->force_sync(std::move(promise)); } diff --git a/td/telegram/DialogDb.cpp b/td/telegram/DialogDb.cpp index e63475c65..e55c5b378 100644 --- a/td/telegram/DialogDb.cpp +++ b/td/telegram/DialogDb.cpp @@ -443,12 +443,12 @@ class DialogDbAsync final : public DialogDbAsyncInterface { //NB: order is important, destructor of pending_writes_ will change pending_write_results_ std::vector, Status>> pending_write_results_; - vector> pending_writes_; + vector> pending_writes_; // TODO use Action double wakeup_at_ = 0; template void add_write_query(F &&f) { - pending_writes_.push_back(PromiseCreator::lambda(std::forward(f), PromiseCreator::Ignore())); + pending_writes_.push_back(PromiseCreator::lambda(std::forward(f))); if (pending_writes_.size() > MAX_PENDING_QUERIES_COUNT) { do_flush(); wakeup_at_ = 0; diff --git a/td/telegram/MessagesDb.cpp b/td/telegram/MessagesDb.cpp index 9660492ff..187a1e7ba 100644 --- a/td/telegram/MessagesDb.cpp +++ b/td/telegram/MessagesDb.cpp @@ -1216,11 +1216,12 @@ class MessagesDbAsync final : public MessagesDbAsyncInterface { //NB: order is important, destructor of pending_writes_ will change pending_write_results_ vector, Status>> pending_write_results_; - vector> pending_writes_; + vector> pending_writes_; // TODO use Action double wakeup_at_ = 0; + template void add_write_query(F &&f) { - pending_writes_.push_back(PromiseCreator::lambda(std::forward(f), PromiseCreator::Ignore())); + pending_writes_.push_back(PromiseCreator::lambda(std::forward(f))); if (pending_writes_.size() > MAX_PENDING_QUERIES_COUNT) { do_flush(); wakeup_at_ = 0; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 2caca46c7..4a691047b 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -3212,11 +3212,11 @@ class SendMessageQuery final : public Td::ResultHandler { {{dialog_id, MessageContentType::Text}, {dialog_id, is_copy ? MessageContentType::Photo : MessageContentType::Text}}); if (G()->shared_config().get_option_boolean("use_quick_ack")) { - query->quick_ack_promise_ = PromiseCreator::lambda( - [random_id](Unit) { - send_closure(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id); - }, - PromiseCreator::Ignore()); + query->quick_ack_promise_ = PromiseCreator::lambda([random_id](Result result) { + if (result.is_ok()) { + send_closure(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id); + } + }); } *send_query_ref = query.get_weak(); send_query(std::move(query)); @@ -3283,11 +3283,11 @@ class StartBotQuery final : public Td::ResultHandler { telegram_api::messages_startBot(std::move(bot_input_user), std::move(input_peer), random_id, parameter), {{dialog_id, MessageContentType::Text}, {dialog_id, MessageContentType::Photo}}); if (G()->shared_config().get_option_boolean("use_quick_ack")) { - query->quick_ack_promise_ = PromiseCreator::lambda( - [random_id](Unit) { - send_closure(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id); - }, - PromiseCreator::Ignore()); + query->quick_ack_promise_ = PromiseCreator::lambda([random_id](Result result) { + if (result.is_ok()) { + send_closure(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id); + } + }); } auto send_query_ref = query.get_weak(); send_query(std::move(query)); @@ -3525,11 +3525,11 @@ class SendMediaQuery final : public Td::ResultHandler { std::move(reply_markup), std::move(entities), schedule_date, std::move(as_input_peer)), {{dialog_id, content_type}, {dialog_id, is_copy ? MessageContentType::Text : content_type}}); if (G()->shared_config().get_option_boolean("use_quick_ack") && was_uploaded_) { - query->quick_ack_promise_ = PromiseCreator::lambda( - [random_id](Unit) { - send_closure(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id); - }, - PromiseCreator::Ignore()); + query->quick_ack_promise_ = PromiseCreator::lambda([random_id](Result result) { + if (result.is_ok()) { + send_closure(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id); + } + }); } *send_query_ref = query.get_weak(); send_query(std::move(query)); @@ -3889,13 +3889,13 @@ class ForwardMessagesQuery final : public Td::ResultHandler { std::move(random_ids), std::move(to_input_peer), schedule_date, std::move(as_input_peer)), {{to_dialog_id, MessageContentType::Text}, {to_dialog_id, MessageContentType::Photo}}); if (G()->shared_config().get_option_boolean("use_quick_ack")) { - query->quick_ack_promise_ = PromiseCreator::lambda( - [random_ids = random_ids_](Unit) { - for (auto random_id : random_ids) { - send_closure(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id); - } - }, - PromiseCreator::Ignore()); + query->quick_ack_promise_ = PromiseCreator::lambda([random_ids = random_ids_](Result result) { + if (result.is_ok()) { + for (auto random_id : random_ids) { + send_closure(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id); + } + } + }); } send_query(std::move(query)); } diff --git a/td/telegram/SecretChatActor.cpp b/td/telegram/SecretChatActor.cpp index f5e65d9f3..21d145453 100644 --- a/td/telegram/SecretChatActor.cpp +++ b/td/telegram/SecretChatActor.cpp @@ -1436,9 +1436,11 @@ NetQueryPtr SecretChatActor::create_net_query(const log_event::OutboundSecretMes } if (message.is_external && context_->get_config_option_boolean("use_quick_ack")) { query->quick_ack_promise_ = - PromiseCreator::lambda([actor_id = actor_id(this), random_id = message.random_id]( - Unit) { send_closure(actor_id, &SecretChatActor::on_send_message_ack, random_id); }, - PromiseCreator::Ignore()); + PromiseCreator::lambda([actor_id = actor_id(this), random_id = message.random_id](Result result) { + if (result.is_ok()) { + send_closure(actor_id, &SecretChatActor::on_send_message_ack, random_id); + } + }); } return query; diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index 3e8b355cd..e03738cc2 100644 --- a/tdactor/td/actor/PromiseFuture.h +++ b/tdactor/td/actor/PromiseFuture.h @@ -692,12 +692,6 @@ class PromiseCreator { return Promise(td::make_unique>>(std::forward(ok))); } - template > - static Promise lambda(OkT &&ok, FailT &&fail) { - return Promise(td::make_unique, std::decay_t>>( - std::forward(ok), std::forward(fail), false)); - } - template >> static auto cancellable_lambda(CancellationToken cancellation_token, OkT &&ok) { return Promise(td::make_unique>>>( From 4b9990aff9bda8f36201872c8a64d18da616ddec Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 26 Jun 2022 22:31:28 +0300 Subject: [PATCH 20/38] Simplify LambdaPromise implementation. --- tdactor/td/actor/PromiseFuture.h | 71 ++++++++++---------------------- 1 file changed, 22 insertions(+), 49 deletions(-) diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index e03738cc2..157381311 100644 --- a/tdactor/td/actor/PromiseFuture.h +++ b/tdactor/td/actor/PromiseFuture.h @@ -12,6 +12,7 @@ #include "td/utils/Closure.h" #include "td/utils/common.h" #include "td/utils/invoke.h" +#include "td/utils/logging.h" #include "td/utils/MovableValue.h" #include "td/utils/ScopeGuard.h" #include "td/utils/Status.h" @@ -104,76 +105,48 @@ struct Ignore { } }; -template +template class LambdaPromise : public PromiseInterface { - enum class OnFail { None, Ok, Fail }; + enum class State : int32 { Empty, Ready, Complete }; public: void set_value(ValueT &&value) override { - CHECK(has_lambda_.get()); - do_ok(ok_, std::move(value)); - on_fail_ = OnFail::None; + CHECK(state_.get() == State::Ready); + func_(std::move(value)); + state_ = State::Complete; } + void set_error(Status &&error) override { - CHECK(has_lambda_.get()); - do_error(std::move(error)); + if (state_.get() == State::Ready) { + do_error(std::move(error)); + state_ = State::Complete; + } } LambdaPromise(const LambdaPromise &other) = delete; LambdaPromise &operator=(const LambdaPromise &other) = delete; LambdaPromise(LambdaPromise &&other) = default; LambdaPromise &operator=(LambdaPromise &&other) = default; ~LambdaPromise() override { - if (has_lambda_.get()) { + if (state_.get() == State::Ready) { do_error(Status::Error("Lost promise")); } } - template - LambdaPromise(FromOkT &&ok, FromFailT &&fail, bool use_ok_as_fail) - : ok_(std::forward(ok)) - , fail_(std::forward(fail)) - , on_fail_(use_ok_as_fail ? OnFail::Ok : OnFail::Fail) - , has_lambda_(true) { - } - template , LambdaPromise>::value, int> = 0> - LambdaPromise(FromOkT &&ok) : LambdaPromise(std::forward(ok), Ignore(), true) { + template + explicit LambdaPromise(FromT &&func) : func_(std::forward(func)), state_(State::Ready) { } private: - FunctionOkT ok_; - FunctionFailT fail_; - OnFail on_fail_ = OnFail::None; - MovableValue has_lambda_{false}; + FunctionT func_; + MovableValue state_{State::Empty}; - void do_error(Status &&error) { - switch (on_fail_) { - case OnFail::None: - break; - case OnFail::Ok: - do_error(ok_, std::move(error)); - break; - case OnFail::Fail: - do_error(fail_, std::move(error)); - break; - } - on_fail_ = OnFail::None; + template + std::enable_if_t>::value, void> do_error(Status &&status) { + func_(Result(std::move(status))); } - - template - std::enable_if_t>::value, void> do_error(F &&f, Status &&status) { - f(Result(std::move(status))); - } - template - std::enable_if_t>::value, void> do_error(F &&f, Y &&status) { - f(Auto()); - } - template - std::enable_if_t>::value, void> do_ok(F &&f, ValueT &&result) { - f(Result(std::move(result))); - } - template - std::enable_if_t>::value, void> do_ok(F &&f, ValueT &&result) { - f(std::move(result)); + template + std::enable_if_t>::value, void> do_error(Y &&status) { + func_(Auto()); } }; } // namespace detail From aa97336963aea7e34e21c6fc2e5abfeed9246088 Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 26 Jun 2022 22:41:57 +0300 Subject: [PATCH 21/38] Remove unused class Ignore. --- tdactor/td/actor/PromiseFuture.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index 157381311..c27de952b 100644 --- a/tdactor/td/actor/PromiseFuture.h +++ b/tdactor/td/actor/PromiseFuture.h @@ -99,12 +99,6 @@ struct DropResult> { template using drop_result_t = typename DropResult::type; -struct Ignore { - void operator()(Status &&error) { - error.ignore(); - } -}; - template class LambdaPromise : public PromiseInterface { enum class State : int32 { Empty, Ready, Complete }; @@ -658,8 +652,6 @@ FutureActor send_promise(ActorId actor_id, ResultT (ActorBT::*func)( class PromiseCreator { public: - using Ignore = detail::Ignore; - template >> static Promise lambda(OkT &&ok) { return Promise(td::make_unique>>(std::forward(ok))); From 513da45a8f375aa190b77e27430d77a3670ba8c6 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 27 Jun 2022 02:57:56 +0300 Subject: [PATCH 22/38] Use free-standing function to create event promises. --- td/telegram/DeviceTokenManager.cpp | 2 +- td/telegram/StateManager.cpp | 2 +- td/telegram/TopDialogManager.cpp | 2 +- td/telegram/UpdatesManager.cpp | 6 +++--- tdactor/td/actor/PromiseFuture.h | 16 ++++++++-------- test/tdclient.cpp | 24 ++++++++++++------------ 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/td/telegram/DeviceTokenManager.cpp b/td/telegram/DeviceTokenManager.cpp index fc9b3e7b6..d7d935d61 100644 --- a/td/telegram/DeviceTokenManager.cpp +++ b/td/telegram/DeviceTokenManager.cpp @@ -364,7 +364,7 @@ void DeviceTokenManager::save_info(int32 token_type) { } sync_cnt_++; G()->td_db()->get_binlog_pmc()->force_sync( - PromiseCreator::event(self_closure(this, &DeviceTokenManager::dec_sync_cnt))); + create_event_promise(self_closure(this, &DeviceTokenManager::dec_sync_cnt))); } void DeviceTokenManager::dec_sync_cnt() { diff --git a/td/telegram/StateManager.cpp b/td/telegram/StateManager.cpp index 2dc618895..b967a25c6 100644 --- a/td/telegram/StateManager.cpp +++ b/td/telegram/StateManager.cpp @@ -128,7 +128,7 @@ void StateManager::on_network_soft() { } void StateManager::start_up() { - create_actor("SleepActor", 1, PromiseCreator::event(self_closure(this, &StateManager::on_network_soft))) + create_actor("SleepActor", 1, create_event_promise(self_closure(this, &StateManager::on_network_soft))) .release(); loop(); } diff --git a/td/telegram/TopDialogManager.cpp b/td/telegram/TopDialogManager.cpp index 3b43a9e17..52aabc622 100644 --- a/td/telegram/TopDialogManager.cpp +++ b/td/telegram/TopDialogManager.cpp @@ -587,7 +587,7 @@ void TopDialogManager::try_start() { db_sync_state_ = SyncState::Ok; send_closure(G()->state_manager(), &StateManager::wait_first_sync, - PromiseCreator::event(self_closure(this, &TopDialogManager::on_first_sync))); + create_event_promise(self_closure(this, &TopDialogManager::on_first_sync))); } void TopDialogManager::on_first_sync() { diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index ba81f2d79..0f9279ba1 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -372,12 +372,12 @@ void UpdatesManager::before_get_difference(bool is_initial) { Promise<> UpdatesManager::add_pts(int32 pts) { auto id = pts_manager_.add_pts(pts); - return PromiseCreator::event(self_closure(this, &UpdatesManager::on_pts_ack, id)); + return create_event_promise(self_closure(this, &UpdatesManager::on_pts_ack, id)); } Promise<> UpdatesManager::add_qts(int32 qts) { auto id = qts_manager_.add_pts(qts); - return PromiseCreator::event(self_closure(this, &UpdatesManager::on_qts_ack, id)); + return create_event_promise(self_closure(this, &UpdatesManager::on_qts_ack, id)); } void UpdatesManager::on_pts_ack(PtsManager::PtsId ack_token) { @@ -1923,7 +1923,7 @@ void UpdatesManager::on_pending_updates(vector { }; } // namespace detail +inline Promise create_event_promise(EventFull &&ok) { + return Promise(td::make_unique(std::move(ok))); +} + +inline Promise create_event_promise(EventFull ok, EventFull fail) { + return Promise(td::make_unique(std::move(ok), std::move(fail))); +} + class SendClosure { public: template @@ -663,14 +671,6 @@ class PromiseCreator { std::move(cancellation_token), std::forward(ok))); } - static Promise<> event(EventFull &&ok) { - return Promise<>(td::make_unique(std::move(ok))); - } - - static Promise<> event(EventFull ok, EventFull fail) { - return Promise<>(td::make_unique(std::move(ok), std::move(fail))); - } - template static Promise<> join(ArgsT &&...args) { return Promise<>(td::make_unique>(std::forward(args)...)); diff --git a/test/tdclient.cpp b/test/tdclient.cpp index cc7a0dae3..3a00549d6 100644 --- a/test/tdclient.cpp +++ b/test/tdclient.cpp @@ -691,12 +691,12 @@ class LoginTestActor final : public td::Actor { td::send_closure(alice_, &TestClient::add_listener, td::make_unique( "alice", alice_phone_, "33333", - td::PromiseCreator::event(self_closure(this, &LoginTestActor::start_up_fence_dec)))); + td::create_event_promise(self_closure(this, &LoginTestActor::start_up_fence_dec)))); td::send_closure(bob_, &TestClient::add_listener, td::make_unique( "bob", bob_phone_, "33333", - td::PromiseCreator::event(self_closure(this, &LoginTestActor::start_up_fence_dec)))); + td::create_event_promise(self_closure(this, &LoginTestActor::start_up_fence_dec)))); } int start_up_fence_ = 3; @@ -722,18 +722,18 @@ class LoginTestActor final : public td::Actor { td::Promise<> promise_; }; td::create_actor("WaitActor", 2, - td::PromiseCreator::event(self_closure(this, &LoginTestActor::start_up_fence_dec))) + td::create_event_promise(self_closure(this, &LoginTestActor::start_up_fence_dec))) .release(); } } void init() { td::send_closure(alice_, &TestClient::add_listener, - td::make_unique(alice_username_, td::PromiseCreator::event(self_closure( + td::make_unique(alice_username_, td::create_event_promise(self_closure( this, &LoginTestActor::init_fence_dec)))); td::send_closure(bob_, &TestClient::add_listener, - td::make_unique(bob_username_, td::PromiseCreator::event(self_closure( - this, &LoginTestActor::init_fence_dec)))); + td::make_unique( + bob_username_, td::create_event_promise(self_closure(this, &LoginTestActor::init_fence_dec)))); } int init_fence_ = 2; @@ -757,10 +757,10 @@ class LoginTestActor final : public td::Actor { td::send_closure(bob_, &TestClient::add_listener, td::make_unique( - alice_tag, td::PromiseCreator::event(self_closure(this, &LoginTestActor::test_a_fence)))); + alice_tag, td::create_event_promise(self_closure(this, &LoginTestActor::test_a_fence)))); td::send_closure(alice_, &TestClient::add_listener, td::make_unique( - bob_tag, td::PromiseCreator::event(self_closure(this, &LoginTestActor::test_a_fence)))); + bob_tag, td::create_event_promise(self_closure(this, &LoginTestActor::test_a_fence)))); td::send_closure(alice_, &TestClient::add_listener, td::make_unique(alice_tag, bob_username_)); td::send_closure(bob_, &TestClient::add_listener, td::make_unique(bob_tag, alice_username_)); @@ -791,7 +791,7 @@ class LoginTestActor final : public td::Actor { td::send_closure( bob_, &TestClient::add_listener, - td::make_unique(tag, td::PromiseCreator::event(self_closure(this, &LoginTestActor::test_b_fence)))); + td::make_unique(tag, td::create_event_promise(self_closure(this, &LoginTestActor::test_b_fence)))); td::send_closure(alice_, &TestClient::add_listener, td::make_unique(tag, bob_username_)); } @@ -802,7 +802,7 @@ class LoginTestActor final : public td::Actor { td::send_closure( bob_, &TestClient::add_listener, td::make_unique(alice_username_, tag, - td::PromiseCreator::event(self_closure(this, &LoginTestActor::test_c_fence)))); + td::create_event_promise(self_closure(this, &LoginTestActor::test_c_fence)))); td::send_closure(alice_, &TestClient::add_listener, td::make_unique(tag, bob_username_)); } @@ -817,9 +817,9 @@ class LoginTestActor final : public td::Actor { void finish() { td::send_closure(alice_, &TestClient::close, - td::PromiseCreator::event(self_closure(this, &LoginTestActor::finish_fence))); + td::create_event_promise(self_closure(this, &LoginTestActor::finish_fence))); td::send_closure(bob_, &TestClient::close, - td::PromiseCreator::event(self_closure(this, &LoginTestActor::finish_fence))); + td::create_event_promise(self_closure(this, &LoginTestActor::finish_fence))); } }; From cb694ab649352f81431e1e18d1fec1aaaf623d34 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 27 Jun 2022 03:05:24 +0300 Subject: [PATCH 23/38] Remove unused ability of Promise to migrate between schedulers. --- tdactor/td/actor/PromiseFuture.h | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index 04b0509ed..8f0310bfe 100644 --- a/tdactor/td/actor/PromiseFuture.h +++ b/tdactor/td/actor/PromiseFuture.h @@ -60,11 +60,6 @@ class PromiseInterface { virtual bool is_canceled() const { return false; } - - virtual void start_migrate(int32 sched_id) { - } - virtual void finish_migrate() { - } }; namespace detail { @@ -236,18 +231,6 @@ class Promise { void reset() { promise_.reset(); } - void start_migrate(int32 sched_id) { - if (!promise_) { - return; - } - promise_->start_migrate(sched_id); - } - void finish_migrate() { - if (!promise_) { - return; - } - promise_->finish_migrate(); - } bool is_cancellable() const { if (!promise_) { return false; @@ -283,14 +266,6 @@ class Promise { unique_ptr> promise_; }; -template -void start_migrate(Promise &promise, int32 sched_id) { - // promise.start_migrate(sched_id); -} -template -void finish_migrate(Promise &promise) { - // promise.finish_migrate(); -} template class SafePromise { From da2e504566d5f8397c4eef573f4e4931ca6a9bef Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 27 Jun 2022 03:59:23 +0300 Subject: [PATCH 24/38] Remove Promise operators. --- tdactor/td/actor/PromiseFuture.h | 19 ++----------------- test/online.cpp | 2 +- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index 8f0310bfe..fb81bced1 100644 --- a/tdactor/td/actor/PromiseFuture.h +++ b/tdactor/td/actor/PromiseFuture.h @@ -32,6 +32,7 @@ class PromiseInterface { PromiseInterface(PromiseInterface &&) = default; PromiseInterface &operator=(PromiseInterface &&) = default; virtual ~PromiseInterface() = default; + virtual void set_value(T &&value) { set_result(std::move(value)); } @@ -45,15 +46,7 @@ class PromiseInterface { set_error(result.move_as_error()); } } - void operator()(T &&value) { - set_value(std::move(value)); - } - void operator()(Status &&error) { - set_error(std::move(error)); - } - void operator()(Result &&result) { - set_result(std::move(result)); - } + virtual bool is_cancellable() const { return false; } @@ -220,14 +213,6 @@ class Promise { promise_->set_result(std::move(result)); promise_.reset(); } - template - void operator()(S &&result) { - if (!promise_) { - return; - } - promise_->operator()(std::forward(result)); - promise_.reset(); - } void reset() { promise_.reset(); } diff --git a/test/online.cpp b/test/online.cpp index 458e4ba4e..97e39df26 100644 --- a/test/online.cpp +++ b/test/online.cpp @@ -160,7 +160,7 @@ class Task : public TestClient::Listener { void on_update(std::shared_ptr update) override { auto it = sent_queries_.find(update->id); if (it != sent_queries_.end()) { - it->second(std::move(update->object)); + it->second.set_value(std::move(update->object)); sent_queries_.erase(it); } process_update(update); From 32bac7bd24202c717a7f4ae119cc7dec48d4b83a Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 27 Jun 2022 13:30:18 +0300 Subject: [PATCH 25/38] Move Promise to tdutils. --- benchmark/bench_actor.cpp | 1 + benchmark/bench_tddb.cpp | 2 +- benchmark/wget.cpp | 2 +- td/mtproto/HandshakeActor.h | 2 +- td/mtproto/Ping.cpp | 3 - td/mtproto/Ping.h | 2 +- td/telegram/Account.h | 3 +- td/telegram/AnimationsManager.cpp | 2 - td/telegram/AnimationsManager.h | 2 +- td/telegram/Application.h | 3 +- td/telegram/AttachMenuManager.h | 2 +- td/telegram/AuthManager.cpp | 3 +- td/telegram/AutoDownloadSettings.h | 3 +- td/telegram/BackgroundManager.h | 2 +- td/telegram/BotCommand.h | 3 +- td/telegram/BotMenuButton.h | 3 +- td/telegram/CallActor.h | 2 +- td/telegram/CallManager.h | 2 +- td/telegram/CallbackQueriesManager.cpp | 1 - td/telegram/CallbackQueriesManager.h | 3 +- td/telegram/ConfigManager.h | 2 +- td/telegram/ContactsManager.cpp | 1 - td/telegram/ContactsManager.h | 2 +- td/telegram/CountryInfoManager.h | 2 +- td/telegram/DeviceTokenManager.cpp | 2 + td/telegram/DeviceTokenManager.h | 2 +- td/telegram/DialogDb.h | 3 +- td/telegram/DialogEventLog.h | 3 +- td/telegram/DownloadManager.h | 2 +- td/telegram/DownloadManagerCallback.cpp | 2 +- td/telegram/FileReferenceManager.h | 2 +- td/telegram/GameManager.h | 2 +- td/telegram/Global.cpp | 2 - td/telegram/Global.h | 2 +- td/telegram/GroupCallManager.h | 2 +- td/telegram/HashtagHints.h | 2 +- td/telegram/InlineQueriesManager.h | 2 +- td/telegram/LanguagePackManager.h | 2 +- td/telegram/LinkManager.h | 2 +- td/telegram/MessageContent.cpp | 1 - td/telegram/MessageContent.h | 3 +- td/telegram/MessageReaction.h | 3 +- td/telegram/MessagesDb.cpp | 1 - td/telegram/MessagesDb.h | 3 +- td/telegram/MessagesManager.cpp | 1 - td/telegram/MessagesManager.h | 2 +- td/telegram/NotificationManager.h | 2 +- td/telegram/NotificationSettingsManager.h | 2 +- td/telegram/OptionManager.h | 2 +- td/telegram/PasswordManager.h | 2 +- td/telegram/Payments.h | 3 +- td/telegram/PollManager.h | 2 +- td/telegram/Premium.h | 3 +- td/telegram/PrivacyManager.h | 2 +- td/telegram/QueryCombiner.h | 2 +- td/telegram/RecentDialogList.h | 2 +- td/telegram/RequestActor.h | 3 +- td/telegram/SecretChatActor.h | 2 +- td/telegram/SecretChatsManager.cpp | 2 - td/telegram/SecretChatsManager.h | 2 +- td/telegram/SecureManager.h | 2 +- td/telegram/SequenceDispatcher.cpp | 3 +- td/telegram/SponsoredMessageManager.h | 2 +- td/telegram/StateManager.h | 2 +- td/telegram/StickersManager.cpp | 2 - td/telegram/StickersManager.h | 2 +- td/telegram/StorageManager.h | 2 +- td/telegram/SuggestedAction.h | 3 +- td/telegram/Td.cpp | 1 - td/telegram/Td.h | 2 +- td/telegram/TdDb.h | 3 +- td/telegram/TermsOfService.h | 3 +- td/telegram/ThemeManager.h | 2 +- td/telegram/TopDialogManager.cpp | 2 + td/telegram/TopDialogManager.h | 2 +- td/telegram/UpdatesManager.cpp | 1 + td/telegram/UpdatesManager.h | 2 +- td/telegram/VoiceNotesManager.h | 2 +- td/telegram/WebPagesManager.h | 2 +- td/telegram/files/FileDb.h | 3 +- td/telegram/files/FileGcWorker.h | 2 +- td/telegram/files/FileGenerateManager.h | 2 +- td/telegram/files/FileLoadManager.h | 2 +- td/telegram/files/FileManager.h | 2 +- td/telegram/files/FileStatsWorker.h | 2 +- td/telegram/logevent/LogEventHelper.h | 3 +- td/telegram/logevent/SecretChatEvent.h | 3 +- td/telegram/net/ConnectionCreator.h | 2 +- td/telegram/net/DcAuthManager.h | 2 +- td/telegram/net/NetQuery.h | 2 +- td/telegram/net/NetQueryDispatcher.h | 2 +- td/telegram/net/NetStatsManager.h | 2 +- td/telegram/net/Session.h | 2 +- td/telegram/net/SessionProxy.cpp | 3 +- tdactor/td/actor/MultiPromise.cpp | 2 +- tdactor/td/actor/MultiPromise.h | 1 + tdactor/td/actor/PromiseFuture.h | 385 +-------------------- tdactor/td/actor/SleepActor.h | 2 +- tdactor/test/actors_simple.cpp | 1 + tddb/td/db/BinlogKeyValue.h | 3 +- tddb/td/db/KeyValueSyncInterface.h | 3 +- tddb/td/db/SqliteKeyValueAsync.h | 3 +- tddb/td/db/TQueue.h | 3 +- tddb/td/db/binlog/Binlog.h | 3 +- tddb/td/db/binlog/BinlogHelper.h | 3 +- tddb/td/db/binlog/BinlogInterface.h | 3 +- tddb/td/db/binlog/ConcurrentBinlog.h | 2 +- tdnet/td/net/DarwinHttp.h | 3 +- tdnet/td/net/GetHostByNameActor.h | 2 +- tdnet/td/net/Wget.h | 2 +- tdutils/CMakeLists.txt | 1 + tdutils/td/utils/Promise.h | 393 ++++++++++++++++++++++ test/mtproto.cpp | 2 +- test/online.cpp | 2 +- test/secret.cpp | 2 +- test/tdclient.cpp | 1 + 116 files changed, 502 insertions(+), 524 deletions(-) create mode 100644 tdutils/td/utils/Promise.h diff --git a/benchmark/bench_actor.cpp b/benchmark/bench_actor.cpp index 66f2e72e3..f68a8d8e0 100644 --- a/benchmark/bench_actor.cpp +++ b/benchmark/bench_actor.cpp @@ -12,6 +12,7 @@ #include "td/utils/common.h" #include "td/utils/crypto.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/SliceBuilder.h" #if TD_MSVC diff --git a/benchmark/bench_tddb.cpp b/benchmark/bench_tddb.cpp index f62c5cd66..eb6880359 100644 --- a/benchmark/bench_tddb.cpp +++ b/benchmark/bench_tddb.cpp @@ -16,12 +16,12 @@ #include "td/db/SqliteDb.h" #include "td/actor/ConcurrentScheduler.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/benchmark.h" #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Random.h" #include "td/utils/Status.h" diff --git a/benchmark/wget.cpp b/benchmark/wget.cpp index 31bedc861..1fdfc2af1 100644 --- a/benchmark/wget.cpp +++ b/benchmark/wget.cpp @@ -9,10 +9,10 @@ #include "td/actor/actor.h" #include "td/actor/ConcurrentScheduler.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" int main(int argc, char *argv[]) { diff --git a/td/mtproto/HandshakeActor.h b/td/mtproto/HandshakeActor.h index 3463bbb2b..cab4ae54c 100644 --- a/td/mtproto/HandshakeActor.h +++ b/td/mtproto/HandshakeActor.h @@ -11,8 +11,8 @@ #include "td/mtproto/RawConnection.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" namespace td { diff --git a/td/mtproto/Ping.cpp b/td/mtproto/Ping.cpp index d9b580459..c8e2a1a6c 100644 --- a/td/mtproto/Ping.cpp +++ b/td/mtproto/Ping.cpp @@ -10,9 +10,6 @@ #include "td/mtproto/PingConnection.h" #include "td/mtproto/RawConnection.h" -#include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/SliceBuilder.h" #include "td/utils/Status.h" diff --git a/td/mtproto/Ping.h b/td/mtproto/Ping.h index f3d8d8cf0..09bc35610 100644 --- a/td/mtproto/Ping.h +++ b/td/mtproto/Ping.h @@ -10,9 +10,9 @@ #include "td/mtproto/RawConnection.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" namespace td { diff --git a/td/telegram/Account.h b/td/telegram/Account.h index 3864c8416..cca9d9f37 100644 --- a/td/telegram/Account.h +++ b/td/telegram/Account.h @@ -9,9 +9,8 @@ #include "td/telegram/DialogParticipant.h" #include "td/telegram/td_api.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" namespace td { diff --git a/td/telegram/AnimationsManager.cpp b/td/telegram/AnimationsManager.cpp index 454da8151..b645b8b5b 100644 --- a/td/telegram/AnimationsManager.cpp +++ b/td/telegram/AnimationsManager.cpp @@ -27,8 +27,6 @@ #include "td/db/SqliteKeyValueAsync.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/algorithm.h" #include "td/utils/logging.h" #include "td/utils/misc.h" diff --git a/td/telegram/AnimationsManager.h b/td/telegram/AnimationsManager.h index c3f821b11..17c5f9559 100644 --- a/td/telegram/AnimationsManager.h +++ b/td/telegram/AnimationsManager.h @@ -15,11 +15,11 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" namespace td { diff --git a/td/telegram/Application.h b/td/telegram/Application.h index b0d18cbd2..4ca4ca7ac 100644 --- a/td/telegram/Application.h +++ b/td/telegram/Application.h @@ -9,9 +9,8 @@ #include "td/telegram/DialogId.h" #include "td/telegram/telegram_api.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" namespace td { diff --git a/td/telegram/AttachMenuManager.h b/td/telegram/AttachMenuManager.h index 8bc10e2fd..5ec2d4d54 100644 --- a/td/telegram/AttachMenuManager.h +++ b/td/telegram/AttachMenuManager.h @@ -14,11 +14,11 @@ #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" namespace td { diff --git a/td/telegram/AuthManager.cpp b/td/telegram/AuthManager.cpp index 861afc1ec..97a1a2694 100644 --- a/td/telegram/AuthManager.cpp +++ b/td/telegram/AuthManager.cpp @@ -28,12 +28,11 @@ #include "td/telegram/TopDialogManager.h" #include "td/telegram/UpdatesManager.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/base64.h" #include "td/utils/format.h" #include "td/utils/logging.h" #include "td/utils/misc.h" +#include "td/utils/Promise.h" #include "td/utils/ScopeGuard.h" #include "td/utils/Slice.h" #include "td/utils/Time.h" diff --git a/td/telegram/AutoDownloadSettings.h b/td/telegram/AutoDownloadSettings.h index 9efce1ffe..c77185829 100644 --- a/td/telegram/AutoDownloadSettings.h +++ b/td/telegram/AutoDownloadSettings.h @@ -9,9 +9,8 @@ #include "td/telegram/net/NetType.h" #include "td/telegram/td_api.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" namespace td { diff --git a/td/telegram/BackgroundManager.h b/td/telegram/BackgroundManager.h index ab360e8bc..996e00442 100644 --- a/td/telegram/BackgroundManager.h +++ b/td/telegram/BackgroundManager.h @@ -15,11 +15,11 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashSet.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/BotCommand.h b/td/telegram/BotCommand.h index 956217792..23d683b11 100644 --- a/td/telegram/BotCommand.h +++ b/td/telegram/BotCommand.h @@ -10,9 +10,8 @@ #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/tl_helpers.h" namespace td { diff --git a/td/telegram/BotMenuButton.h b/td/telegram/BotMenuButton.h index a9069b2c0..79f4b5464 100644 --- a/td/telegram/BotMenuButton.h +++ b/td/telegram/BotMenuButton.h @@ -10,9 +10,8 @@ #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/tl_helpers.h" namespace td { diff --git a/td/telegram/CallActor.h b/td/telegram/CallActor.h index 97186f35f..cb674ac55 100644 --- a/td/telegram/CallActor.h +++ b/td/telegram/CallActor.h @@ -18,10 +18,10 @@ #include "td/mtproto/DhHandshake.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/Container.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/CallManager.h b/td/telegram/CallManager.h index 54a16f32b..3d0f82a84 100644 --- a/td/telegram/CallManager.h +++ b/td/telegram/CallManager.h @@ -12,10 +12,10 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/CallbackQueriesManager.cpp b/td/telegram/CallbackQueriesManager.cpp index 872bdeffb..d9bdb6b11 100644 --- a/td/telegram/CallbackQueriesManager.cpp +++ b/td/telegram/CallbackQueriesManager.cpp @@ -18,7 +18,6 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/logging.h" diff --git a/td/telegram/CallbackQueriesManager.h b/td/telegram/CallbackQueriesManager.h index c3eb1ea4a..e59e1b778 100644 --- a/td/telegram/CallbackQueriesManager.h +++ b/td/telegram/CallbackQueriesManager.h @@ -13,10 +13,9 @@ #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/buffer.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" namespace td { diff --git a/td/telegram/ConfigManager.h b/td/telegram/ConfigManager.h index b04be2133..272058c5f 100644 --- a/td/telegram/ConfigManager.h +++ b/td/telegram/ConfigManager.h @@ -14,11 +14,11 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/FloodControlStrict.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/Time.h" diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 5b1e27431..9b217baee 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -55,7 +55,6 @@ #include "td/db/SqliteKeyValue.h" #include "td/db/SqliteKeyValueAsync.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/SleepActor.h" #include "td/utils/algorithm.h" diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 36b8f75a8..d7669f729 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -39,13 +39,13 @@ #include "td/actor/actor.h" #include "td/actor/MultiPromise.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashSet.h" #include "td/utils/Hints.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" #include "td/utils/Time.h" diff --git a/td/telegram/CountryInfoManager.h b/td/telegram/CountryInfoManager.h index 270caebad..013c5024e 100644 --- a/td/telegram/CountryInfoManager.h +++ b/td/telegram/CountryInfoManager.h @@ -10,10 +10,10 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" diff --git a/td/telegram/DeviceTokenManager.cpp b/td/telegram/DeviceTokenManager.cpp index d7d935d61..727e0bc23 100644 --- a/td/telegram/DeviceTokenManager.cpp +++ b/td/telegram/DeviceTokenManager.cpp @@ -16,6 +16,8 @@ #include "td/mtproto/DhHandshake.h" +#include "td/actor/PromiseFuture.h" + #include "td/utils/algorithm.h" #include "td/utils/base64.h" #include "td/utils/buffer.h" diff --git a/td/telegram/DeviceTokenManager.h b/td/telegram/DeviceTokenManager.h index 2a03ba259..faf13ef11 100644 --- a/td/telegram/DeviceTokenManager.h +++ b/td/telegram/DeviceTokenManager.h @@ -11,9 +11,9 @@ #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/StringBuilder.h" diff --git a/td/telegram/DialogDb.h b/td/telegram/DialogDb.h index 08a4f5111..9a9dfec66 100644 --- a/td/telegram/DialogDb.h +++ b/td/telegram/DialogDb.h @@ -13,10 +13,9 @@ #include "td/db/KeyValueSyncInterface.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/buffer.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/DialogEventLog.h b/td/telegram/DialogEventLog.h index 2d88d5e4a..e47af602f 100644 --- a/td/telegram/DialogEventLog.h +++ b/td/telegram/DialogEventLog.h @@ -10,9 +10,8 @@ #include "td/telegram/td_api.h" #include "td/telegram/UserId.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" namespace td { diff --git a/td/telegram/DownloadManager.h b/td/telegram/DownloadManager.h index 1b3ba51be..aa0790fd9 100644 --- a/td/telegram/DownloadManager.h +++ b/td/telegram/DownloadManager.h @@ -12,9 +12,9 @@ #include "td/telegram/td_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" namespace td { diff --git a/td/telegram/DownloadManagerCallback.cpp b/td/telegram/DownloadManagerCallback.cpp index 9233a7f82..c938756c3 100644 --- a/td/telegram/DownloadManagerCallback.cpp +++ b/td/telegram/DownloadManagerCallback.cpp @@ -11,9 +11,9 @@ #include "td/telegram/Td.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" namespace td { diff --git a/td/telegram/FileReferenceManager.h b/td/telegram/FileReferenceManager.h index 986fe0212..340040db6 100644 --- a/td/telegram/FileReferenceManager.h +++ b/td/telegram/FileReferenceManager.h @@ -18,11 +18,11 @@ #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/Variant.h" diff --git a/td/telegram/GameManager.h b/td/telegram/GameManager.h index 1933f3079..084a664ec 100644 --- a/td/telegram/GameManager.h +++ b/td/telegram/GameManager.h @@ -12,9 +12,9 @@ #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" namespace td { diff --git a/td/telegram/Global.cpp b/td/telegram/Global.cpp index 5a388fa92..e8df3c801 100644 --- a/td/telegram/Global.cpp +++ b/td/telegram/Global.cpp @@ -14,8 +14,6 @@ #include "td/telegram/StateManager.h" #include "td/telegram/TdDb.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/format.h" #include "td/utils/logging.h" #include "td/utils/misc.h" diff --git a/td/telegram/Global.h b/td/telegram/Global.h index ae2f6a171..cda08328f 100644 --- a/td/telegram/Global.h +++ b/td/telegram/Global.h @@ -15,12 +15,12 @@ #include "td/net/NetStats.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/SchedulerLocalStorage.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/Time.h" diff --git a/td/telegram/GroupCallManager.h b/td/telegram/GroupCallManager.h index 894a600ca..fe5af5761 100644 --- a/td/telegram/GroupCallManager.h +++ b/td/telegram/GroupCallManager.h @@ -17,11 +17,11 @@ #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/HashtagHints.h b/td/telegram/HashtagHints.h index ea51470d4..9434769fa 100644 --- a/td/telegram/HashtagHints.h +++ b/td/telegram/HashtagHints.h @@ -7,10 +7,10 @@ #pragma once #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/Hints.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" namespace td { diff --git a/td/telegram/InlineQueriesManager.h b/td/telegram/InlineQueriesManager.h index 8c3effa6d..ab7365587 100644 --- a/td/telegram/InlineQueriesManager.h +++ b/td/telegram/InlineQueriesManager.h @@ -19,11 +19,11 @@ #include "td/actor/actor.h" #include "td/actor/MultiPromise.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/LanguagePackManager.h b/td/telegram/LanguagePackManager.h index 754b41124..973d8d3b1 100644 --- a/td/telegram/LanguagePackManager.h +++ b/td/telegram/LanguagePackManager.h @@ -11,11 +11,11 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/Container.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" diff --git a/td/telegram/LinkManager.h b/td/telegram/LinkManager.h index 38d675ac5..2fe6183c4 100644 --- a/td/telegram/LinkManager.h +++ b/td/telegram/LinkManager.h @@ -12,9 +12,9 @@ #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index c0d9fbe8a..68ea785a4 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -76,7 +76,6 @@ #include "td/actor/actor.h" #include "td/actor/MultiPromise.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/algorithm.h" #include "td/utils/emoji.h" diff --git a/td/telegram/MessageContent.h b/td/telegram/MessageContent.h index 9a65153ea..5ce9af19e 100644 --- a/td/telegram/MessageContent.h +++ b/td/telegram/MessageContent.h @@ -26,10 +26,9 @@ #include "td/telegram/UserId.h" #include "td/telegram/WebPageId.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/buffer.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/MessageReaction.h b/td/telegram/MessageReaction.h index a2ce9e918..bdb098845 100644 --- a/td/telegram/MessageReaction.h +++ b/td/telegram/MessageReaction.h @@ -14,10 +14,9 @@ #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/StringBuilder.h" #include diff --git a/td/telegram/MessagesDb.cpp b/td/telegram/MessagesDb.cpp index 187a1e7ba..87a819201 100644 --- a/td/telegram/MessagesDb.cpp +++ b/td/telegram/MessagesDb.cpp @@ -14,7 +14,6 @@ #include "td/db/SqliteStatement.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/SchedulerLocalStorage.h" #include "td/utils/format.h" diff --git a/td/telegram/MessagesDb.h b/td/telegram/MessagesDb.h index 3ac11b35d..94ab7cba5 100644 --- a/td/telegram/MessagesDb.h +++ b/td/telegram/MessagesDb.h @@ -13,10 +13,9 @@ #include "td/telegram/NotificationId.h" #include "td/telegram/ServerMessageId.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/buffer.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 4a691047b..9dbb6f466 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -68,7 +68,6 @@ #include "td/db/SqliteKeyValue.h" #include "td/db/SqliteKeyValueAsync.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/SleepActor.h" #include "td/utils/algorithm.h" diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 004953d53..9a0f630a3 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -61,7 +61,6 @@ #include "td/actor/actor.h" #include "td/actor/MultiPromise.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/SignalSlot.h" #include "td/actor/Timeout.h" @@ -73,6 +72,7 @@ #include "td/utils/Heap.h" #include "td/utils/Hints.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" diff --git a/td/telegram/NotificationManager.h b/td/telegram/NotificationManager.h index 69a3ddb6c..492063e51 100644 --- a/td/telegram/NotificationManager.h +++ b/td/telegram/NotificationManager.h @@ -21,13 +21,13 @@ #include "td/telegram/td_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" #include "td/utils/Time.h" diff --git a/td/telegram/NotificationSettingsManager.h b/td/telegram/NotificationSettingsManager.h index c88be9458..6e55591ea 100644 --- a/td/telegram/NotificationSettingsManager.h +++ b/td/telegram/NotificationSettingsManager.h @@ -14,11 +14,11 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/OptionManager.h b/td/telegram/OptionManager.h index d6c1e7e20..2bfd1d341 100644 --- a/td/telegram/OptionManager.h +++ b/td/telegram/OptionManager.h @@ -9,9 +9,9 @@ #include "td/telegram/td_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" namespace td { diff --git a/td/telegram/PasswordManager.h b/td/telegram/PasswordManager.h index ada95a267..dd5eb1546 100644 --- a/td/telegram/PasswordManager.h +++ b/td/telegram/PasswordManager.h @@ -13,12 +13,12 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/Container.h" #include "td/utils/optional.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/tl_helpers.h" diff --git a/td/telegram/Payments.h b/td/telegram/Payments.h index 13deb0e31..f6896645e 100644 --- a/td/telegram/Payments.h +++ b/td/telegram/Payments.h @@ -14,9 +14,8 @@ #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" diff --git a/td/telegram/PollManager.h b/td/telegram/PollManager.h index 59f3e0a03..90a0a8802 100644 --- a/td/telegram/PollManager.h +++ b/td/telegram/PollManager.h @@ -16,13 +16,13 @@ #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashSet.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/Premium.h b/td/telegram/Premium.h index 9e5dfa9f2..fa97a471d 100644 --- a/td/telegram/Premium.h +++ b/td/telegram/Premium.h @@ -8,9 +8,8 @@ #include "td/telegram/td_api.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" namespace td { diff --git a/td/telegram/PrivacyManager.h b/td/telegram/PrivacyManager.h index 789d01e44..2632f5ff7 100644 --- a/td/telegram/PrivacyManager.h +++ b/td/telegram/PrivacyManager.h @@ -12,10 +12,10 @@ #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/Container.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/QueryCombiner.h b/td/telegram/QueryCombiner.h index ae9b1c99a..7d1542715 100644 --- a/td/telegram/QueryCombiner.h +++ b/td/telegram/QueryCombiner.h @@ -7,10 +7,10 @@ #pragma once #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" diff --git a/td/telegram/RecentDialogList.h b/td/telegram/RecentDialogList.h index b12edb8a6..1163c73aa 100644 --- a/td/telegram/RecentDialogList.h +++ b/td/telegram/RecentDialogList.h @@ -9,10 +9,10 @@ #include "td/telegram/DialogId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/FlatHashSet.h" +#include "td/utils/Promise.h" #include diff --git a/td/telegram/RequestActor.h b/td/telegram/RequestActor.h index 03827c04b..3463e2994 100644 --- a/td/telegram/RequestActor.h +++ b/td/telegram/RequestActor.h @@ -15,6 +15,7 @@ #include "td/utils/common.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include @@ -37,7 +38,7 @@ class RequestActor : public Actor { FutureActor future; init_promise_future(&promise_actor, &future); - auto promise = PromiseCreator::from_promise_actor(std::move(promise_actor)); + auto promise = create_promise_from_promise_actor(std::move(promise_actor)); do_run(std::move(promise)); if (future.is_ready()) { diff --git a/td/telegram/SecretChatActor.h b/td/telegram/SecretChatActor.h index 775e3d1c7..afae8dc6d 100644 --- a/td/telegram/SecretChatActor.h +++ b/td/telegram/SecretChatActor.h @@ -24,7 +24,6 @@ #include "td/mtproto/DhHandshake.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/buffer.h" #include "td/utils/ChangesProcessor.h" @@ -32,6 +31,7 @@ #include "td/utils/Container.h" #include "td/utils/format.h" #include "td/utils/port/Clocks.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" diff --git a/td/telegram/SecretChatsManager.cpp b/td/telegram/SecretChatsManager.cpp index 2a8a50c91..696e4bd68 100644 --- a/td/telegram/SecretChatsManager.cpp +++ b/td/telegram/SecretChatsManager.cpp @@ -28,8 +28,6 @@ #include "td/db/binlog/BinlogHelper.h" #include "td/db/binlog/BinlogInterface.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" #include "td/utils/format.h" #include "td/utils/logging.h" diff --git a/td/telegram/SecretChatsManager.h b/td/telegram/SecretChatsManager.h index 1e2ca83c3..cacd5263c 100644 --- a/td/telegram/SecretChatsManager.h +++ b/td/telegram/SecretChatsManager.h @@ -14,9 +14,9 @@ #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Time.h" #include diff --git a/td/telegram/SecureManager.h b/td/telegram/SecureManager.h index e4180254b..c895f4381 100644 --- a/td/telegram/SecureManager.h +++ b/td/telegram/SecureManager.h @@ -14,11 +14,11 @@ #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/Container.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/SequenceDispatcher.cpp b/td/telegram/SequenceDispatcher.cpp index 7fa0c27a6..fb01bdb94 100644 --- a/td/telegram/SequenceDispatcher.cpp +++ b/td/telegram/SequenceDispatcher.cpp @@ -10,13 +10,12 @@ #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/Td.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/algorithm.h" #include "td/utils/ChainScheduler.h" #include "td/utils/format.h" #include "td/utils/logging.h" #include "td/utils/misc.h" +#include "td/utils/Promise.h" #include "td/utils/SliceBuilder.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" diff --git a/td/telegram/SponsoredMessageManager.h b/td/telegram/SponsoredMessageManager.h index a35adecbd..6e11aa04f 100644 --- a/td/telegram/SponsoredMessageManager.h +++ b/td/telegram/SponsoredMessageManager.h @@ -12,11 +12,11 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" namespace td { diff --git a/td/telegram/StateManager.h b/td/telegram/StateManager.h index 66b0dabcd..b32448f80 100644 --- a/td/telegram/StateManager.h +++ b/td/telegram/StateManager.h @@ -12,9 +12,9 @@ #include "td/mtproto/ConnectionManager.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" namespace td { diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 6160e1bb4..edefbcc40 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -41,8 +41,6 @@ #include "td/db/SqliteKeyValue.h" #include "td/db/SqliteKeyValueAsync.h" -#include "td/actor/MultiPromise.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/SleepActor.h" #include "td/utils/algorithm.h" diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index eef623515..fb0876b46 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -22,7 +22,6 @@ #include "td/actor/actor.h" #include "td/actor/MultiPromise.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/buffer.h" @@ -30,6 +29,7 @@ #include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashSet.h" #include "td/utils/Hints.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" diff --git a/td/telegram/StorageManager.h b/td/telegram/StorageManager.h index 2650ea57f..9c6c39bf8 100644 --- a/td/telegram/StorageManager.h +++ b/td/telegram/StorageManager.h @@ -12,10 +12,10 @@ #include "td/telegram/td_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/CancellationToken.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" diff --git a/td/telegram/SuggestedAction.h b/td/telegram/SuggestedAction.h index c64144815..af33f9202 100644 --- a/td/telegram/SuggestedAction.h +++ b/td/telegram/SuggestedAction.h @@ -9,9 +9,8 @@ #include "td/telegram/DialogId.h" #include "td/telegram/td_api.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" namespace td { diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 836d2fbc8..d7686486d 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -134,7 +134,6 @@ #include "td/mtproto/TransportType.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/algorithm.h" #include "td/utils/buffer.h" diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 0e4c33ef4..f7323d86a 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -21,7 +21,6 @@ #include "td/db/DbKey.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/buffer.h" @@ -29,6 +28,7 @@ #include "td/utils/Container.h" #include "td/utils/FlatHashMap.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" diff --git a/td/telegram/TdDb.h b/td/telegram/TdDb.h index 957d0d842..db0a732e7 100644 --- a/td/telegram/TdDb.h +++ b/td/telegram/TdDb.h @@ -13,8 +13,7 @@ #include "td/db/DbKey.h" #include "td/db/KeyValueSyncInterface.h" -#include "td/actor/PromiseFuture.h" - +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" diff --git a/td/telegram/TermsOfService.h b/td/telegram/TermsOfService.h index 7ac832fa7..410526da8 100644 --- a/td/telegram/TermsOfService.h +++ b/td/telegram/TermsOfService.h @@ -11,9 +11,8 @@ #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/tl_helpers.h" diff --git a/td/telegram/ThemeManager.h b/td/telegram/ThemeManager.h index ffed0aed4..e11b9038e 100644 --- a/td/telegram/ThemeManager.h +++ b/td/telegram/ThemeManager.h @@ -12,9 +12,9 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" namespace td { diff --git a/td/telegram/TopDialogManager.cpp b/td/telegram/TopDialogManager.cpp index 52aabc622..679b54ede 100644 --- a/td/telegram/TopDialogManager.cpp +++ b/td/telegram/TopDialogManager.cpp @@ -22,6 +22,8 @@ #include "td/telegram/TdDb.h" #include "td/telegram/TdParameters.h" +#include "td/actor/PromiseFuture.h" + #include "td/utils/algorithm.h" #include "td/utils/buffer.h" #include "td/utils/logging.h" diff --git a/td/telegram/TopDialogManager.h b/td/telegram/TopDialogManager.h index 175ec7805..fa5e47a25 100644 --- a/td/telegram/TopDialogManager.h +++ b/td/telegram/TopDialogManager.h @@ -11,9 +11,9 @@ #include "td/telegram/TopDialogCategory.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include "td/utils/Time.h" diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 0f9279ba1..c020d9482 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -57,6 +57,7 @@ #include "td/telegram/WebPagesManager.h" #include "td/actor/MultiPromise.h" +#include "td/actor/PromiseFuture.h" #include "td/utils/algorithm.h" #include "td/utils/buffer.h" diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index b637bb4a7..1c72b649c 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -17,12 +17,12 @@ #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/common.h" #include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include "td/utils/tl_storers.h" #include "td/utils/TlStorerToString.h" diff --git a/td/telegram/VoiceNotesManager.h b/td/telegram/VoiceNotesManager.h index 11138157c..60c0681d5 100644 --- a/td/telegram/VoiceNotesManager.h +++ b/td/telegram/VoiceNotesManager.h @@ -13,12 +13,12 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashSet.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" namespace td { diff --git a/td/telegram/WebPagesManager.h b/td/telegram/WebPagesManager.h index cfe447818..95d280407 100644 --- a/td/telegram/WebPagesManager.h +++ b/td/telegram/WebPagesManager.h @@ -16,12 +16,12 @@ #include "td/telegram/WebPageId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashSet.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/files/FileDb.h b/td/telegram/files/FileDb.h index 51eeb9ae7..db6a26f5c 100644 --- a/td/telegram/files/FileDb.h +++ b/td/telegram/files/FileDb.h @@ -9,11 +9,10 @@ #include "td/telegram/files/FileData.h" #include "td/telegram/files/FileDbId.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include "td/utils/tl_storers.h" diff --git a/td/telegram/files/FileGcWorker.h b/td/telegram/files/FileGcWorker.h index cb5567362..e7da77f18 100644 --- a/td/telegram/files/FileGcWorker.h +++ b/td/telegram/files/FileGcWorker.h @@ -10,10 +10,10 @@ #include "td/telegram/files/FileStats.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/CancellationToken.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" namespace td { diff --git a/td/telegram/files/FileGenerateManager.h b/td/telegram/files/FileGenerateManager.h index 22c20f4db..3df9d5e89 100644 --- a/td/telegram/files/FileGenerateManager.h +++ b/td/telegram/files/FileGenerateManager.h @@ -9,8 +9,8 @@ #include "td/telegram/files/FileLocation.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/files/FileLoadManager.h b/td/telegram/files/FileLoadManager.h index 95884eca7..9192c0cc2 100644 --- a/td/telegram/files/FileLoadManager.h +++ b/td/telegram/files/FileLoadManager.h @@ -17,11 +17,11 @@ #include "td/telegram/net/DcId.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/Container.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/files/FileManager.h b/td/telegram/files/FileManager.h index 33d62023f..e8bb35992 100644 --- a/td/telegram/files/FileManager.h +++ b/td/telegram/files/FileManager.h @@ -21,7 +21,6 @@ #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/buffer.h" #include "td/utils/common.h" @@ -31,6 +30,7 @@ #include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" #include "td/utils/optional.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" diff --git a/td/telegram/files/FileStatsWorker.h b/td/telegram/files/FileStatsWorker.h index da38d799e..71c4a7003 100644 --- a/td/telegram/files/FileStatsWorker.h +++ b/td/telegram/files/FileStatsWorker.h @@ -9,9 +9,9 @@ #include "td/telegram/files/FileStats.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/CancellationToken.h" +#include "td/utils/Promise.h" namespace td { diff --git a/td/telegram/logevent/LogEventHelper.h b/td/telegram/logevent/LogEventHelper.h index c9c23d757..b1beb6756 100644 --- a/td/telegram/logevent/LogEventHelper.h +++ b/td/telegram/logevent/LogEventHelper.h @@ -8,9 +8,8 @@ #include "td/telegram/Global.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/StorerBase.h" #include "td/utils/Time.h" diff --git a/td/telegram/logevent/SecretChatEvent.h b/td/telegram/logevent/SecretChatEvent.h index f5951d039..4072eaf6e 100644 --- a/td/telegram/logevent/SecretChatEvent.h +++ b/td/telegram/logevent/SecretChatEvent.h @@ -13,11 +13,10 @@ #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/format.h" +#include "td/utils/Promise.h" #include "td/utils/SliceBuilder.h" #include "td/utils/Status.h" #include "td/utils/StorerBase.h" diff --git a/td/telegram/net/ConnectionCreator.h b/td/telegram/net/ConnectionCreator.h index 16082dd13..92c7a5eee 100644 --- a/td/telegram/net/ConnectionCreator.h +++ b/td/telegram/net/ConnectionCreator.h @@ -21,7 +21,6 @@ #include "td/net/NetStats.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/SignalSlot.h" #include "td/utils/BufferedFd.h" @@ -31,6 +30,7 @@ #include "td/utils/logging.h" #include "td/utils/port/IPAddress.h" #include "td/utils/port/SocketFd.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/Time.h" diff --git a/td/telegram/net/DcAuthManager.h b/td/telegram/net/DcAuthManager.h index a6e21abda..2626db9c3 100644 --- a/td/telegram/net/DcAuthManager.h +++ b/td/telegram/net/DcAuthManager.h @@ -11,11 +11,11 @@ #include "td/telegram/net/NetQuery.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include diff --git a/td/telegram/net/NetQuery.h b/td/telegram/net/NetQuery.h index bc0edb3d0..d885bd784 100644 --- a/td/telegram/net/NetQuery.h +++ b/td/telegram/net/NetQuery.h @@ -11,7 +11,6 @@ #include "td/telegram/net/NetQueryStats.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/actor/SignalSlot.h" #include "td/utils/buffer.h" @@ -19,6 +18,7 @@ #include "td/utils/format.h" #include "td/utils/logging.h" #include "td/utils/ObjectPool.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Span.h" #include "td/utils/Status.h" diff --git a/td/telegram/net/NetQueryDispatcher.h b/td/telegram/net/NetQueryDispatcher.h index 236081cb0..737d7a748 100644 --- a/td/telegram/net/NetQueryDispatcher.h +++ b/td/telegram/net/NetQueryDispatcher.h @@ -10,9 +10,9 @@ #include "td/telegram/net/NetQuery.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/ScopeGuard.h" #include "td/utils/Status.h" diff --git a/td/telegram/net/NetStatsManager.h b/td/telegram/net/NetStatsManager.h index a869aa1f2..a794addb1 100644 --- a/td/telegram/net/NetStatsManager.h +++ b/td/telegram/net/NetStatsManager.h @@ -13,8 +13,8 @@ #include "td/net/NetStats.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include diff --git a/td/telegram/net/Session.h b/td/telegram/net/Session.h index 16ce9a5b1..d46779195 100644 --- a/td/telegram/net/Session.h +++ b/td/telegram/net/Session.h @@ -17,7 +17,6 @@ #include "td/mtproto/SessionConnection.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/buffer.h" #include "td/utils/CancellationToken.h" @@ -25,6 +24,7 @@ #include "td/utils/FlatHashMap.h" #include "td/utils/FlatHashSet.h" #include "td/utils/List.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" #include "td/utils/VectorQueue.h" diff --git a/td/telegram/net/SessionProxy.cpp b/td/telegram/net/SessionProxy.cpp index cb2de374c..1e101f8a7 100644 --- a/td/telegram/net/SessionProxy.cpp +++ b/td/telegram/net/SessionProxy.cpp @@ -14,11 +14,10 @@ #include "td/telegram/Td.h" #include "td/telegram/UniqueId.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/logging.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" diff --git a/tdactor/td/actor/MultiPromise.cpp b/tdactor/td/actor/MultiPromise.cpp index 5bf8d40bd..f78e0f016 100644 --- a/tdactor/td/actor/MultiPromise.cpp +++ b/tdactor/td/actor/MultiPromise.cpp @@ -28,7 +28,7 @@ Promise MultiPromiseActor::get_promise() { future.set_event(EventCreator::raw(actor_id(), nullptr)); futures_.emplace_back(std::move(future)); LOG(DEBUG) << "Get promise #" << futures_.size() << " for " << name_; - return PromiseCreator::from_promise_actor(std::move(promise)); + return create_promise_from_promise_actor(std::move(promise)); } void MultiPromiseActor::raw_event(const Event::Raw &event) { diff --git a/tdactor/td/actor/MultiPromise.h b/tdactor/td/actor/MultiPromise.h index 88ac09e52..73b24d5d1 100644 --- a/tdactor/td/actor/MultiPromise.h +++ b/tdactor/td/actor/MultiPromise.h @@ -10,6 +10,7 @@ #include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" namespace td { diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index fb81bced1..1a8940558 100644 --- a/tdactor/td/actor/PromiseFuture.h +++ b/tdactor/td/actor/PromiseFuture.h @@ -8,282 +8,10 @@ #include "td/actor/actor.h" -#include "td/utils/CancellationToken.h" -#include "td/utils/Closure.h" #include "td/utils/common.h" -#include "td/utils/invoke.h" -#include "td/utils/logging.h" -#include "td/utils/MovableValue.h" -#include "td/utils/ScopeGuard.h" -#include "td/utils/Status.h" - -#include -#include -#include +#include "td/utils/Promise.h" namespace td { - -template -class PromiseInterface { - public: - PromiseInterface() = default; - PromiseInterface(const PromiseInterface &) = delete; - PromiseInterface &operator=(const PromiseInterface &) = delete; - PromiseInterface(PromiseInterface &&) = default; - PromiseInterface &operator=(PromiseInterface &&) = default; - virtual ~PromiseInterface() = default; - - virtual void set_value(T &&value) { - set_result(std::move(value)); - } - virtual void set_error(Status &&error) { - set_result(std::move(error)); - } - virtual void set_result(Result &&result) { - if (result.is_ok()) { - set_value(result.move_as_ok()); - } else { - set_error(result.move_as_error()); - } - } - - virtual bool is_cancellable() const { - return false; - } - virtual bool is_canceled() const { - return false; - } -}; - -namespace detail { - -template -struct GetArg final : public GetArg {}; - -template -class GetArg { - public: - using type = Arg; -}; -template -class GetArg { - public: - using type = Arg; -}; - -template -using get_arg_t = std::decay_t::type>; - -template -struct DropResult { - using type = T; -}; - -template -struct DropResult> { - using type = T; -}; - -template -using drop_result_t = typename DropResult::type; - -template -class LambdaPromise : public PromiseInterface { - enum class State : int32 { Empty, Ready, Complete }; - - public: - void set_value(ValueT &&value) override { - CHECK(state_.get() == State::Ready); - func_(std::move(value)); - state_ = State::Complete; - } - - void set_error(Status &&error) override { - if (state_.get() == State::Ready) { - do_error(std::move(error)); - state_ = State::Complete; - } - } - LambdaPromise(const LambdaPromise &other) = delete; - LambdaPromise &operator=(const LambdaPromise &other) = delete; - LambdaPromise(LambdaPromise &&other) = default; - LambdaPromise &operator=(LambdaPromise &&other) = default; - ~LambdaPromise() override { - if (state_.get() == State::Ready) { - do_error(Status::Error("Lost promise")); - } - } - - template - explicit LambdaPromise(FromT &&func) : func_(std::forward(func)), state_(State::Ready) { - } - - private: - FunctionT func_; - MovableValue state_{State::Empty}; - - template - std::enable_if_t>::value, void> do_error(Status &&status) { - func_(Result(std::move(status))); - } - template - std::enable_if_t>::value, void> do_error(Y &&status) { - func_(Auto()); - } -}; -} // namespace detail - -template -class SafePromise; - -template -class Promise; - -template -struct is_promise_interface : std::false_type {}; - -template -struct is_promise_interface> : std::true_type {}; - -template -struct is_promise_interface> : std::true_type {}; - -template -struct is_promise_interface_ptr : std::false_type {}; - -template -struct is_promise_interface_ptr> : std::true_type {}; - -template ::value, bool> has_t = false> -auto lambda_promise(F &&f) { - return detail::LambdaPromise>>, std::decay_t>( - std::forward(f)); -} -template ::value, bool> has_t = true> -auto lambda_promise(F &&f) { - return detail::LambdaPromise>(std::forward(f)); -} - -template >::value, bool> from_promise_interface = true> -auto &&promise_interface(F &&f) { - return std::forward(f); -} - -template >::value, bool> from_promise_interface = false> -auto promise_interface(F &&f) { - return lambda_promise(std::forward(f)); -} - -template >::value, bool> from_promise_interface = true> -auto promise_interface_ptr(F &&f) { - return std::forward(f); -} - -template >::value, bool> from_promise_interface = false> -auto promise_interface_ptr(F &&f) { - return td::make_unique(std::forward(f)))>>( - promise_interface(std::forward(f))); -} - -template -class Promise { - public: - void set_value(T &&value) { - if (!promise_) { - return; - } - promise_->set_value(std::move(value)); - promise_.reset(); - } - void set_error(Status &&error) { - if (!promise_) { - return; - } - promise_->set_error(std::move(error)); - promise_.reset(); - } - void set_result(Result &&result) { - if (!promise_) { - return; - } - promise_->set_result(std::move(result)); - promise_.reset(); - } - void reset() { - promise_.reset(); - } - bool is_cancellable() const { - if (!promise_) { - return false; - } - return promise_->is_cancellable(); - } - bool is_canceled() const { - if (!promise_) { - return false; - } - return promise_->is_canceled(); - } - unique_ptr> release() { - return std::move(promise_); - } - - Promise() = default; - explicit Promise(unique_ptr> promise) : promise_(std::move(promise)) { - } - Promise(Auto) { - } - Promise(SafePromise &&other); - Promise &operator=(SafePromise &&other); - template , Promise>::value, int> = 0> - Promise(F &&f) : promise_(promise_interface_ptr(std::forward(f))) { - } - - explicit operator bool() { - return static_cast(promise_); - } - - private: - unique_ptr> promise_; -}; - - -template -class SafePromise { - public: - SafePromise(Promise promise, Result result) : promise_(std::move(promise)), result_(std::move(result)) { - } - SafePromise(const SafePromise &other) = delete; - SafePromise &operator=(const SafePromise &other) = delete; - SafePromise(SafePromise &&other) = default; - SafePromise &operator=(SafePromise &&other) = default; - ~SafePromise() { - if (promise_) { - promise_.set_result(std::move(result_)); - } - } - Promise release() { - return std::move(promise_); - } - - private: - Promise promise_; - Result result_; -}; - -template -Promise::Promise(SafePromise &&other) : Promise(other.release()) { -} -template -Promise &Promise::operator=(SafePromise &&other) { - *this = other.release(); - return *this; -} - namespace detail { class EventPromise final : public PromiseInterface { @@ -323,40 +51,6 @@ class EventPromise final : public PromiseInterface { } } }; - -template -class CancellablePromise final : public PromiseT { - public: - template - CancellablePromise(CancellationToken cancellation_token, ArgsT &&...args) - : PromiseT(std::forward(args)...), cancellation_token_(std::move(cancellation_token)) { - } - bool is_cancellable() const final { - return true; - } - bool is_canceled() const final { - return static_cast(cancellation_token_); - } - - private: - CancellationToken cancellation_token_; -}; - -template -class JoinPromise final : public PromiseInterface { - public: - explicit JoinPromise(ArgsT &&...arg) : promises_(std::forward(arg)...) { - } - void set_value(Unit &&) final { - tuple_for_each(promises_, [](auto &promise) { promise.set_value(Unit()); }); - } - void set_error(Status &&error) final { - tuple_for_each(promises_, [&error](auto &promise) { promise.set_error(error.clone()); }); - } - - private: - std::tuple...> promises_; -}; } // namespace detail inline Promise create_event_promise(EventFull &&ok) { @@ -367,31 +61,6 @@ inline Promise create_event_promise(EventFull ok, EventFull fail) { return Promise(td::make_unique(std::move(ok), std::move(fail))); } -class SendClosure { - public: - template - void operator()(ArgsT &&...args) const { - send_closure(std::forward(args)...); - } -}; - -//template -//template -//auto Promise::send_closure(ArgsT &&... args) { -// return [promise = std::move(*this), t = std::make_tuple(std::forward(args)...)](auto &&r_res) mutable { -// TRY_RESULT_PROMISE(promise, res, std::move(r_res)); -// td2::call_tuple(SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::move(res), std::move(promise)))); -// }; -//} - -template -auto promise_send_closure(ArgsT &&...args) { - return [t = std::make_tuple(std::forward(args)...)](auto &&res) mutable { - call_tuple(SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::forward(res)))); - }; -} - -/*** FutureActor and PromiseActor ***/ template class FutureActor; @@ -618,57 +287,9 @@ FutureActor send_promise(ActorId actor_id, ResultT (ActorBT::*func)( return pf.move_future(); } -class PromiseCreator { - public: - template >> - static Promise lambda(OkT &&ok) { - return Promise(td::make_unique>>(std::forward(ok))); - } - - template >> - static auto cancellable_lambda(CancellationToken cancellation_token, OkT &&ok) { - return Promise(td::make_unique>>>( - std::move(cancellation_token), std::forward(ok))); - } - - template - static Promise<> join(ArgsT &&...args) { - return Promise<>(td::make_unique>(std::forward(args)...)); - } - - template - static Promise from_promise_actor(PromiseActor &&from) { - return Promise(td::make_unique>(std::move(from))); - } -}; - -inline void set_promises(vector> &promises) { - auto moved_promises = std::move(promises); - promises.clear(); - - for (auto &promise : moved_promises) { - promise.set_value(Unit()); - } -} - template -void fail_promises(vector> &promises, Status &&error) { - CHECK(error.is_error()); - auto moved_promises = std::move(promises); - promises.clear(); - - auto size = moved_promises.size(); - if (size == 0) { - return; - } - size--; - for (size_t i = 0; i < size; i++) { - auto &promise = moved_promises[i]; - if (promise) { - promise.set_error(error.clone()); - } - } - moved_promises[size].set_error(std::move(error)); +Promise create_promise_from_promise_actor(PromiseActor &&from) { + return Promise(td::make_unique>(std::move(from))); } } // namespace td diff --git a/tdactor/td/actor/SleepActor.h b/tdactor/td/actor/SleepActor.h index 2c02db8af..8682ab0df 100644 --- a/tdactor/td/actor/SleepActor.h +++ b/tdactor/td/actor/SleepActor.h @@ -7,9 +7,9 @@ #pragma once #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" namespace td { diff --git a/tdactor/test/actors_simple.cpp b/tdactor/test/actors_simple.cpp index a76b80884..58f14ac48 100644 --- a/tdactor/test/actors_simple.cpp +++ b/tdactor/test/actors_simple.cpp @@ -16,6 +16,7 @@ #include "td/utils/Observer.h" #include "td/utils/port/FileFd.h" #include "td/utils/port/thread.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" diff --git a/tddb/td/db/BinlogKeyValue.h b/tddb/td/db/BinlogKeyValue.h index 1759308cf..23419e950 100644 --- a/tddb/td/db/BinlogKeyValue.h +++ b/tddb/td/db/BinlogKeyValue.h @@ -11,14 +11,13 @@ #include "td/db/DbKey.h" #include "td/db/KeyValueSyncInterface.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/algorithm.h" #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/port/RwMutex.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/StorerBase.h" diff --git a/tddb/td/db/KeyValueSyncInterface.h b/tddb/td/db/KeyValueSyncInterface.h index 7aa553684..b73a7096d 100644 --- a/tddb/td/db/KeyValueSyncInterface.h +++ b/tddb/td/db/KeyValueSyncInterface.h @@ -6,9 +6,8 @@ // #pragma once -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include diff --git a/tddb/td/db/SqliteKeyValueAsync.h b/tddb/td/db/SqliteKeyValueAsync.h index 530b3f1e0..e5bc29b1e 100644 --- a/tddb/td/db/SqliteKeyValueAsync.h +++ b/tddb/td/db/SqliteKeyValueAsync.h @@ -8,10 +8,9 @@ #include "td/db/SqliteKeyValueSafe.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" #include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" #include diff --git a/tddb/td/db/TQueue.h b/tddb/td/db/TQueue.h index bde8730c0..934d8a02e 100644 --- a/tddb/td/db/TQueue.h +++ b/tddb/td/db/TQueue.h @@ -6,9 +6,8 @@ // #pragma once -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Span.h" #include "td/utils/Status.h" diff --git a/tddb/td/db/binlog/Binlog.h b/tddb/td/db/binlog/Binlog.h index 14dbcf14f..88dbacf58 100644 --- a/tddb/td/db/binlog/Binlog.h +++ b/tddb/td/db/binlog/Binlog.h @@ -9,8 +9,6 @@ #include "td/db/binlog/BinlogEvent.h" #include "td/db/DbKey.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/AesCtrByteFlow.h" #include "td/utils/buffer.h" #include "td/utils/BufferedFd.h" @@ -19,6 +17,7 @@ #include "td/utils/crypto.h" #include "td/utils/logging.h" #include "td/utils/port/FileFd.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/StorerBase.h" diff --git a/tddb/td/db/binlog/BinlogHelper.h b/tddb/td/db/binlog/BinlogHelper.h index aaeee7b51..66a65e060 100644 --- a/tddb/td/db/binlog/BinlogHelper.h +++ b/tddb/td/db/binlog/BinlogHelper.h @@ -9,9 +9,8 @@ #include "td/db/binlog/BinlogEvent.h" #include "td/db/binlog/BinlogInterface.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/StorerBase.h" namespace td { diff --git a/tddb/td/db/binlog/BinlogInterface.h b/tddb/td/db/binlog/BinlogInterface.h index 9ef596a15..b3ec7b119 100644 --- a/tddb/td/db/binlog/BinlogInterface.h +++ b/tddb/td/db/binlog/BinlogInterface.h @@ -9,10 +9,9 @@ #include "td/db/binlog/BinlogEvent.h" #include "td/db/DbKey.h" -#include "td/actor/PromiseFuture.h" - #include "td/utils/buffer.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/StorerBase.h" namespace td { diff --git a/tddb/td/db/binlog/ConcurrentBinlog.h b/tddb/td/db/binlog/ConcurrentBinlog.h index 3db87516a..ad6c9bc5c 100644 --- a/tddb/td/db/binlog/ConcurrentBinlog.h +++ b/tddb/td/db/binlog/ConcurrentBinlog.h @@ -11,10 +11,10 @@ #include "td/db/DbKey.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/buffer.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" diff --git a/tdnet/td/net/DarwinHttp.h b/tdnet/td/net/DarwinHttp.h index 4d5447f74..42c0a5b00 100644 --- a/tdnet/td/net/DarwinHttp.h +++ b/tdnet/td/net/DarwinHttp.h @@ -6,9 +6,8 @@ // #pragma once -#include "td/actor/PromiseFuture.h" - #include "td/utils/buffer.h" +#include "td/utils/Promise.h" #include "td/utils/Slice.h" namespace td { diff --git a/tdnet/td/net/GetHostByNameActor.h b/tdnet/td/net/GetHostByNameActor.h index 4acef459e..f864b13e3 100644 --- a/tdnet/td/net/GetHostByNameActor.h +++ b/tdnet/td/net/GetHostByNameActor.h @@ -7,11 +7,11 @@ #pragma once #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/FlatHashMap.h" #include "td/utils/logging.h" #include "td/utils/port/IPAddress.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/tdnet/td/net/Wget.h b/tdnet/td/net/Wget.h index 98d1d1e0f..9372b4d58 100644 --- a/tdnet/td/net/Wget.h +++ b/tdnet/td/net/Wget.h @@ -11,9 +11,9 @@ #include "td/net/SslStream.h" #include "td/actor/actor.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" #include diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index ae2b3ba08..c0d26b9ec 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -250,6 +250,7 @@ set(TDUTILS_SOURCE td/utils/overloaded.h td/utils/Parser.h td/utils/PathView.h + td/utils/Promise.h td/utils/queue.h td/utils/Random.h td/utils/ScopeGuard.h diff --git a/tdutils/td/utils/Promise.h b/tdutils/td/utils/Promise.h new file mode 100644 index 000000000..7746bc0ae --- /dev/null +++ b/tdutils/td/utils/Promise.h @@ -0,0 +1,393 @@ +// +// 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) +// +#pragma once + +#include "td/utils/CancellationToken.h" +#include "td/utils/Closure.h" +#include "td/utils/common.h" +#include "td/utils/invoke.h" +#include "td/utils/logging.h" +#include "td/utils/MovableValue.h" +#include "td/utils/ScopeGuard.h" +#include "td/utils/Status.h" + +#include +#include +#include + +namespace td { + +template +class PromiseInterface { + public: + PromiseInterface() = default; + PromiseInterface(const PromiseInterface &) = delete; + PromiseInterface &operator=(const PromiseInterface &) = delete; + PromiseInterface(PromiseInterface &&) = default; + PromiseInterface &operator=(PromiseInterface &&) = default; + virtual ~PromiseInterface() = default; + + virtual void set_value(T &&value) { + set_result(std::move(value)); + } + virtual void set_error(Status &&error) { + set_result(std::move(error)); + } + virtual void set_result(Result &&result) { + if (result.is_ok()) { + set_value(result.move_as_ok()); + } else { + set_error(result.move_as_error()); + } + } + + virtual bool is_cancellable() const { + return false; + } + virtual bool is_canceled() const { + return false; + } +}; + +namespace detail { + +template +struct GetArg final : public GetArg {}; + +template +class GetArg { + public: + using type = Arg; +}; +template +class GetArg { + public: + using type = Arg; +}; + +template +using get_arg_t = std::decay_t::type>; + +template +struct DropResult { + using type = T; +}; + +template +struct DropResult> { + using type = T; +}; + +template +using drop_result_t = typename DropResult::type; + +template +class LambdaPromise : public PromiseInterface { + enum class State : int32 { Empty, Ready, Complete }; + + public: + void set_value(ValueT &&value) override { + CHECK(state_.get() == State::Ready); + func_(std::move(value)); + state_ = State::Complete; + } + + void set_error(Status &&error) override { + if (state_.get() == State::Ready) { + do_error(std::move(error)); + state_ = State::Complete; + } + } + LambdaPromise(const LambdaPromise &other) = delete; + LambdaPromise &operator=(const LambdaPromise &other) = delete; + LambdaPromise(LambdaPromise &&other) = default; + LambdaPromise &operator=(LambdaPromise &&other) = default; + ~LambdaPromise() override { + if (state_.get() == State::Ready) { + do_error(Status::Error("Lost promise")); + } + } + + template + explicit LambdaPromise(FromT &&func) : func_(std::forward(func)), state_(State::Ready) { + } + + private: + FunctionT func_; + MovableValue state_{State::Empty}; + + template + std::enable_if_t>::value, void> do_error(Status &&status) { + func_(Result(std::move(status))); + } + template + std::enable_if_t>::value, void> do_error(Y &&status) { + func_(Auto()); + } +}; +} // namespace detail + +template +class SafePromise; + +template +class Promise; + +template +struct is_promise_interface : std::false_type {}; + +template +struct is_promise_interface> : std::true_type {}; + +template +struct is_promise_interface> : std::true_type {}; + +template +struct is_promise_interface_ptr : std::false_type {}; + +template +struct is_promise_interface_ptr> : std::true_type {}; + +template ::value, bool> has_t = false> +auto lambda_promise(F &&f) { + return detail::LambdaPromise>>, std::decay_t>( + std::forward(f)); +} +template ::value, bool> has_t = true> +auto lambda_promise(F &&f) { + return detail::LambdaPromise>(std::forward(f)); +} + +template >::value, bool> from_promise_interface = true> +auto &&promise_interface(F &&f) { + return std::forward(f); +} + +template >::value, bool> from_promise_interface = false> +auto promise_interface(F &&f) { + return lambda_promise(std::forward(f)); +} + +template >::value, bool> from_promise_interface = true> +auto promise_interface_ptr(F &&f) { + return std::forward(f); +} + +template >::value, bool> from_promise_interface = false> +auto promise_interface_ptr(F &&f) { + return td::make_unique(std::forward(f)))>>( + promise_interface(std::forward(f))); +} + +template +class Promise { + public: + void set_value(T &&value) { + if (!promise_) { + return; + } + promise_->set_value(std::move(value)); + promise_.reset(); + } + void set_error(Status &&error) { + if (!promise_) { + return; + } + promise_->set_error(std::move(error)); + promise_.reset(); + } + void set_result(Result &&result) { + if (!promise_) { + return; + } + promise_->set_result(std::move(result)); + promise_.reset(); + } + void reset() { + promise_.reset(); + } + bool is_cancellable() const { + if (!promise_) { + return false; + } + return promise_->is_cancellable(); + } + bool is_canceled() const { + if (!promise_) { + return false; + } + return promise_->is_canceled(); + } + unique_ptr> release() { + return std::move(promise_); + } + + Promise() = default; + explicit Promise(unique_ptr> promise) : promise_(std::move(promise)) { + } + Promise(Auto) { + } + Promise(SafePromise &&other); + Promise &operator=(SafePromise &&other); + template , Promise>::value, int> = 0> + Promise(F &&f) : promise_(promise_interface_ptr(std::forward(f))) { + } + + explicit operator bool() { + return static_cast(promise_); + } + + private: + unique_ptr> promise_; +}; + +template +class SafePromise { + public: + SafePromise(Promise promise, Result result) : promise_(std::move(promise)), result_(std::move(result)) { + } + SafePromise(const SafePromise &other) = delete; + SafePromise &operator=(const SafePromise &other) = delete; + SafePromise(SafePromise &&other) = default; + SafePromise &operator=(SafePromise &&other) = default; + ~SafePromise() { + if (promise_) { + promise_.set_result(std::move(result_)); + } + } + Promise release() { + return std::move(promise_); + } + + private: + Promise promise_; + Result result_; +}; + +template +Promise::Promise(SafePromise &&other) : Promise(other.release()) { +} + +template +Promise &Promise::operator=(SafePromise &&other) { + *this = other.release(); + return *this; +} + +namespace detail { +template +class CancellablePromise final : public PromiseT { + public: + template + CancellablePromise(CancellationToken cancellation_token, ArgsT &&...args) + : PromiseT(std::forward(args)...), cancellation_token_(std::move(cancellation_token)) { + } + bool is_cancellable() const final { + return true; + } + bool is_canceled() const final { + return static_cast(cancellation_token_); + } + + private: + CancellationToken cancellation_token_; +}; + +template +class JoinPromise final : public PromiseInterface { + public: + explicit JoinPromise(ArgsT &&...arg) : promises_(std::forward(arg)...) { + } + void set_value(Unit &&) final { + tuple_for_each(promises_, [](auto &promise) { promise.set_value(Unit()); }); + } + void set_error(Status &&error) final { + tuple_for_each(promises_, [&error](auto &promise) { promise.set_error(error.clone()); }); + } + + private: + std::tuple...> promises_; +}; +} // namespace detail + +class SendClosure { + public: + template + void operator()(ArgsT &&...args) const { + send_closure(std::forward(args)...); + } +}; + +//template +//template +//auto Promise::send_closure(ArgsT &&... args) { +// return [promise = std::move(*this), t = std::make_tuple(std::forward(args)...)](auto &&r_res) mutable { +// TRY_RESULT_PROMISE(promise, res, std::move(r_res)); +// call_tuple(SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::move(res), std::move(promise)))); +// }; +//} + +template +auto promise_send_closure(ArgsT &&...args) { + return [t = std::make_tuple(std::forward(args)...)](auto &&res) mutable { + call_tuple(SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::forward(res)))); + }; +} + +class PromiseCreator { + public: + template >> + static Promise lambda(OkT &&ok) { + return Promise(td::make_unique>>(std::forward(ok))); + } + + template >> + static auto cancellable_lambda(CancellationToken cancellation_token, OkT &&ok) { + return Promise(td::make_unique>>>( + std::move(cancellation_token), std::forward(ok))); + } + + template + static Promise<> join(ArgsT &&...args) { + return Promise<>(td::make_unique>(std::forward(args)...)); + } +}; + +inline void set_promises(vector> &promises) { + auto moved_promises = std::move(promises); + promises.clear(); + + for (auto &promise : moved_promises) { + promise.set_value(Unit()); + } +} + +template +void fail_promises(vector> &promises, Status &&error) { + CHECK(error.is_error()); + auto moved_promises = std::move(promises); + promises.clear(); + + auto size = moved_promises.size(); + if (size == 0) { + return; + } + size--; + for (size_t i = 0; i < size; i++) { + auto &promise = moved_promises[i]; + if (promise) { + promise.set_error(error.clone()); + } + } + moved_promises[size].set_error(std::move(error)); +} + +} // namespace td diff --git a/test/mtproto.cpp b/test/mtproto.cpp index 58eff4356..4f7e5c3f1 100644 --- a/test/mtproto.cpp +++ b/test/mtproto.cpp @@ -29,7 +29,6 @@ #include "td/actor/actor.h" #include "td/actor/ConcurrentScheduler.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/base64.h" #include "td/utils/BufferedFd.h" @@ -39,6 +38,7 @@ #include "td/utils/port/Clocks.h" #include "td/utils/port/IPAddress.h" #include "td/utils/port/SocketFd.h" +#include "td/utils/Promise.h" #include "td/utils/Random.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" diff --git a/test/online.cpp b/test/online.cpp index 97e39df26..50b87081e 100644 --- a/test/online.cpp +++ b/test/online.cpp @@ -12,7 +12,6 @@ #include "td/actor/actor.h" #include "td/actor/ConcurrentScheduler.h" #include "td/actor/MultiPromise.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/crypto.h" #include "td/utils/FileLog.h" @@ -21,6 +20,7 @@ #include "td/utils/OptionParser.h" #include "td/utils/port/path.h" #include "td/utils/port/signals.h" +#include "td/utils/Promise.h" #include "td/utils/Random.h" #include diff --git a/test/secret.cpp b/test/secret.cpp index bc1d03a91..3c1d351ea 100644 --- a/test/secret.cpp +++ b/test/secret.cpp @@ -26,7 +26,6 @@ #include "td/actor/actor.h" #include "td/actor/ConcurrentScheduler.h" -#include "td/actor/PromiseFuture.h" #include "td/utils/algorithm.h" #include "td/utils/as.h" @@ -38,6 +37,7 @@ #include "td/utils/Gzip.h" #include "td/utils/logging.h" #include "td/utils/misc.h" +#include "td/utils/Promise.h" #include "td/utils/Random.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" diff --git a/test/tdclient.cpp b/test/tdclient.cpp index 3a00549d6..81cb2aad4 100644 --- a/test/tdclient.cpp +++ b/test/tdclient.cpp @@ -26,6 +26,7 @@ #include "td/utils/port/path.h" #include "td/utils/port/sleep.h" #include "td/utils/port/thread.h" +#include "td/utils/Promise.h" #include "td/utils/Random.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" From 003fa6ffee88521102d9609dc0166b903e946597 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Jun 2022 10:32:56 +0300 Subject: [PATCH 26/38] Remove back template lambda support in Promise. --- tdutils/td/utils/Promise.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tdutils/td/utils/Promise.h b/tdutils/td/utils/Promise.h index 7746bc0ae..8f9c5fe71 100644 --- a/tdutils/td/utils/Promise.h +++ b/tdutils/td/utils/Promise.h @@ -92,7 +92,7 @@ class LambdaPromise : public PromiseInterface { public: void set_value(ValueT &&value) override { CHECK(state_.get() == State::Ready); - func_(std::move(value)); + do_ok(std::move(value)); state_ = State::Complete; } @@ -128,6 +128,14 @@ class LambdaPromise : public PromiseInterface { std::enable_if_t>::value, void> do_error(Y &&status) { func_(Auto()); } + template + std::enable_if_t>::value, void> do_ok(ValueT &&value) { + func_(Result(std::move(value))); + } + template + std::enable_if_t>::value, void> do_ok(ValueT &&value) { + func_(std::move(value)); + } }; } // namespace detail From 340fb779c350029cb680c3f21dad9dad167419e0 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Jun 2022 10:48:03 +0300 Subject: [PATCH 27/38] Move Promise implementation details to namespace detail. --- tdutils/td/utils/Promise.h | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/tdutils/td/utils/Promise.h b/tdutils/td/utils/Promise.h index 8f9c5fe71..072c24f0e 100644 --- a/tdutils/td/utils/Promise.h +++ b/tdutils/td/utils/Promise.h @@ -53,6 +53,12 @@ class PromiseInterface { } }; +template +class SafePromise; + +template +class Promise; + namespace detail { template @@ -137,13 +143,6 @@ class LambdaPromise : public PromiseInterface { func_(std::move(value)); } }; -} // namespace detail - -template -class SafePromise; - -template -class Promise; template struct is_promise_interface : std::false_type {}; @@ -162,12 +161,11 @@ struct is_promise_interface_ptr> : std::true_type {}; template ::value, bool> has_t = false> auto lambda_promise(F &&f) { - return detail::LambdaPromise>>, std::decay_t>( - std::forward(f)); + return LambdaPromise>>, std::decay_t>(std::forward(f)); } template ::value, bool> has_t = true> auto lambda_promise(F &&f) { - return detail::LambdaPromise>(std::forward(f)); + return LambdaPromise>(std::forward(f)); } template (std::forward(f)))>>( promise_interface(std::forward(f))); } +} // namespace detail template class Promise { @@ -246,7 +245,7 @@ class Promise { Promise(SafePromise &&other); Promise &operator=(SafePromise &&other); template , Promise>::value, int> = 0> - Promise(F &&f) : promise_(promise_interface_ptr(std::forward(f))) { + Promise(F &&f) : promise_(detail::promise_interface_ptr(std::forward(f))) { } explicit operator bool() { @@ -324,7 +323,6 @@ class JoinPromise final : public PromiseInterface { private: std::tuple...> promises_; }; -} // namespace detail class SendClosure { public: @@ -333,20 +331,21 @@ class SendClosure { send_closure(std::forward(args)...); } }; +} // namespace detail //template //template //auto Promise::send_closure(ArgsT &&... args) { // return [promise = std::move(*this), t = std::make_tuple(std::forward(args)...)](auto &&r_res) mutable { // TRY_RESULT_PROMISE(promise, res, std::move(r_res)); -// call_tuple(SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::move(res), std::move(promise)))); +// call_tuple(detail::SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::move(res), std::move(promise)))); // }; //} template auto promise_send_closure(ArgsT &&...args) { return [t = std::make_tuple(std::forward(args)...)](auto &&res) mutable { - call_tuple(SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::forward(res)))); + call_tuple(detail::SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::forward(res)))); }; } From ebebe0300ce83b729e93d227c0d9906a04a73fd6 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Jun 2022 14:02:14 +0300 Subject: [PATCH 28/38] Move promise_send_closure to PromiseFuture.h. --- td/telegram/DownloadManager.cpp | 1 + td/telegram/SequenceDispatcher.cpp | 2 ++ td/telegram/net/Session.cpp | 2 ++ tdactor/td/actor/PromiseFuture.h | 15 +++++++++++++++ tdutils/td/utils/Promise.h | 24 ------------------------ test/online.cpp | 1 + 6 files changed, 21 insertions(+), 24 deletions(-) diff --git a/td/telegram/DownloadManager.cpp b/td/telegram/DownloadManager.cpp index 88c784dc2..9912610e0 100644 --- a/td/telegram/DownloadManager.cpp +++ b/td/telegram/DownloadManager.cpp @@ -15,6 +15,7 @@ #include "td/telegram/TdParameters.h" #include "td/actor/MultiPromise.h" +#include "td/actor/PromiseFuture.h" #include "td/utils/algorithm.h" #include "td/utils/FlatHashMap.h" diff --git a/td/telegram/SequenceDispatcher.cpp b/td/telegram/SequenceDispatcher.cpp index fb01bdb94..8f46379d2 100644 --- a/td/telegram/SequenceDispatcher.cpp +++ b/td/telegram/SequenceDispatcher.cpp @@ -10,6 +10,8 @@ #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/Td.h" +#include "td/actor/PromiseFuture.h" + #include "td/utils/algorithm.h" #include "td/utils/ChainScheduler.h" #include "td/utils/format.h" diff --git a/td/telegram/net/Session.cpp b/td/telegram/net/Session.cpp index 362adc812..9693bfb19 100644 --- a/td/telegram/net/Session.cpp +++ b/td/telegram/net/Session.cpp @@ -26,6 +26,8 @@ #include "td/mtproto/SessionConnection.h" #include "td/mtproto/TransportType.h" +#include "td/actor/PromiseFuture.h" + #include "td/utils/algorithm.h" #include "td/utils/as.h" #include "td/utils/format.h" diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index 1a8940558..d2585afc2 100644 --- a/tdactor/td/actor/PromiseFuture.h +++ b/tdactor/td/actor/PromiseFuture.h @@ -51,6 +51,14 @@ class EventPromise final : public PromiseInterface { } } }; + +class SendClosure { + public: + template + void operator()(ArgsT &&...args) const { + send_closure(std::forward(args)...); + } +}; } // namespace detail inline Promise create_event_promise(EventFull &&ok) { @@ -287,6 +295,13 @@ FutureActor send_promise(ActorId actor_id, ResultT (ActorBT::*func)( return pf.move_future(); } +template +auto promise_send_closure(ArgsT &&...args) { + return [t = std::make_tuple(std::forward(args)...)](auto &&res) mutable { + call_tuple(detail::SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::forward(res)))); + }; +} + template Promise create_promise_from_promise_actor(PromiseActor &&from) { return Promise(td::make_unique>(std::move(from))); diff --git a/tdutils/td/utils/Promise.h b/tdutils/td/utils/Promise.h index 072c24f0e..252727da0 100644 --- a/tdutils/td/utils/Promise.h +++ b/tdutils/td/utils/Promise.h @@ -323,32 +323,8 @@ class JoinPromise final : public PromiseInterface { private: std::tuple...> promises_; }; - -class SendClosure { - public: - template - void operator()(ArgsT &&...args) const { - send_closure(std::forward(args)...); - } -}; } // namespace detail -//template -//template -//auto Promise::send_closure(ArgsT &&... args) { -// return [promise = std::move(*this), t = std::make_tuple(std::forward(args)...)](auto &&r_res) mutable { -// TRY_RESULT_PROMISE(promise, res, std::move(r_res)); -// call_tuple(detail::SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::move(res), std::move(promise)))); -// }; -//} - -template -auto promise_send_closure(ArgsT &&...args) { - return [t = std::make_tuple(std::forward(args)...)](auto &&res) mutable { - call_tuple(detail::SendClosure(), std::tuple_cat(std::move(t), std::make_tuple(std::forward(res)))); - }; -} - class PromiseCreator { public: template >> diff --git a/test/online.cpp b/test/online.cpp index 50b87081e..db6832886 100644 --- a/test/online.cpp +++ b/test/online.cpp @@ -12,6 +12,7 @@ #include "td/actor/actor.h" #include "td/actor/ConcurrentScheduler.h" #include "td/actor/MultiPromise.h" +#include "td/actor/PromiseFuture.h" #include "td/utils/crypto.h" #include "td/utils/FileLog.h" From 386fec3d176e0b3528a7a8bc9af4a78f889ae476 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Jun 2022 15:18:16 +0300 Subject: [PATCH 29/38] Improve LogEvent store debug. --- td/telegram/logevent/LogEvent.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/td/telegram/logevent/LogEvent.h b/td/telegram/logevent/LogEvent.h index a94c00901..d0f0a80d6 100644 --- a/td/telegram/logevent/LogEvent.h +++ b/td/telegram/logevent/LogEvent.h @@ -198,7 +198,7 @@ Status log_event_parse(T &data, Slice slice) { } template -BufferSlice log_event_store(const T &data) { +BufferSlice log_event_store_impl(const T &data, const char *file, int line) { LogEventStorerCalcLength storer_calc_length; store(data, storer_calc_length); @@ -211,11 +211,16 @@ BufferSlice log_event_store(const T &data) { #ifdef TD_DEBUG T check_result; - log_event_parse(check_result, value_buffer.as_slice()).ensure(); + auto status = log_event_parse(check_result, value_buffer.as_slice()); + if (status.is_error()) { + LOG(FATAL) << status << ' ' << file << ' ' << line; + } #endif return value_buffer; } +#define log_event_store(data) log_event_store_impl((data), __FILE__, __LINE__) + template log_event::LogEventStorerImpl get_log_event_storer(const T &event) { return log_event::LogEventStorerImpl(event); From 26fdb92dd88da42884eb4050523dc71683c0532f Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Jun 2022 15:32:05 +0300 Subject: [PATCH 30/38] Minor improvements. --- td/generate/scheme/td_api.tl | 2 +- td/telegram/MessageEntity.cpp | 4 ++-- td/telegram/MessagesManager.cpp | 4 ++-- tdactor/td/actor/PromiseFuture.h | 8 +++++++- tdutils/td/utils/Promise.h | 3 --- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 17ebb5280..c24205ade 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -6406,7 +6406,7 @@ getPremiumState = PremiumState; //@description Checks whether Telegram Premium purchase is possible. Must be called before in-store Premium purchase canPurchasePremium = Ok; -//@description Informs server about a Telegram Premium purchase through App Store. For official applications only @receipt App Store receipt @is_restore True, if this is restore of Premium purchase +//@description Informs server about a Telegram Premium purchase through App Store. For official applications only @receipt App Store receipt @is_restore Pass true if this is a restore of a Telegram Premium purchase assignAppStoreTransaction receipt:bytes is_restore:Bool = Ok; //@description Informs server about a Telegram Premium purchase through Google Play. For official applications only @purchase_token Google Play purchase token diff --git a/td/telegram/MessageEntity.cpp b/td/telegram/MessageEntity.cpp index 1f8be2831..d4c205c9c 100644 --- a/td/telegram/MessageEntity.cpp +++ b/td/telegram/MessageEntity.cpp @@ -1390,12 +1390,12 @@ static void sort_entities(vector &entities) { std::sort(entities.begin(), entities.end()); } -#define check_is_sorted(entities) check_is_sorted_impl(entities, __LINE__) +#define check_is_sorted(entities) check_is_sorted_impl((entities), __LINE__) static void check_is_sorted_impl(const vector &entities, int line) { LOG_CHECK(std::is_sorted(entities.begin(), entities.end())) << line << " " << entities; } -#define check_non_intersecting(entities) check_non_intersecting_impl(entities, __LINE__) +#define check_non_intersecting(entities) check_non_intersecting_impl((entities), __LINE__) static void check_non_intersecting_impl(const vector &entities, int line) { for (size_t i = 0; i + 1 < entities.size(); i++) { LOG_CHECK(entities[i].offset + entities[i].length <= entities[i + 1].offset) << line << " " << entities; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 9dbb6f466..7fbd01864 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -27916,8 +27916,8 @@ class MessagesManager::ForwardMessagesLogEvent { DialogId from_dialog_id; vector message_ids; vector messages_in; - bool drop_author; - bool drop_media_captions; + bool drop_author = false; + bool drop_media_captions = false; vector> messages_out; template diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index d2585afc2..5ddc6e984 100644 --- a/tdactor/td/actor/PromiseFuture.h +++ b/tdactor/td/actor/PromiseFuture.h @@ -8,12 +8,18 @@ #include "td/actor/actor.h" +#include "td/utils/Closure.h" #include "td/utils/common.h" +#include "td/utils/invoke.h" #include "td/utils/Promise.h" +#include "td/utils/ScopeGuard.h" +#include "td/utils/Status.h" + +#include +#include namespace td { namespace detail { - class EventPromise final : public PromiseInterface { public: void set_value(Unit &&) final { diff --git a/tdutils/td/utils/Promise.h b/tdutils/td/utils/Promise.h index 252727da0..1ba653094 100644 --- a/tdutils/td/utils/Promise.h +++ b/tdutils/td/utils/Promise.h @@ -7,12 +7,9 @@ #pragma once #include "td/utils/CancellationToken.h" -#include "td/utils/Closure.h" #include "td/utils/common.h" #include "td/utils/invoke.h" -#include "td/utils/logging.h" #include "td/utils/MovableValue.h" -#include "td/utils/ScopeGuard.h" #include "td/utils/Status.h" #include From faaf8f10f9d7c9917cef08cd6056d42242ff6680 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Jun 2022 16:39:32 +0300 Subject: [PATCH 31/38] Process channel PTS updates during getDifference. --- td/telegram/UpdatesManager.cpp | 15 +++++++++++++++ td/telegram/UpdatesManager.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index c020d9482..4e6b88b51 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1904,6 +1904,9 @@ void UpdatesManager::on_pending_updates(vectorget_id()) { + case telegram_api::updateNewChannelMessage::ID: + case telegram_api::updateEditChannelMessage::ID: + case telegram_api::updateDeleteChannelMessages::ID: + case telegram_api::updatePinnedChannelMessages::ID: + return true; + default: + return false; + } +} + void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { DialogId dialog_id(UserId(update->user_id_)); td_->messages_manager_->on_dialog_action(dialog_id, MessageId(), dialog_id, DialogAction(std::move(update->action_)), diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 1c72b649c..16882689a 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -357,6 +357,8 @@ class UpdatesManager final : public Actor { static int32 get_update_qts(const telegram_api::Update *update); + static bool is_channel_pts_update(const telegram_api::Update *update); + static const vector> *get_updates(const telegram_api::Updates *updates_ptr); static vector> *get_updates(telegram_api::Updates *updates_ptr); From 9ef9751f5f43568c0fc9e81b90e4b751cd350018 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Jun 2022 16:43:51 +0300 Subject: [PATCH 32/38] Immediately exit UpdatesManager::process_updates if there are no updates to process. --- td/telegram/UpdatesManager.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 4e6b88b51..8958739c1 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -2027,14 +2027,15 @@ void UpdatesManager::add_pending_qts_update(tl_object_ptr void UpdatesManager::process_updates(vector> &&updates, bool force_apply, Promise &&promise) { - tl_object_ptr update_pts_changed; - int32 update_count = 0; for (auto &update : updates) { if (update != nullptr) { update_count++; } } + if (update_count == 0) { + return promise.set_value(Unit()); + } MultiPromiseActorSafe mpas{"OnProcessUpdatesMultiPromiseActor"}; Promise lock; @@ -2070,6 +2071,8 @@ void UpdatesManager::process_updates(vector> } } */ + + tl_object_ptr update_pts_changed; for (auto &update : updates) { if (update != nullptr) { // process updateNewChannelMessage first From 70d4fd863bbe01d9d6635cc1a804c0c3854ba5d8 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Jun 2022 16:50:22 +0300 Subject: [PATCH 33/38] Avoid updates serialization if it will not be needed. --- td/telegram/UpdatesManager.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 8958739c1..b0f1f28e0 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -2293,11 +2293,14 @@ void UpdatesManager::postpone_pts_update(tl_object_ptr &&u void UpdatesManager::process_seq_updates(int32 seq_end, int32 date, vector> &&updates, Promise &&promise) { - string serialized_updates = PSTRING() << "process_seq_updates [seq_ = " << seq_ << ", seq_end = " << seq_end << "]: "; - // TODO remove after bugs will be fixed - for (auto &update : updates) { - if (update != nullptr) { - serialized_updates += oneline(to_string(update)); + string serialized_updates; + if (date && seq_end) { + serialized_updates = PSTRING() << "process_seq_updates [seq_ = " << seq_ << ", seq_end = " << seq_end << "]: "; + // TODO remove after bugs will be fixed + for (auto &update : updates) { + if (update != nullptr) { + serialized_updates += oneline(to_string(update)); + } } } process_updates(std::move(updates), false, std::move(promise)); From 2953a2ec64f5a7a7f1390c9f67c679e0cb7707d0 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Jun 2022 17:10:57 +0300 Subject: [PATCH 34/38] Ignore accidentally received web pages by bots. --- td/telegram/WebPagesManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/td/telegram/WebPagesManager.cpp b/td/telegram/WebPagesManager.cpp index dfe0bbd7a..010210dcb 100644 --- a/td/telegram/WebPagesManager.cpp +++ b/td/telegram/WebPagesManager.cpp @@ -422,6 +422,9 @@ WebPagesManager::~WebPagesManager() = default; WebPageId WebPagesManager::on_get_web_page(tl_object_ptr &&web_page_ptr, DialogId owner_dialog_id) { CHECK(web_page_ptr != nullptr); + if (td_->auth_manager_->is_bot()) { + return WebPageId(); + } LOG(DEBUG) << "Got " << to_string(web_page_ptr); switch (web_page_ptr->get_id()) { case telegram_api::webPageEmpty::ID: { From 8f472521d408600da5d46e32539b68e7550b5e36 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Jun 2022 17:22:04 +0300 Subject: [PATCH 35/38] Avoid expected logging. --- td/telegram/PollManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/td/telegram/PollManager.cpp b/td/telegram/PollManager.cpp index 7c754326c..6318c1c6b 100644 --- a/td/telegram/PollManager.cpp +++ b/td/telegram/PollManager.cpp @@ -1786,7 +1786,7 @@ void PollManager::on_get_poll_vote(PollId poll_id, UserId user_id, vector '9') { - LOG(ERROR) << "Receive updateMessagePollVote with unexpected option \"" << format::escaped(slice) << '"'; + LOG(INFO) << "Receive updateMessagePollVote with unexpected option \"" << format::escaped(slice) << '"'; return; } option_ids.push_back(static_cast(slice[0] - '0')); From e8dccae7519f222e02dfa1f5aa2b2496dfb1b733 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 28 Jun 2022 18:34:53 +0300 Subject: [PATCH 36/38] Explicitly pass ContactsManager to get_input_reply_markup/get_reply_markup_object. --- td/telegram/InlineQueriesManager.cpp | 4 ++-- td/telegram/MessagesManager.cpp | 32 +++++++++++++------------ td/telegram/PollManager.cpp | 2 +- td/telegram/ReplyMarkup.cpp | 36 ++++++++++++++-------------- td/telegram/ReplyMarkup.h | 11 +++++---- 5 files changed, 45 insertions(+), 40 deletions(-) diff --git a/td/telegram/InlineQueriesManager.cpp b/td/telegram/InlineQueriesManager.cpp index 72b978846..4624e2f88 100644 --- a/td/telegram/InlineQueriesManager.cpp +++ b/td/telegram/InlineQueriesManager.cpp @@ -349,7 +349,7 @@ Result> InlineQueriesManager: return Status::Error(400, "Inline message can't be empty"); } TRY_RESULT(reply_markup, get_reply_markup(std::move(reply_markup_ptr), true, true, false, true)); - auto input_reply_markup = get_input_reply_markup(reply_markup); + auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), reply_markup); auto constructor_id = input_message_content->get_id(); if (constructor_id == td_api::inputMessageText::ID) { @@ -694,7 +694,7 @@ Result> InlineQueriesManager:: return r_reply_markup.move_as_error(); } - auto input_reply_markup = get_input_reply_markup(r_reply_markup.ok()); + auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), r_reply_markup.ok()); int32 flags = 0; if (input_reply_markup != nullptr) { flags |= telegram_api::inputBotInlineMessageGame::REPLY_MARKUP_MASK; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 7fbd01864..857da5eb7 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -24602,7 +24602,7 @@ tl_object_ptr MessagesManager::get_message_object(DialogId dial auto edit_date = m->hide_edit_date ? 0 : m->edit_date; auto is_pinned = is_scheduled ? false : m->is_pinned; auto has_timestamped_media = for_event_log || reply_to_message_id == 0 || m->max_own_media_timestamp >= 0; - auto reply_markup = get_reply_markup_object(m->reply_markup); + auto reply_markup = get_reply_markup_object(td_->contacts_manager_.get(), m->reply_markup); auto live_location_date = m->is_failed_to_send ? 0 : m->date; auto skip_bot_commands = for_event_log ? true : need_skip_bot_commands(dialog_id, m); @@ -25725,7 +25725,7 @@ void MessagesManager::on_message_media_uploaded(DialogId dialog_id, const Messag auto message_id = m->message_id; if (message_id.is_any_server()) { const FormattedText *caption = get_message_content_caption(m->edited_content.get()); - auto input_reply_markup = get_input_reply_markup(m->edited_reply_markup); + auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), m->edited_reply_markup); bool was_uploaded = FileManager::extract_was_uploaded(input_media); bool was_thumbnail_uploaded = FileManager::extract_was_thumbnail_uploaded(input_media); @@ -25765,7 +25765,8 @@ void MessagesManager::on_message_media_uploaded(DialogId dialog_id, const Messag int64 random_id = begin_send_message(dialog_id, m); td_->create_handler()->send( file_id, thumbnail_file_id, get_message_flags(m), dialog_id, get_send_message_as_input_peer(m), - m->reply_to_message_id, get_message_schedule_date(m), get_input_reply_markup(m->reply_markup), + m->reply_to_message_id, get_message_schedule_date(m), + get_input_reply_markup(td_->contacts_manager_.get(), m->reply_markup), get_input_message_entities(td_->contacts_manager_.get(), caption, "on_message_media_uploaded"), caption == nullptr ? "" : caption->text, std::move(input_media), m->content->get_type(), m->is_copy, random_id, &m->send_query_ref); @@ -26171,7 +26172,7 @@ void MessagesManager::on_text_message_ready_to_send(DialogId dialog_id, MessageI int64 random_id = begin_send_message(dialog_id, m); td_->create_handler()->send( get_message_flags(m), dialog_id, get_send_message_as_input_peer(m), m->reply_to_message_id, - get_message_schedule_date(m), get_input_reply_markup(m->reply_markup), + get_message_schedule_date(m), get_input_reply_markup(td_->contacts_manager_.get(), m->reply_markup), get_input_message_entities(td_->contacts_manager_.get(), message_text->entities, "do_send_message"), message_text->text, m->is_copy, random_id, &m->send_query_ref); } @@ -26880,7 +26881,7 @@ void MessagesManager::edit_message_text(FullMessageId full_message_id, if (r_new_reply_markup.is_error()) { return promise.set_error(r_new_reply_markup.move_as_error()); } - auto input_reply_markup = get_input_reply_markup(r_new_reply_markup.ok()); + auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok()); int32 flags = 0; if (input_message_text.disable_web_page_preview) { flags |= SEND_MESSAGE_FLAG_DISABLE_WEB_PAGE_PREVIEW; @@ -26936,7 +26937,7 @@ void MessagesManager::edit_message_live_location(FullMessageId full_message_id, if (r_new_reply_markup.is_error()) { return promise.set_error(r_new_reply_markup.move_as_error()); } - auto input_reply_markup = get_input_reply_markup(r_new_reply_markup.ok()); + auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok()); int32 flags = 0; if (location.empty()) { @@ -27172,7 +27173,7 @@ void MessagesManager::edit_message_caption(FullMessageId full_message_id, if (r_new_reply_markup.is_error()) { return promise.set_error(r_new_reply_markup.move_as_error()); } - auto input_reply_markup = get_input_reply_markup(r_new_reply_markup.ok()); + auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok()); td_->create_handler(std::move(promise)) ->send(1 << 11, dialog_id, m->message_id, caption.text, @@ -27212,7 +27213,7 @@ void MessagesManager::edit_message_reply_markup(FullMessageId full_message_id, if (r_new_reply_markup.is_error()) { return promise.set_error(r_new_reply_markup.move_as_error()); } - auto input_reply_markup = get_input_reply_markup(r_new_reply_markup.ok()); + auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok()); td_->create_handler(std::move(promise)) ->send(0, dialog_id, m->message_id, string(), vector>(), nullptr, std::move(input_reply_markup), get_message_schedule_date(m)); @@ -27259,7 +27260,7 @@ void MessagesManager::edit_inline_message_text(const string &inline_message_id, ->send(flags, std::move(input_bot_inline_message_id), input_message_text.text.text, get_input_message_entities(td_->contacts_manager_.get(), input_message_text.text.entities, "edit_inline_message_text"), - nullptr, get_input_reply_markup(r_new_reply_markup.ok())); + nullptr, get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok())); } void MessagesManager::edit_inline_message_live_location(const string &inline_message_id, @@ -27297,7 +27298,7 @@ void MessagesManager::edit_inline_message_live_location(const string &inline_mes flags, false /*ignored*/, location.get_input_geo_point(), heading, 0, proximity_alert_radius); td_->create_handler(std::move(promise)) ->send(0, std::move(input_bot_inline_message_id), "", vector>(), - std::move(input_media), get_input_reply_markup(r_new_reply_markup.ok())); + std::move(input_media), get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok())); } void MessagesManager::edit_inline_message_media(const string &inline_message_id, @@ -27349,7 +27350,7 @@ void MessagesManager::edit_inline_message_media(const string &inline_message_id, td_->create_handler(std::move(promise)) ->send(1 << 11, std::move(input_bot_inline_message_id), caption == nullptr ? "" : caption->text, get_input_message_entities(td_->contacts_manager_.get(), caption, "edit_inline_message_media"), - std::move(input_media), get_input_reply_markup(r_new_reply_markup.ok())); + std::move(input_media), get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok())); } void MessagesManager::edit_inline_message_caption(const string &inline_message_id, @@ -27380,7 +27381,7 @@ void MessagesManager::edit_inline_message_caption(const string &inline_message_i td_->create_handler(std::move(promise)) ->send(1 << 11, std::move(input_bot_inline_message_id), caption.text, get_input_message_entities(td_->contacts_manager_.get(), caption.entities, "edit_inline_message_caption"), - nullptr, get_input_reply_markup(r_new_reply_markup.ok())); + nullptr, get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok())); } void MessagesManager::edit_inline_message_reply_markup(const string &inline_message_id, @@ -27402,7 +27403,7 @@ void MessagesManager::edit_inline_message_reply_markup(const string &inline_mess td_->create_handler(std::move(promise)) ->send(0, std::move(input_bot_inline_message_id), string(), vector>(), - nullptr, get_input_reply_markup(r_new_reply_markup.ok())); + nullptr, get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok())); } void MessagesManager::edit_message_scheduling_state( @@ -30391,8 +30392,9 @@ void MessagesManager::send_update_message_edited(DialogId dialog_id, const Messa cancel_dialog_action(dialog_id, m); auto edit_date = m->hide_edit_date ? 0 : m->edit_date; send_closure(G()->td(), &Td::send_update, - make_tl_object(dialog_id.get(), m->message_id.get(), edit_date, - get_reply_markup_object(m->reply_markup))); + make_tl_object( + dialog_id.get(), m->message_id.get(), edit_date, + get_reply_markup_object(td_->contacts_manager_.get(), m->reply_markup))); } void MessagesManager::send_update_message_interaction_info(DialogId dialog_id, const Message *m) const { diff --git a/td/telegram/PollManager.cpp b/td/telegram/PollManager.cpp index 6318c1c6b..c62aacc7c 100644 --- a/td/telegram/PollManager.cpp +++ b/td/telegram/PollManager.cpp @@ -195,7 +195,7 @@ class StopPollQuery final : public Td::ResultHandler { } int32 flags = telegram_api::messages_editMessage::MEDIA_MASK; - auto input_reply_markup = get_input_reply_markup(reply_markup); + auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), reply_markup); if (input_reply_markup != nullptr) { flags |= telegram_api::messages_editMessage::REPLY_MARKUP_MASK; } diff --git a/td/telegram/ReplyMarkup.cpp b/td/telegram/ReplyMarkup.cpp index 785e18c0b..15bfceec5 100644 --- a/td/telegram/ReplyMarkup.cpp +++ b/td/telegram/ReplyMarkup.cpp @@ -11,7 +11,6 @@ #include "td/telegram/Global.h" #include "td/telegram/LinkManager.h" #include "td/telegram/misc.h" -#include "td/telegram/Td.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" @@ -703,7 +702,7 @@ Result> get_reply_markup(tl_object_ptr get_keyboard_button(const KeyboardButton &keyboard_button) { +static tl_object_ptr get_input_keyboard_button(const KeyboardButton &keyboard_button) { switch (keyboard_button.type) { case KeyboardButton::Type::Text: return make_tl_object(keyboard_button.text); @@ -725,8 +724,8 @@ static tl_object_ptr get_keyboard_button(const Key } } -static tl_object_ptr get_inline_keyboard_button( - const InlineKeyboardButton &keyboard_button) { +static tl_object_ptr get_input_keyboard_button( + ContactsManager *contacts_manager, const InlineKeyboardButton &keyboard_button) { switch (keyboard_button.type) { case InlineKeyboardButton::Type::Url: return make_tl_object(keyboard_button.text, keyboard_button.data); @@ -757,7 +756,7 @@ static tl_object_ptr get_inline_keyboard_button( if (!keyboard_button.forward_text.empty()) { flags |= telegram_api::inputKeyboardButtonUrlAuth::FWD_TEXT_MASK; } - auto r_input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(UserId(bot_user_id)); + auto r_input_user = contacts_manager->get_input_user(UserId(bot_user_id)); if (r_input_user.is_error()) { LOG(ERROR) << "Failed to get InputUser for " << bot_user_id << ": " << r_input_user.error(); return make_tl_object(keyboard_button.text, keyboard_button.data); @@ -770,7 +769,7 @@ static tl_object_ptr get_inline_keyboard_button( UNREACHABLE(); break; case InlineKeyboardButton::Type::User: { - auto r_input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(keyboard_button.user_id); + auto r_input_user = contacts_manager->get_input_user(keyboard_button.user_id); if (r_input_user.is_error()) { LOG(ERROR) << "Failed to get InputUser for " << keyboard_button.user_id << ": " << r_input_user.error(); r_input_user = make_tl_object(); @@ -786,7 +785,7 @@ static tl_object_ptr get_inline_keyboard_button( } } -tl_object_ptr ReplyMarkup::get_input_reply_markup() const { +tl_object_ptr ReplyMarkup::get_input_reply_markup(ContactsManager *contacts_manager) const { LOG(DEBUG) << "Send " << *this; switch (type) { case ReplyMarkup::Type::InlineKeyboard: { @@ -796,7 +795,7 @@ tl_object_ptr ReplyMarkup::get_input_reply_markup() c vector> buttons; buttons.reserve(row.size()); for (auto &button : row) { - buttons.push_back(get_inline_keyboard_button(button)); + buttons.push_back(get_input_keyboard_button(contacts_manager, button)); } rows.push_back(make_tl_object(std::move(buttons))); } @@ -810,7 +809,7 @@ tl_object_ptr ReplyMarkup::get_input_reply_markup() c vector> buttons; buttons.reserve(row.size()); for (auto &button : row) { - buttons.push_back(get_keyboard_button(button)); + buttons.push_back(get_input_keyboard_button(button)); } rows.push_back(make_tl_object(std::move(buttons))); } @@ -868,7 +867,7 @@ static tl_object_ptr get_keyboard_button_object(const Ke } static tl_object_ptr get_inline_keyboard_button_object( - const InlineKeyboardButton &keyboard_button) { + ContactsManager *contacts_manager, const InlineKeyboardButton &keyboard_button) { tl_object_ptr type; switch (keyboard_button.type) { case InlineKeyboardButton::Type::Url: @@ -898,8 +897,7 @@ static tl_object_ptr get_inline_keyboard_button_ob break; case InlineKeyboardButton::Type::User: type = make_tl_object( - G()->td().get_actor_unsafe()->contacts_manager_->get_user_id_object(keyboard_button.user_id, - "get_inline_keyboard_button_object")); + contacts_manager->get_user_id_object(keyboard_button.user_id, "get_inline_keyboard_button_object")); break; case InlineKeyboardButton::Type::WebView: type = make_tl_object(keyboard_button.data); @@ -911,7 +909,7 @@ static tl_object_ptr get_inline_keyboard_button_ob return make_tl_object(keyboard_button.text, std::move(type)); } -tl_object_ptr ReplyMarkup::get_reply_markup_object() const { +tl_object_ptr ReplyMarkup::get_reply_markup_object(ContactsManager *contacts_manager) const { switch (type) { case ReplyMarkup::Type::InlineKeyboard: { vector>> rows; @@ -920,7 +918,7 @@ tl_object_ptr ReplyMarkup::get_reply_markup_object() const vector> buttons; buttons.reserve(row.size()); for (auto &button : row) { - buttons.push_back(get_inline_keyboard_button_object(button)); + buttons.push_back(get_inline_keyboard_button_object(contacts_manager, button)); } rows.push_back(std::move(buttons)); } @@ -952,20 +950,22 @@ tl_object_ptr ReplyMarkup::get_reply_markup_object() const } } -tl_object_ptr get_input_reply_markup(const unique_ptr &reply_markup) { +tl_object_ptr get_input_reply_markup(ContactsManager *contacts_manager, + const unique_ptr &reply_markup) { if (reply_markup == nullptr) { return nullptr; } - return reply_markup->get_input_reply_markup(); + return reply_markup->get_input_reply_markup(contacts_manager); } -tl_object_ptr get_reply_markup_object(const unique_ptr &reply_markup) { +tl_object_ptr get_reply_markup_object(ContactsManager *contacts_manager, + const unique_ptr &reply_markup) { if (reply_markup == nullptr) { return nullptr; } - return reply_markup->get_reply_markup_object(); + return reply_markup->get_reply_markup_object(contacts_manager); } void add_reply_markup_dependencies(Dependencies &dependencies, const ReplyMarkup *reply_markup) { diff --git a/td/telegram/ReplyMarkup.h b/td/telegram/ReplyMarkup.h index 6fb296c53..e1d7b6bba 100644 --- a/td/telegram/ReplyMarkup.h +++ b/td/telegram/ReplyMarkup.h @@ -16,6 +16,7 @@ namespace td { +class ContactsManager; class Dependencies; struct KeyboardButton { @@ -72,9 +73,9 @@ struct ReplyMarkup { StringBuilder &print(StringBuilder &string_builder) const; - tl_object_ptr get_input_reply_markup() const; + tl_object_ptr get_input_reply_markup(ContactsManager *contacts_manager) const; - tl_object_ptr get_reply_markup_object() const; + tl_object_ptr get_reply_markup_object(ContactsManager *contacts_manager) const; }; bool operator==(const ReplyMarkup &lhs, const ReplyMarkup &rhs); @@ -89,9 +90,11 @@ Result> get_reply_markup(tl_object_ptr get_input_reply_markup(const unique_ptr &reply_markup); +tl_object_ptr get_input_reply_markup(ContactsManager *contacts_manager, + const unique_ptr &reply_markup); -tl_object_ptr get_reply_markup_object(const unique_ptr &reply_markup); +tl_object_ptr get_reply_markup_object(ContactsManager *contacts_manager, + const unique_ptr &reply_markup); void add_reply_markup_dependencies(Dependencies &dependencies, const ReplyMarkup *reply_markup); From d9d76adb7caeedd462ee0299a443c28d2d5aa883 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 29 Jun 2022 11:17:22 +0300 Subject: [PATCH 37/38] Return user_id in inline keyboard as is for local and yet unsent messages. --- td/telegram/MessagesManager.cpp | 3 ++- td/telegram/ReplyMarkup.cpp | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 857da5eb7..1196c7b97 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -24602,7 +24602,8 @@ tl_object_ptr MessagesManager::get_message_object(DialogId dial auto edit_date = m->hide_edit_date ? 0 : m->edit_date; auto is_pinned = is_scheduled ? false : m->is_pinned; auto has_timestamped_media = for_event_log || reply_to_message_id == 0 || m->max_own_media_timestamp >= 0; - auto reply_markup = get_reply_markup_object(td_->contacts_manager_.get(), m->reply_markup); + auto reply_markup = + get_reply_markup_object(m->message_id.is_any_server() ? td_->contacts_manager_.get() : nullptr, m->reply_markup); auto live_location_date = m->is_failed_to_send ? 0 : m->date; auto skip_bot_commands = for_event_log ? true : need_skip_bot_commands(dialog_id, m); diff --git a/td/telegram/ReplyMarkup.cpp b/td/telegram/ReplyMarkup.cpp index 15bfceec5..356ce805d 100644 --- a/td/telegram/ReplyMarkup.cpp +++ b/td/telegram/ReplyMarkup.cpp @@ -895,10 +895,13 @@ static tl_object_ptr get_inline_keyboard_button_ob case InlineKeyboardButton::Type::CallbackWithPassword: type = make_tl_object(keyboard_button.data); break; - case InlineKeyboardButton::Type::User: - type = make_tl_object( - contacts_manager->get_user_id_object(keyboard_button.user_id, "get_inline_keyboard_button_object")); + case InlineKeyboardButton::Type::User: { + auto user_id = contacts_manager == nullptr ? keyboard_button.user_id.get() + : contacts_manager->get_user_id_object( + keyboard_button.user_id, "get_inline_keyboard_button_object"); + type = make_tl_object(user_id); break; + } case InlineKeyboardButton::Type::WebView: type = make_tl_object(keyboard_button.data); break; From aa635a89c2955dc04a7e20704bdcf5ac33725a4e Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 29 Jun 2022 15:57:59 +0300 Subject: [PATCH 38/38] Check keyboard buttons data for validness. --- td/telegram/ReplyMarkup.cpp | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/td/telegram/ReplyMarkup.cpp b/td/telegram/ReplyMarkup.cpp index 356ce805d..740bf413b 100644 --- a/td/telegram/ReplyMarkup.cpp +++ b/td/telegram/ReplyMarkup.cpp @@ -223,7 +223,12 @@ static KeyboardButton get_keyboard_button(tl_object_ptr(keyboard_button_ptr); button.type = KeyboardButton::Type::WebView; button.text = std::move(keyboard_button->text_); - button.url = std::move(keyboard_button->url_); + auto r_url = LinkManager::check_link(keyboard_button->url_); + if (r_url.is_error()) { + LOG(ERROR) << "Keyboard Web App " << r_url.error().message(); + return {}; + } + button.url = r_url.move_as_ok(); break; } default: @@ -242,7 +247,12 @@ static InlineKeyboardButton get_inline_keyboard_button( auto keyboard_button = move_tl_object_as(keyboard_button_ptr); button.type = InlineKeyboardButton::Type::Url; button.text = std::move(keyboard_button->text_); - button.data = std::move(keyboard_button->url_); + auto r_url = LinkManager::check_link(keyboard_button->url_); + if (r_url.is_error()) { + LOG(ERROR) << "Inline keyboard " << r_url.error().message(); + return {}; + } + button.data = r_url.move_as_ok(); break; } case telegram_api::keyboardButtonCallback::ID: { @@ -279,8 +289,13 @@ static InlineKeyboardButton get_inline_keyboard_button( button.type = InlineKeyboardButton::Type::UrlAuth; button.id = keyboard_button->button_id_; button.text = std::move(keyboard_button->text_); - button.data = std::move(keyboard_button->url_); button.forward_text = std::move(keyboard_button->fwd_text_); + auto r_url = LinkManager::check_link(keyboard_button->url_); + if (r_url.is_error()) { + LOG(ERROR) << "Inline keyboard Login " << r_url.error().message(); + return {}; + } + button.data = r_url.move_as_ok(); break; } case telegram_api::keyboardButtonUserProfile::ID: { @@ -288,13 +303,22 @@ static InlineKeyboardButton get_inline_keyboard_button( button.type = InlineKeyboardButton::Type::User; button.text = std::move(keyboard_button->text_); button.user_id = UserId(keyboard_button->user_id_); + if (!button.user_id.is_valid()) { + LOG(ERROR) << "Receive " << button.user_id << " in inline keyboard"; + return {}; + } break; } case telegram_api::keyboardButtonWebView::ID: { auto keyboard_button = move_tl_object_as(keyboard_button_ptr); button.type = InlineKeyboardButton::Type::WebView; button.text = std::move(keyboard_button->text_); - button.data = std::move(keyboard_button->url_); + auto r_url = LinkManager::check_link(keyboard_button->url_); + if (r_url.is_error()) { + LOG(ERROR) << "Inline keyboard Web App " << r_url.error().message(); + return {}; + } + button.data = r_url.move_as_ok(); break; } default: