From 656a6412907db5dade026954699a241fe62b69c2 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 22 Dec 2020 01:51:20 +0300 Subject: [PATCH 01/22] Fix sending response to setPollAnser. --- td/telegram/PollManager.cpp | 40 ++++++++++++++++++++-------------- td/telegram/PollManager.h | 2 ++ td/telegram/UpdatesManager.cpp | 2 +- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/td/telegram/PollManager.cpp b/td/telegram/PollManager.cpp index db9340335..2385c5b0e 100644 --- a/td/telegram/PollManager.cpp +++ b/td/telegram/PollManager.cpp @@ -844,26 +844,34 @@ void PollManager::on_set_poll_answer(PollId poll_id, uint64 generation, poll->was_saved = false; } if (result.is_ok()) { - td_->updates_manager_->on_get_updates(result.move_as_ok(), Promise()); - - for (auto &promise : promises) { - promise.set_value(Unit()); - } + td_->updates_manager_->on_get_updates( + result.move_as_ok(), PromiseCreator::lambda([actor_id = actor_id(this), poll_id, + promises = std::move(promises)](Result &&result) mutable { + send_closure(actor_id, &PollManager::on_set_poll_answer_finished, poll_id, Unit(), std::move(promises)); + })); } else { - for (auto &promise : promises) { - promise.set_error(result.error().clone()); + on_set_poll_answer_finished(poll_id, result.move_as_error(), std::move(promises)); + } +} + +void PollManager::on_set_poll_answer_finished(PollId poll_id, Result &&result, vector> &&promises) { + if (!G()->close_flag()) { + auto poll = get_poll(poll_id); + if (poll != nullptr && !poll->was_saved) { + // no updates was sent during updates processing, so send them + // poll wasn't changed, so there is no reason to actually save it + if (!(poll->is_closed && poll->is_updated_after_close)) { + LOG(INFO) << "Schedule updating of " << poll_id << " soon"; + update_poll_timeout_.set_timeout_in(poll_id.get(), 0.0); + } + + notify_on_poll_update(poll_id); + poll->was_saved = true; } } - if (poll != nullptr && !poll->was_saved) { - // no updates was sent during updates processing, so send them - // poll wasn't changed, so there is no reason to actually save it - if (!(poll->is_closed && poll->is_updated_after_close)) { - LOG(INFO) << "Schedule updating of " << poll_id << " soon"; - update_poll_timeout_.set_timeout_in(poll_id.get(), 0.0); - } - notify_on_poll_update(poll_id); - poll->was_saved = true; + for (auto &promise : promises) { + promise.set_result(result.clone()); } } diff --git a/td/telegram/PollManager.h b/td/telegram/PollManager.h index 6d8c63ff7..3af448a92 100644 --- a/td/telegram/PollManager.h +++ b/td/telegram/PollManager.h @@ -186,6 +186,8 @@ class PollManager : public Actor { void on_set_poll_answer(PollId poll_id, uint64 generation, Result> &&result); + void on_set_poll_answer_finished(PollId poll_id, Result &&result, vector> &&promises); + void invalidate_poll_voters(const Poll *poll, PollId poll_id); void invalidate_poll_option_voters(const Poll *poll, PollId poll_id, size_t option_index); diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 812cadc27..f9dbc3e22 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1258,7 +1258,7 @@ void UpdatesManager::on_pending_updates(vector Date: Tue, 22 Dec 2020 01:52:14 +0300 Subject: [PATCH 02/22] Improve documentation. --- td/generate/scheme/td_api.tl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index e8dac7221..f48261039 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3888,12 +3888,12 @@ getMessageLinkInfo url:string = MessageLinkInfo; //@reply_markup Markup for replying to the message; for bots only @input_message_content The content of the message to be sent sendMessage chat_id:int53 message_thread_id:int53 reply_to_message_id:int53 options:messageSendOptions reply_markup:ReplyMarkup input_message_content:InputMessageContent = Message; -//@description Sends messages grouped together into an album. Currently only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages +//@description Sends 2-10 messages grouped together into an album. Currently only audio, document, photo and video messages can be grouped into an album. Documents and audio files can be only grouped in an album with messages of the same type. Returns sent messages //@chat_id Target chat //@message_thread_id If not 0, a message thread identifier in which the messages will be sent //@reply_to_message_id Identifier of a message to reply to or 0 //@options Options to be used to send the messages -//@input_message_contents Contents of messages to be sent +//@input_message_contents Contents of messages to be sent. At most 10 messages can be added to an album sendMessageAlbum chat_id:int53 message_thread_id:int53 reply_to_message_id:int53 options:messageSendOptions input_message_contents:vector = Messages; //@description Invites a bot to a chat (if it is not yet a member) and sends it the /start command. Bots can't be invited to a private chat other than the chat with the bot. Bots can't be invited to channels (although they can be added as admins) and secret chats. Returns the sent message @@ -3910,7 +3910,9 @@ sendBotStartMessage bot_user_id:int32 chat_id:int53 parameter:string = Message; sendInlineQueryResultMessage chat_id:int53 message_thread_id:int53 reply_to_message_id:int53 options:messageSendOptions query_id:int64 result_id:string hide_via_bot:Bool = Message; //@description Forwards previously sent messages. Returns the forwarded messages in the same order as the message identifiers passed in message_ids. If a message can't be forwarded, null will be returned instead of the message -//@chat_id Identifier of the chat to which to forward messages @from_chat_id Identifier of the chat from which to forward messages @message_ids Identifiers of the messages to forward. Message identifiers must be in a strictly increasing order +//@chat_id Identifier of the chat to which to forward messages +//@from_chat_id Identifier of the chat from which to forward messages +//@message_ids Identifiers of the messages to forward. Message identifiers must be in a strictly increasing order. At most 100 messages can be forwarded simultaneously //@options Options to be used to send the messages //@send_copy True, if content of the messages needs to be copied without links to the original messages. Always true if the messages are forwarded to a secret chat //@remove_caption True, if media caption of message copies needs to be removed. Ignored if send_copy is false From f55363852144d42ef54eda820ed8a1090752d167 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 22 Dec 2020 01:56:36 +0300 Subject: [PATCH 03/22] Use full path in tdtl includes. --- tdtl/td/tl/tl_config.cpp | 2 +- tdtl/td/tl/tl_config.h | 4 ++-- tdtl/td/tl/tl_core.cpp | 2 +- tdtl/td/tl/tl_file_outputer.cpp | 2 +- tdtl/td/tl/tl_file_outputer.h | 2 +- tdtl/td/tl/tl_file_utils.cpp | 2 +- tdtl/td/tl/tl_generate.cpp | 14 +++++++------- tdtl/td/tl/tl_generate.h | 6 +++--- tdtl/td/tl/tl_outputer.cpp | 2 +- tdtl/td/tl/tl_string_outputer.cpp | 2 +- tdtl/td/tl/tl_string_outputer.h | 2 +- tdtl/td/tl/tl_writer.cpp | 4 ++-- tdtl/td/tl/tl_writer.h | 2 +- 13 files changed, 23 insertions(+), 23 deletions(-) diff --git a/tdtl/td/tl/tl_config.cpp b/tdtl/td/tl/tl_config.cpp index bfe03875c..9e49a146a 100644 --- a/tdtl/td/tl/tl_config.cpp +++ b/tdtl/td/tl/tl_config.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_config.h" +#include "td/tl/tl_config.h" #include #include diff --git a/tdtl/td/tl/tl_config.h b/tdtl/td/tl/tl_config.h index afc3cb442..b05b31686 100644 --- a/tdtl/td/tl/tl_config.h +++ b/tdtl/td/tl/tl_config.h @@ -6,8 +6,8 @@ // #pragma once -#include "tl_core.h" -#include "tl_simple_parser.h" +#include "td/tl/tl_core.h" +#include "td/tl/tl_simple_parser.h" #include #include diff --git a/tdtl/td/tl/tl_core.cpp b/tdtl/td/tl/tl_core.cpp index 9e1c2bf61..f59f27d07 100644 --- a/tdtl/td/tl/tl_core.cpp +++ b/tdtl/td/tl/tl_core.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_core.h" +#include "td/tl/tl_core.h" #include diff --git a/tdtl/td/tl/tl_file_outputer.cpp b/tdtl/td/tl/tl_file_outputer.cpp index d27574a0f..9a57f07ba 100644 --- a/tdtl/td/tl/tl_file_outputer.cpp +++ b/tdtl/td/tl/tl_file_outputer.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_file_outputer.h" +#include "td/tl/tl_file_outputer.h" #include diff --git a/tdtl/td/tl/tl_file_outputer.h b/tdtl/td/tl/tl_file_outputer.h index d58b658ad..0ff34bbf0 100644 --- a/tdtl/td/tl/tl_file_outputer.h +++ b/tdtl/td/tl/tl_file_outputer.h @@ -6,7 +6,7 @@ // #pragma once -#include "tl_outputer.h" +#include "td/tl/tl_outputer.h" #include #include diff --git a/tdtl/td/tl/tl_file_utils.cpp b/tdtl/td/tl/tl_file_utils.cpp index b31a8d8b9..9ffc646a0 100644 --- a/tdtl/td/tl/tl_file_utils.cpp +++ b/tdtl/td/tl/tl_file_utils.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_file_utils.h" +#include "td/tl/tl_file_utils.h" #include #include diff --git a/tdtl/td/tl/tl_generate.cpp b/tdtl/td/tl/tl_generate.cpp index 9e3647431..9120e5e52 100644 --- a/tdtl/td/tl/tl_generate.cpp +++ b/tdtl/td/tl/tl_generate.cpp @@ -4,14 +4,14 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_generate.h" +#include "td/tl/tl_generate.h" -#include "tl_config.h" -#include "tl_core.h" -#include "tl_file_utils.h" -#include "tl_outputer.h" -#include "tl_string_outputer.h" -#include "tl_writer.h" +#include "td/tl/tl_config.h" +#include "td/tl/tl_core.h" +#include "td/tl/tl_file_utils.h" +#include "td/tl/tl_outputer.h" +#include "td/tl/tl_string_outputer.h" +#include "td/tl/tl_writer.h" #include #include diff --git a/tdtl/td/tl/tl_generate.h b/tdtl/td/tl/tl_generate.h index 96e3d8c35..795d38524 100644 --- a/tdtl/td/tl/tl_generate.h +++ b/tdtl/td/tl/tl_generate.h @@ -6,9 +6,9 @@ // #pragma once -#include "tl_config.h" -#include "tl_outputer.h" -#include "tl_writer.h" +#include "td/tl/tl_config.h" +#include "td/tl/tl_outputer.h" +#include "td/tl/tl_writer.h" #include diff --git a/tdtl/td/tl/tl_outputer.cpp b/tdtl/td/tl/tl_outputer.cpp index 3fae22107..b6e9f9bd1 100644 --- a/tdtl/td/tl/tl_outputer.cpp +++ b/tdtl/td/tl/tl_outputer.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_outputer.h" +#include "td/tl/tl_outputer.h" namespace td { namespace tl { diff --git a/tdtl/td/tl/tl_string_outputer.cpp b/tdtl/td/tl/tl_string_outputer.cpp index 0894b084b..cdafc2fca 100644 --- a/tdtl/td/tl/tl_string_outputer.cpp +++ b/tdtl/td/tl/tl_string_outputer.cpp @@ -4,7 +4,7 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_string_outputer.h" +#include "td/tl/tl_string_outputer.h" namespace td { namespace tl { diff --git a/tdtl/td/tl/tl_string_outputer.h b/tdtl/td/tl/tl_string_outputer.h index b343f49e2..ac9ce98e7 100644 --- a/tdtl/td/tl/tl_string_outputer.h +++ b/tdtl/td/tl/tl_string_outputer.h @@ -6,7 +6,7 @@ // #pragma once -#include "tl_outputer.h" +#include "td/tl/tl_outputer.h" #include diff --git a/tdtl/td/tl/tl_writer.cpp b/tdtl/td/tl/tl_writer.cpp index ad918d222..63581ba36 100644 --- a/tdtl/td/tl/tl_writer.cpp +++ b/tdtl/td/tl/tl_writer.cpp @@ -4,9 +4,9 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "tl_writer.h" +#include "td/tl/tl_writer.h" -#include "tl_core.h" +#include "td/tl/tl_core.h" #include #include diff --git a/tdtl/td/tl/tl_writer.h b/tdtl/td/tl/tl_writer.h index e2b9a88a1..08d3dc0c0 100644 --- a/tdtl/td/tl/tl_writer.h +++ b/tdtl/td/tl/tl_writer.h @@ -6,7 +6,7 @@ // #pragma once -#include "tl_core.h" +#include "td/tl/tl_core.h" #include #include From b89cb3fbd68563ece08842c897f72eb87ea45f33 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 22 Dec 2020 02:09:08 +0300 Subject: [PATCH 04/22] Fix misprint. --- td/telegram/StickersManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 287f4d2f3..b6f738996 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1501,7 +1501,7 @@ vector> StickersManager::get_sticke case 'm': case 'M': pos--; - // falltrough + // fallthrough case 'z': case 'Z': if (x != start_x || y != start_y) { From 3589676550057dacd51873e9572b88fe58959258 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 22 Dec 2020 15:51:57 +0300 Subject: [PATCH 05/22] Minor fixes. --- CMakeLists.txt | 1 + td/generate/scheme/td_api.tl | 2 +- td/telegram/ContactsManager.cpp | 1 - td/telegram/GroupCallManager.cpp | 8 ++++++-- td/telegram/GroupCallManager.h | 2 ++ td/telegram/GroupCallParticipant.cpp | 2 ++ td/telegram/InputGroupCallId.cpp | 3 --- td/telegram/StickersManager.cpp | 2 ++ td/telegram/Td.cpp | 1 + tdactor/td/actor/ConcurrentScheduler.cpp | 1 + tdactor/td/actor/PromiseFuture.h | 1 + test/tdclient.cpp | 20 ++++++++++---------- test/tqueue.cpp | 10 ++++------ 13 files changed, 31 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b03c28a4..bb81b3b88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -494,6 +494,7 @@ set(TDLIB_SOURCE td/telegram/FullMessageId.h td/telegram/Game.h td/telegram/Global.h + td/telegram/GroupCallId.h td/telegram/GroupCallManager.h td/telegram/GroupCallParticipant.h td/telegram/HashtagHints.h diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index f48261039..be6b7afda 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3225,7 +3225,7 @@ messageStatistics message_interaction_graph:StatisticalGraph = MessageStatistics point x:double y:double = Point; -//@class VectorPathCommand @description Reperesents a vector path command +//@class VectorPathCommand @description Represents a vector path command //@description A straight line to a given point @end_point The end point of the straight line vectorPathCommandLine end_point:point = VectorPathCommand; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 9aed8083e..e83f31856 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -19,7 +19,6 @@ #include "td/telegram/files/FileType.h" #include "td/telegram/FolderId.h" #include "td/telegram/Global.h" -#include "td/telegram/GroupCallManager.h" #include "td/telegram/InlineQueriesManager.h" #include "td/telegram/InputGroupCallId.h" #include "td/telegram/logevent/LogEvent.h" diff --git a/td/telegram/GroupCallManager.cpp b/td/telegram/GroupCallManager.cpp index 8d50a1751..379c0ea27 100644 --- a/td/telegram/GroupCallManager.cpp +++ b/td/telegram/GroupCallManager.cpp @@ -6,21 +6,25 @@ // #include "td/telegram/GroupCallManager.h" +#include "td/telegram/AccessRights.h" #include "td/telegram/AuthManager.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/DialogParticipant.h" #include "td/telegram/Global.h" +#include "td/telegram/MessageId.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/Td.h" #include "td/telegram/UpdatesManager.h" -#include "td/actor/MultiPromise.h" - +#include "td/utils/buffer.h" #include "td/utils/JsonBuilder.h" +#include "td/utils/misc.h" #include "td/utils/Random.h" +#include +#include #include #include diff --git a/td/telegram/GroupCallManager.h b/td/telegram/GroupCallManager.h index 8fec9b725..fbd0dca24 100644 --- a/td/telegram/GroupCallManager.h +++ b/td/telegram/GroupCallManager.h @@ -18,6 +18,8 @@ #include "td/actor/PromiseFuture.h" #include "td/actor/Timeout.h" +#include "td/utils/common.h" +#include "td/utils/logging.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/GroupCallParticipant.cpp b/td/telegram/GroupCallParticipant.cpp index 95a3cbb7a..4e0dbb70f 100644 --- a/td/telegram/GroupCallParticipant.cpp +++ b/td/telegram/GroupCallParticipant.cpp @@ -8,6 +8,8 @@ #include "td/telegram/ContactsManager.h" +#include "td/utils/logging.h" + namespace td { GroupCallParticipant::GroupCallParticipant(const tl_object_ptr &participant) { diff --git a/td/telegram/InputGroupCallId.cpp b/td/telegram/InputGroupCallId.cpp index 977585ad7..87e418321 100644 --- a/td/telegram/InputGroupCallId.cpp +++ b/td/telegram/InputGroupCallId.cpp @@ -6,9 +6,6 @@ // #include "td/telegram/InputGroupCallId.h" -#include "td/utils/logging.h" -#include "td/utils/misc.h" - namespace td { InputGroupCallId::InputGroupCallId(const tl_object_ptr &input_group_call) diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index b6f738996..148b90675 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -47,6 +47,8 @@ #include "td/utils/PathView.h" #include "td/utils/Random.h" #include "td/utils/Slice.h" +#include "td/utils/StackAllocator.h" +#include "td/utils/StringBuilder.h" #include "td/utils/Time.h" #include "td/utils/tl_helpers.h" #include "td/utils/utf8.h" diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index de6233e5d..5b31c42c1 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -43,6 +43,7 @@ #include "td/telegram/FolderId.h" #include "td/telegram/FullMessageId.h" #include "td/telegram/Global.h" +#include "td/telegram/GroupCallId.h" #include "td/telegram/GroupCallManager.h" #include "td/telegram/HashtagHints.h" #include "td/telegram/InlineQueriesManager.h" diff --git a/tdactor/td/actor/ConcurrentScheduler.cpp b/tdactor/td/actor/ConcurrentScheduler.cpp index 1b1e70093..4c41d92bd 100644 --- a/tdactor/td/actor/ConcurrentScheduler.cpp +++ b/tdactor/td/actor/ConcurrentScheduler.cpp @@ -9,6 +9,7 @@ #include "td/utils/ExitGuard.h" #include "td/utils/MpscPollableQueue.h" #include "td/utils/port/thread_local.h" +#include "td/utils/ScopeGuard.h" #include diff --git a/tdactor/td/actor/PromiseFuture.h b/tdactor/td/actor/PromiseFuture.h index e6ffbc8f5..8afcadf6e 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" // for tuple_for_each +#include "td/utils/MovableValue.h" #include "td/utils/ScopeGuard.h" #include "td/utils/Status.h" diff --git a/test/tdclient.cpp b/test/tdclient.cpp index 46f731d4e..0ad3cebda 100644 --- a/test/tdclient.cpp +++ b/test/tdclient.cpp @@ -162,7 +162,7 @@ class TestClient : public td::Actor { td::Promise<> close_promise_; }; -class Task : public TestClient::Listener { +class TestClinetTask : public TestClient::Listener { public: void on_update(std::shared_ptr update) override { auto it = sent_queries_.find(update->id); @@ -198,7 +198,7 @@ class Task : public TestClient::Listener { } }; -class DoAuthentication : public Task { +class DoAuthentication : public TestClinetTask { public: DoAuthentication(td::string name, td::string phone, td::string code, td::Promise<> promise) : name_(std::move(name)), phone_(std::move(phone)), code_(std::move(code)), promise_(std::move(promise)) { @@ -274,7 +274,7 @@ class DoAuthentication : public Task { } }; -class SetUsername : public Task { +class SetUsername : public TestClinetTask { public: SetUsername(td::string username, td::Promise<> promise) : username_(std::move(username)), promise_(std::move(promise)) { @@ -339,7 +339,7 @@ class SetUsername : public Task { } }; -class CheckTestA : public Task { +class CheckTestA : public TestClinetTask { public: CheckTestA(td::string tag, td::Promise<> promise) : tag_(std::move(tag)), promise_(std::move(promise)) { } @@ -371,7 +371,7 @@ class CheckTestA : public Task { } }; -class TestA : public Task { +class TestA : public TestClinetTask { public: TestA(td::string tag, td::string username) : tag_(std::move(tag)), username_(std::move(username)) { } @@ -397,7 +397,7 @@ class TestA : public Task { td::string username_; }; -class TestSecretChat : public Task { +class TestSecretChat : public TestClinetTask { public: TestSecretChat(td::string tag, td::string username) : tag_(std::move(tag)), username_(std::move(username)) { } @@ -448,7 +448,7 @@ class TestSecretChat : public Task { td::int64 chat_id_ = 0; }; -class TestFileGenerated : public Task { +class TestFileGenerated : public TestClinetTask { public: TestFileGenerated(td::string tag, td::string username) : tag_(std::move(tag)), username_(std::move(username)) { } @@ -514,7 +514,7 @@ class TestFileGenerated : public Task { class GenerateFile : public td::Actor { public: - GenerateFile(Task *parent, td::int64 id, td::string original_path, td::string destination_path, + GenerateFile(TestClinetTask *parent, td::int64 id, td::string original_path, td::string destination_path, td::string conversion) : parent_(parent) , id_(id) @@ -524,7 +524,7 @@ class TestFileGenerated : public Task { } private: - Task *parent_; + TestClinetTask *parent_; td::int64 id_; td::string original_path_; td::string destination_path_; @@ -589,7 +589,7 @@ class TestFileGenerated : public Task { td::int64 chat_id_ = 0; }; -class CheckTestC : public Task { +class CheckTestC : public TestClinetTask { public: CheckTestC(td::string username, td::string tag, td::Promise<> promise) : username_(std::move(username)), tag_(std::move(tag)), promise_(std::move(promise)) { diff --git a/test/tqueue.cpp b/test/tqueue.cpp index 828491a2e..5d6eff2ac 100644 --- a/test/tqueue.cpp +++ b/test/tqueue.cpp @@ -10,18 +10,16 @@ #include "td/db/TQueue.h" #include "td/utils/buffer.h" +#include "td/utils/common.h" #include "td/utils/int_types.h" -#include "td/utils/misc.h" -#include "td/utils/port/path.h" +#include "td/utils/logging.h" #include "td/utils/Random.h" #include "td/utils/Slice.h" #include "td/utils/Span.h" -#include "td/utils/Status.h" #include "td/utils/tests.h" -#include "td/utils/VectorQueue.h" -#include -#include +#include +#include TEST(TQueue, hands) { td::TQueue::Event events[100]; From abdc727a0f10f71347aace7d2dd94c06a6422c63 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 22 Dec 2020 17:46:00 +0300 Subject: [PATCH 06/22] Improve OpenSSL 3.0 compatibility. --- benchmark/bench_crypto.cpp | 4 ++ tdutils/td/utils/BigNum.cpp | 7 +++- tdutils/td/utils/crypto.cpp | 80 ++++++++++++++++++++++++++++++++----- 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/benchmark/bench_crypto.cpp b/benchmark/bench_crypto.cpp index ce880b8db..7b87b477d 100644 --- a/benchmark/bench_crypto.cpp +++ b/benchmark/bench_crypto.cpp @@ -28,6 +28,7 @@ static constexpr int DATA_SIZE = 8 << 10; static constexpr int SHORT_DATA_SIZE = 64; +#if OPENSSL_VERSION_NUMBER <= 0x10100000L class SHA1Bench : public td::Benchmark { public: alignas(64) unsigned char data[DATA_SIZE]; @@ -50,6 +51,7 @@ class SHA1Bench : public td::Benchmark { } } }; +#endif class AesEcbBench : public td::Benchmark { public: @@ -433,7 +435,9 @@ int main() { td::bench(SslRandBench()); #endif td::bench(SslRandBufBench()); +#if OPENSSL_VERSION_NUMBER <= 0x10100000L td::bench(SHA1Bench()); +#endif td::bench(Crc32Bench()); td::bench(Crc64Bench()); } diff --git a/tdutils/td/utils/BigNum.cpp b/tdutils/td/utils/BigNum.cpp index 7b3e2ed82..cadf7d074 100644 --- a/tdutils/td/utils/BigNum.cpp +++ b/tdutils/td/utils/BigNum.cpp @@ -147,7 +147,12 @@ bool BigNum::is_bit_set(int num) const { } bool BigNum::is_prime(BigNumContext &context) const { - int result = BN_is_prime_ex(impl_->big_num, BN_prime_checks, context.impl_->big_num_context, nullptr); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int result = BN_check_prime(impl_->big_num, context.impl_->big_num_context, nullptr); +#else + int result = + BN_is_prime_ex(impl_->big_num, get_num_bits() > 2048 ? 128 : 64, context.impl_->big_num_context, nullptr); +#endif LOG_IF(FATAL, result == -1); return result == 1; } diff --git a/tdutils/td/utils/crypto.cpp b/tdutils/td/utils/crypto.cpp index febab300d..7c5d9744e 100644 --- a/tdutils/td/utils/crypto.cpp +++ b/tdutils/td/utils/crypto.cpp @@ -674,21 +674,47 @@ void AesCtrState::decrypt(Slice from, MutableSlice to) { encrypt(from, to); } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +static void make_digest(Slice data, MutableSlice output, const EVP_MD *evp_md) { + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + LOG_IF(FATAL, ctx == nullptr); + int res = EVP_DigestInit_ex(ctx, evp_md, nullptr); + LOG_IF(FATAL, res != 1); + res = EVP_DigestUpdate(ctx, data.ubegin(), data.size()); + LOG_IF(FATAL, res != 1); + res = EVP_DigestFinal_ex(ctx, output.ubegin(), nullptr); + LOG_IF(FATAL, res != 1); + EVP_MD_CTX_free(ctx); +} +#endif + void sha1(Slice data, unsigned char output[20]) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + make_digest(data, MutableSlice(output, 20), EVP_sha1()); +#else auto result = SHA1(data.ubegin(), data.size(), output); CHECK(result == output); +#endif } void sha256(Slice data, MutableSlice output) { CHECK(output.size() >= 32); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + make_digest(data, output, EVP_sha256()); +#else auto result = SHA256(data.ubegin(), data.size(), output.ubegin()); CHECK(result == output.ubegin()); +#endif } void sha512(Slice data, MutableSlice output) { CHECK(output.size() >= 64); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + make_digest(data, output, EVP_sha512()); +#else auto result = SHA512(data.ubegin(), data.size(), output.ubegin()); CHECK(result == output.ubegin()); +#endif } string sha256(Slice data) { @@ -705,7 +731,27 @@ string sha512(Slice data) { class Sha256State::Impl { public: +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MD_CTX *ctx_; + + Impl() { + ctx_ = EVP_MD_CTX_new(); + LOG_IF(FATAL, ctx_ == nullptr); + } + ~Impl() { + CHECK(ctx_ != nullptr); + EVP_MD_CTX_free(ctx_); + } +#else SHA256_CTX ctx_; + Impl() = default; + ~Impl() = default; +#endif + + Impl(const Impl &from) = delete; + Impl &operator=(const Impl &from) = delete; + Impl(Impl &&from) = delete; + Impl &operator=(Impl &&from) = delete; }; Sha256State::Sha256State() = default; @@ -737,7 +783,11 @@ void Sha256State::init() { impl_ = make_unique(); } CHECK(!is_inited_); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int err = EVP_DigestInit_ex(impl_->ctx_, EVP_sha256(), nullptr); +#else int err = SHA256_Init(&impl_->ctx_); +#endif LOG_IF(FATAL, err != 1); is_inited_ = true; } @@ -745,7 +795,11 @@ void Sha256State::init() { void Sha256State::feed(Slice data) { CHECK(impl_); CHECK(is_inited_); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int err = EVP_DigestUpdate(impl_->ctx_, data.ubegin(), data.size()); +#else int err = SHA256_Update(&impl_->ctx_, data.ubegin(), data.size()); +#endif LOG_IF(FATAL, err != 1); } @@ -753,7 +807,11 @@ void Sha256State::extract(MutableSlice output, bool destroy) { CHECK(output.size() >= 32); CHECK(impl_); CHECK(is_inited_); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int err = EVP_DigestFinal_ex(impl_->ctx_, output.ubegin(), nullptr); +#else int err = SHA256_Final(output.ubegin(), &impl_->ctx_); +#endif LOG_IF(FATAL, err != 1); is_inited_ = false; if (destroy) { @@ -762,9 +820,13 @@ void Sha256State::extract(MutableSlice output, bool destroy) { } void md5(Slice input, MutableSlice output) { - CHECK(output.size() >= MD5_DIGEST_LENGTH); + CHECK(output.size() >= 16); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + make_digest(input, output, EVP_md5()); +#else auto result = MD5(input.ubegin(), input.size(), output.ubegin()); CHECK(result == output.ubegin()); +#endif } static void pbkdf2_impl(Slice password, Slice salt, int iteration_count, MutableSlice dest, const EVP_MD *evp_md) { @@ -812,22 +874,22 @@ void pbkdf2_sha512(Slice password, Slice salt, int iteration_count, MutableSlice pbkdf2_impl(password, salt, iteration_count, dest, EVP_sha512()); } -void hmac_sha256(Slice key, Slice message, MutableSlice dest) { - CHECK(dest.size() == 256 / 8); +void hmac_impl(const EVP_MD *evp_md, Slice key, Slice message, MutableSlice dest) { unsigned int len = 0; - auto result = HMAC(EVP_sha256(), key.ubegin(), narrow_cast(key.size()), message.ubegin(), + auto result = HMAC(evp_md, key.ubegin(), narrow_cast(key.size()), message.ubegin(), narrow_cast(message.size()), dest.ubegin(), &len); CHECK(result == dest.ubegin()); CHECK(len == dest.size()); } +void hmac_sha256(Slice key, Slice message, MutableSlice dest) { + CHECK(dest.size() == 256 / 8); + hmac_impl(EVP_sha256(), key, message, dest); +} + void hmac_sha512(Slice key, Slice message, MutableSlice dest) { CHECK(dest.size() == 512 / 8); - unsigned int len = 0; - auto result = HMAC(EVP_sha512(), key.ubegin(), narrow_cast(key.size()), message.ubegin(), - narrow_cast(message.size()), dest.ubegin(), &len); - CHECK(result == dest.ubegin()); - CHECK(len == dest.size()); + hmac_impl(EVP_sha512(), key, message, dest); } static int get_evp_pkey_type(EVP_PKEY *pkey) { From 9985f6db6a15127750e9ab16a79434f4c7287b88 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 22 Dec 2020 17:54:35 +0300 Subject: [PATCH 07/22] Add HMAC tests. --- tdutils/test/crypto.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tdutils/test/crypto.cpp b/tdutils/test/crypto.cpp index cfa46d1a6..907806694 100644 --- a/tdutils/test/crypto.cpp +++ b/tdutils/test/crypto.cpp @@ -303,6 +303,32 @@ TEST(Crypto, md5) { ASSERT_STREQ(answers[i], td::base64_encode(output)); } } + +TEST(Crypto, hmac_sha256) { + td::vector answers{ + "t33rfT85UOe6N00BhsNwobE+f2TnW331HhdvQ4GdJp8=", "BQl5HF2jqhCz4JTqhAs+H364oxboh7QlluOMHuuRVh8=", + "NCCPuZBsAPBd/qr3SyeYE+e1RNgzkKJCS/+eXDBw8zU=", "mo3ahTkyLKfoQoYA0s7vRZULuH++vqwFJD0U5n9HHw0="}; + + for (std::size_t i = 0; i < strings.size(); i++) { + td::string output(32, '\0'); + td::hmac_sha256("cucumber", strings[i], output); + ASSERT_STREQ(answers[i], td::base64_encode(output)); + } +} + +TEST(Crypto, hmac_sha512) { + td::vector answers{ + "o28hTN1m/TGlm/VYxDIzOdUE4wMpQzO8hVcTkiP2ezEJXtrOvCjRnl20aOV1S8axA5Te0TzIjfIoEAtpzamIsA==", + "32X3GslSz0HDznSrCNt++ePRcFVSUSD+tfOVannyxS+yLt/om11qILCE64RFTS8/B84gByMzC3FuAlfcIam/KA==", + "BVqe5rK1Fg1i+C7xXTAzT9vDPcf3kQQpTtse6rT/EVDzKo9AUo4ZwyUyJ0KcLHoffIjul/TuJoBg+wLz7Z7r7g==", + "WASmeku5Pcfz7N0Kp4Q3I9sxtO2MiaBXA418CY0HvjdtmAo7QY+K3E0o9UemgGzz41KqeypzRC92MwOAOnXJLA=="}; + + for (std::size_t i = 0; i < strings.size(); i++) { + td::string output(64, '\0'); + td::hmac_sha512("cucumber", strings[i], output); + ASSERT_STREQ(answers[i], td::base64_encode(output)); + } +} #endif #if TD_HAVE_ZLIB From 7d1e5bca553fda802bd2455a80a21f32a49d97d1 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 22 Dec 2020 19:24:26 +0300 Subject: [PATCH 08/22] Reimplement HMAC for OpenSSL 3.0.0. --- tdutils/td/utils/crypto.cpp | 44 ++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/tdutils/td/utils/crypto.cpp b/tdutils/td/utils/crypto.cpp index 7c5d9744e..cf1c0effe 100644 --- a/tdutils/td/utils/crypto.cpp +++ b/tdutils/td/utils/crypto.cpp @@ -28,11 +28,17 @@ #include #include #include +#include #include #include #include #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#include +#endif + #if TD_HAVE_ZLIB #include #endif @@ -874,22 +880,58 @@ void pbkdf2_sha512(Slice password, Slice salt, int iteration_count, MutableSlice pbkdf2_impl(password, salt, iteration_count, dest, EVP_sha512()); } -void hmac_impl(const EVP_MD *evp_md, Slice key, Slice message, MutableSlice dest) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +static void hmac_impl(const char *digest, Slice key, Slice message, MutableSlice dest) { + EVP_MAC *hmac = EVP_MAC_fetch(nullptr, "HMAC", nullptr); + LOG_IF(FATAL, hmac == nullptr); + + EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(hmac); + LOG_IF(FATAL, ctx == nullptr); + + OSSL_PARAM params[3]; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, const_cast(digest), 0); + params[1] = + OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, const_cast(key.ubegin()), key.size()); + params[2] = OSSL_PARAM_construct_end(); + + int res = EVP_MAC_CTX_set_params(ctx, params); + LOG_IF(FATAL, res != 1); + res = EVP_MAC_init(ctx); + LOG_IF(FATAL, res != 1); + res = EVP_MAC_update(ctx, message.ubegin(), message.size()); + LOG_IF(FATAL, res != 1); + res = EVP_MAC_final(ctx, dest.ubegin(), nullptr, dest.size()); + LOG_IF(FATAL, res != 1); + + EVP_MAC_CTX_free(ctx); + EVP_MAC_free(hmac); +} +#else +static void hmac_impl(const EVP_MD *evp_md, Slice key, Slice message, MutableSlice dest) { unsigned int len = 0; auto result = HMAC(evp_md, key.ubegin(), narrow_cast(key.size()), message.ubegin(), narrow_cast(message.size()), dest.ubegin(), &len); CHECK(result == dest.ubegin()); CHECK(len == dest.size()); } +#endif void hmac_sha256(Slice key, Slice message, MutableSlice dest) { CHECK(dest.size() == 256 / 8); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + hmac_impl("SHA256", key, message, dest); +#else hmac_impl(EVP_sha256(), key, message, dest); +#endif } void hmac_sha512(Slice key, Slice message, MutableSlice dest) { CHECK(dest.size() == 512 / 8); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + hmac_impl("SHA512", key, message, dest); +#else hmac_impl(EVP_sha512(), key, message, dest); +#endif } static int get_evp_pkey_type(EVP_PKEY *pkey) { From 03bb56ae96f231edddefff50154c94de8f5efa23 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 22 Dec 2020 22:28:04 +0300 Subject: [PATCH 09/22] Add RSA test. --- td/mtproto/RSA.cpp | 3 ++- test/mtproto.cpp | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/td/mtproto/RSA.cpp b/td/mtproto/RSA.cpp index a5825c2a6..33922b4c1 100644 --- a/td/mtproto/RSA.cpp +++ b/td/mtproto/RSA.cpp @@ -104,6 +104,7 @@ size_t RSA::encrypt(unsigned char *from, size_t from_len, size_t max_from_len, u CHECK(chunks * 256 <= to_len); Random::secure_bytes(from + from_len, pad); + size_t result = chunks * 256; BigNumContext ctx; BigNum y; while (chunks-- > 0) { @@ -112,7 +113,7 @@ size_t RSA::encrypt(unsigned char *from, size_t from_len, size_t max_from_len, u MutableSlice(to, 256).copy_from(y.to_binary(256)); to += 256; } - return chunks * 256; + return result; } void RSA::decrypt_signature(Slice from, MutableSlice to) const { diff --git a/test/mtproto.cpp b/test/mtproto.cpp index 873933291..8aca9dccd 100644 --- a/test/mtproto.cpp +++ b/test/mtproto.cpp @@ -711,3 +711,22 @@ TEST(Mtproto, TlsTransport) { } sched.finish(); } + +TEST(Mtproto, RSA) { + auto pem = td::Slice( + "-----BEGIN RSA PUBLIC KEY-----\n" + "MIIBCgKCAQEAr4v4wxMDXIaMOh8bayF/NyoYdpcysn5EbjTIOZC0RkgzsRj3SGlu\n" + "52QSz+ysO41dQAjpFLgxPVJoOlxXokaOq827IfW0bGCm0doT5hxtedu9UCQKbE8j\n" + "lDOk+kWMXHPZFJKWRgKgTu9hcB3y3Vk+JFfLpq3d5ZB48B4bcwrRQnzkx5GhWOFX\n" + "x73ZgjO93eoQ2b/lDyXxK4B4IS+hZhjzezPZTI5upTRbs5ljlApsddsHrKk6jJNj\n" + "8Ygs/ps8e6ct82jLXbnndC9s8HjEvDvBPH9IPjv5JUlmHMBFZ5vFQIfbpo0u0+1P\n" + "n6bkEi5o7/ifoyVv2pAZTRwppTz0EuXD8QIDAQAB\n" + "-----END RSA PUBLIC KEY-----"); + auto rsa = RSA::from_pem_public_key(pem).move_as_ok(); + ASSERT_EQ(-7596991558377038078, rsa.get_fingerprint()); + ASSERT_EQ(256u, rsa.size()); + + string s(255, '\0'); + string to(256, '\0'); + ASSERT_EQ(256u, rsa.encrypt(MutableSlice(s).ubegin(), 10, 255, MutableSlice(to).ubegin(), 256)); +} From 6d6d1b20b6db1b61fe99256aa95321acdcdba13d Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 22 Dec 2020 23:26:15 +0300 Subject: [PATCH 10/22] Reimplement RSA for OpenSSL 3.0.0. --- td/mtproto/RSA.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/td/mtproto/RSA.cpp b/td/mtproto/RSA.cpp index 33922b4c1..57287c42a 100644 --- a/td/mtproto/RSA.cpp +++ b/td/mtproto/RSA.cpp @@ -20,8 +20,11 @@ #include #include +#include #include +#if OPENSSL_VERSION_NUMBER < 0x30000000L #include +#endif namespace td { @@ -44,25 +47,55 @@ Result RSA::from_pem_public_key(Slice pem) { BIO_free(bio); }; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY *rsa = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr); +#else auto rsa = PEM_read_bio_RSAPublicKey(bio, nullptr, nullptr, nullptr); +#endif if (rsa == nullptr) { - return Status::Error("Error while reading rsa pubkey"); + return Status::Error("Error while reading RSA public key"); } SCOPE_EXIT { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_free(rsa); +#else RSA_free(rsa); +#endif }; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (!EVP_PKEY_is_a(rsa, "RSA")) { + return Status::Error("Key is not an RSA key"); + } + if (EVP_PKEY_size(rsa) != 256) { + return Status::Error("EVP_PKEY_size != 256"); + } +#else if (RSA_size(rsa) != 256) { return Status::Error("RSA_size != 256"); } +#endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BIGNUM *n_num = nullptr; + BIGNUM *e_num = nullptr; + + int res = EVP_PKEY_get_bn_param(rsa, "n", &n_num); + CHECK(res == 1 && n_num != nullptr); + res = EVP_PKEY_get_bn_param(rsa, "e", &e_num); + CHECK(res == 1 && e_num != nullptr); + + auto n = static_cast(n_num); + auto e = static_cast(e_num); +#else const BIGNUM *n_num; const BIGNUM *e_num; -#if OPENSSL_VERSION_NUMBER < 0x10100000L + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + RSA_get0_key(rsa, &n_num, &e_num, nullptr); +#else n_num = rsa->n; e_num = rsa->e; -#else - RSA_get0_key(rsa, &n_num, &e_num, nullptr); #endif auto n = static_cast(BN_dup(n_num)); @@ -70,6 +103,7 @@ Result RSA::from_pem_public_key(Slice pem) { if (n == nullptr || e == nullptr) { return Status::Error("Cannot dup BIGNUM"); } +#endif return RSA(BigNum::from_raw(n), BigNum::from_raw(e)); } From b9d1530c782faa479a9d44e95a411be95779b6a5 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 23 Dec 2020 01:58:56 +0300 Subject: [PATCH 11/22] Store all promises for pending qts updates. --- td/telegram/UpdatesManager.cpp | 33 +++++++++++++++++++++------------ td/telegram/UpdatesManager.h | 2 +- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index f9dbc3e22..86146b937 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1119,17 +1119,24 @@ void UpdatesManager::on_get_difference(tl_object_ptrseq_; if (!pending_seq_updates_.empty()) { LOG(WARNING) << "Drop " << pending_seq_updates_.size() << " pending seq updates after receive empty difference"; - for (auto &pending_update : pending_seq_updates_) { + auto pending_seq_updates = std::move(pending_seq_updates_); + pending_seq_updates_.clear(); + + for (auto &pending_update : pending_seq_updates) { pending_update.second.promise.set_value(Unit()); } - pending_seq_updates_.clear(); } if (!pending_qts_updates_.empty()) { LOG(WARNING) << "Drop " << pending_qts_updates_.size() << " pending qts updates after receive empty difference"; - for (auto &pending_update : pending_qts_updates_) { - pending_update.second.promise.set_value(Unit()); - } + auto pending_qts_updates = std::move(pending_qts_updates_); pending_qts_updates_.clear(); + + for (auto &pending_update : pending_qts_updates) { + auto promises = std::move(pending_update.second.promises); + for (auto &promise : promises) { + promise.set_value(Unit()); + } + } } break; } @@ -1446,10 +1453,8 @@ void UpdatesManager::on_pending_updates(vectorsecond.promise.set_value(Unit()); // TODO - } + LOG_IF(WARNING, pending_seq_updates_.find(seq_begin) != pending_seq_updates_.end()) + << "Already have pending updates with seq = " << seq_begin << ", but receive it again from " << source; pending_seq_updates_.emplace(seq_begin, PendingUpdates(seq_begin, seq_end, date, std::move(updates), mpas.get_promise())); @@ -1492,10 +1497,9 @@ void UpdatesManager::add_pending_qts_update(tl_object_ptr auto &pending_update = pending_qts_updates_[qts]; if (pending_update.update != nullptr) { LOG(WARNING) << "Receive duplicate update with qts = " << qts; - pending_update.promise.set_value(Unit()); // TODO } pending_update.update = std::move(update); - pending_update.promise = std::move(promise); + pending_update.promises.push_back(std::move(promise)); return; } @@ -1644,7 +1648,12 @@ void UpdatesManager::process_pending_qts_updates() { break; } if (qts == get_qts() + 1) { - process_qts_update(std::move(update_it->second.update), qts, std::move(update_it->second.promise)); + auto promise = PromiseCreator::lambda([promises = std::move(update_it->second.promises)](Unit) mutable { + for (auto &promise : promises) { + promise.set_value(Unit()); + } + }); + process_qts_update(std::move(update_it->second.update), qts, std::move(promise)); } pending_qts_updates_.erase(update_it); } diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 6ed66e9c5..c98a6737f 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -103,7 +103,7 @@ class UpdatesManager : public Actor { class PendingQtsUpdate { public: tl_object_ptr update; - Promise promise; + vector> promises; }; Td *td_; From 887c2dfdf70377e954894787f575cb66962cc3f9 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 23 Dec 2020 02:06:45 +0300 Subject: [PATCH 12/22] Properly set promise when ignore pending updates. --- 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 86146b937..c0ffbe72d 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1624,6 +1624,7 @@ void UpdatesManager::process_pending_seq_updates() { LOG_IF(ERROR, update_it->second.seq_end > seq_) << "Strange updates coming with seq_begin = " << seq_begin << ", seq_end = " << update_it->second.seq_end << ", but seq = " << seq_; + update_it->second.promise.set_value(Unit()); } pending_seq_updates_.erase(update_it); } @@ -1647,13 +1648,15 @@ void UpdatesManager::process_pending_qts_updates() { if (qts > get_qts() + 1) { break; } + auto promise = PromiseCreator::lambda([promises = std::move(update_it->second.promises)](Unit) mutable { + for (auto &promise : promises) { + promise.set_value(Unit()); + } + }); if (qts == get_qts() + 1) { - auto promise = PromiseCreator::lambda([promises = std::move(update_it->second.promises)](Unit) mutable { - for (auto &promise : promises) { - promise.set_value(Unit()); - } - }); process_qts_update(std::move(update_it->second.update), qts, std::move(promise)); + } else { + promise.set_value(Unit()); } pending_qts_updates_.erase(update_it); } From 28ce6974ceb2c6bc91fac38e857827b77d988df3 Mon Sep 17 00:00:00 2001 From: Egor Pugin Date: Wed, 23 Dec 2020 10:41:56 +0300 Subject: [PATCH 13/22] Remove extra include dir part. (#1336) --- td/telegram/logevent/LogEventHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/td/telegram/logevent/LogEventHelper.cpp b/td/telegram/logevent/LogEventHelper.cpp index 7c4efbb13..ced436ceb 100644 --- a/td/telegram/logevent/LogEventHelper.cpp +++ b/td/telegram/logevent/LogEventHelper.cpp @@ -9,7 +9,7 @@ #include "td/telegram/Global.h" #include "td/telegram/TdDb.h" -#include "tddb/td/db/binlog/BinlogHelper.h" +#include "td/db/binlog/BinlogHelper.h" #include "td/utils/logging.h" #include "td/utils/Status.h" From 7c14b3b8816fbb1f1de8d0ac96fadfe3bb14fb6f Mon Sep 17 00:00:00 2001 From: Fela Ameghino Date: Wed, 23 Dec 2020 09:25:27 +0100 Subject: [PATCH 14/22] Use *FromApp methods when available (#1303) --- tdutils/CMakeLists.txt | 1 + tdutils/td/utils/port/FileFd.cpp | 3 +- tdutils/td/utils/port/FromApp.h | 115 +++++++++++++++++++++++++++++++ tdutils/td/utils/port/path.cpp | 22 ++++++ 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 tdutils/td/utils/port/FromApp.h diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index fb5a22129..4711822db 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -123,6 +123,7 @@ set(TDUTILS_SOURCE td/utils/port/EventFd.h td/utils/port/EventFdBase.h td/utils/port/FileFd.h + td/utils/port/FromApp.h td/utils/port/IPAddress.h td/utils/port/IoSlice.h td/utils/port/MemoryMapping.h diff --git a/tdutils/td/utils/port/FileFd.cpp b/tdutils/td/utils/port/FileFd.cpp index 634dacb64..9795128eb 100644 --- a/tdutils/td/utils/port/FileFd.cpp +++ b/tdutils/td/utils/port/FileFd.cpp @@ -7,6 +7,7 @@ #include "td/utils/port/FileFd.h" #if TD_PORT_WINDOWS +#include "td/utils/port/FromApp.h" #include "td/utils/port/Stat.h" #include "td/utils/port/wstring_convert.h" #endif @@ -211,7 +212,7 @@ Result FileFd::open(CSlice filepath, int32 flags, int32 mode) { extended_parameters.dwSize = sizeof(extended_parameters); extended_parameters.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; extended_parameters.dwFileFlags = native_flags; - auto handle = CreateFile2(w_filepath.c_str(), desired_access, share_mode, creation_disposition, &extended_parameters); + auto handle = td::CreateFile2FromAppW(w_filepath.c_str(), desired_access, share_mode, creation_disposition, &extended_parameters); #endif if (handle == INVALID_HANDLE_VALUE) { return OS_ERROR(PSLICE() << "File \"" << filepath << "\" can't be " << PrintFlags{flags}); diff --git a/tdutils/td/utils/port/FromApp.h b/tdutils/td/utils/port/FromApp.h new file mode 100644 index 000000000..d969ad34b --- /dev/null +++ b/tdutils/td/utils/port/FromApp.h @@ -0,0 +1,115 @@ +#pragma once +#include "td/utils/common.h" + +#ifdef TD_PORT_WINDOWS +#include +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) +inline HMODULE GetKernelModule() { + static HMODULE kernelModule; + if (kernelModule == nullptr) { + MEMORY_BASIC_INFORMATION mbi; + if (VirtualQuery(VirtualQuery, &mbi, sizeof(MEMORY_BASIC_INFORMATION))) { + kernelModule = reinterpret_cast(mbi.AllocationBase); + } + } + + return kernelModule; +} + +inline HMODULE LoadLibrary(LPCTSTR lpFileName) { + typedef HMODULE(WINAPI * pLoadLibrary)(_In_ LPCTSTR); + static const auto procLoadLibrary = reinterpret_cast(GetProcAddress(GetKernelModule(), "LoadLibraryW")); + + return procLoadLibrary(lpFileName); +} + +inline HMODULE GetFromAppModule() { + static const HMODULE fromAppModule = LoadLibrary(L"api-ms-win-core-file-fromapp-l1-1-0.dll"); + return fromAppModule; +} + +namespace td { +inline HANDLE CreateFile2FromAppW(_In_ LPCWSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, + _In_ DWORD dwCreationDisposition, + _In_opt_ LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams) { + using pCreateFile2FromAppW = + HANDLE(WINAPI *)(_In_ LPCWSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, + _In_ DWORD dwCreationDisposition, _In_opt_ LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams); + static const auto createFile2FromAppW = + reinterpret_cast(GetProcAddress(GetFromAppModule(), "CreateFile2FromAppW")); + if (createFile2FromAppW != nullptr) { + return createFile2FromAppW(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams); + } + + return CreateFile2(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams); +} + +inline BOOL CreateDirectoryFromAppW(_In_ LPCWSTR lpPathName, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes) { + using pCreateDirectoryFromAppW = + BOOL(WINAPI *)(_In_ LPCWSTR lpPathName, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes); + static const auto createDirectoryFromAppW = + reinterpret_cast(GetProcAddress(GetFromAppModule(), "CreateDirectoryFromAppW")); + if (createDirectoryFromAppW != nullptr) { + return createDirectoryFromAppW(lpPathName, lpSecurityAttributes); + } + + return CreateDirectoryW(lpPathName, lpSecurityAttributes); +} + +inline BOOL RemoveDirectoryFromAppW(_In_ LPCWSTR lpPathName) { + using pRemoveDirectoryFromAppW = BOOL(WINAPI *)(_In_ LPCWSTR lpPathName); + static const auto removeDirectoryFromAppW = + reinterpret_cast(GetProcAddress(GetFromAppModule(), "RemoveDirectoryFromAppW")); + if (removeDirectoryFromAppW != nullptr) { + return removeDirectoryFromAppW(lpPathName); + } + + return RemoveDirectoryW(lpPathName); +} + +inline BOOL DeleteFileFromAppW(_In_ LPCWSTR lpFileName) { + using pDeleteFileFromAppW = BOOL(WINAPI *)(_In_ LPCWSTR lpFileName); + static const auto deleteFileFromAppW = + reinterpret_cast(GetProcAddress(GetFromAppModule(), "DeleteFileFromAppW")); + if (deleteFileFromAppW != nullptr) { + return deleteFileFromAppW(lpFileName); + } + + return DeleteFileW(lpFileName); +} + +inline BOOL MoveFileExFromAppW(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) { + using pMoveFileFromAppW = BOOL(WINAPI *)(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName); + static const auto moveFileFromAppW = + reinterpret_cast(GetProcAddress(GetFromAppModule(), "MoveFileFromAppW")); + if (moveFileFromAppW != nullptr) { + if (dwFlags == MOVEFILE_REPLACE_EXISTING) { + DeleteFileFromAppW(lpNewFileName); + } + + return moveFileFromAppW(lpExistingFileName, lpNewFileName); + } + + return MoveFileEx(lpExistingFileName, lpNewFileName, dwFlags); +} + +inline HANDLE FindFirstFileExFromAppW(_In_ LPCWSTR lpFileName, _In_ FINDEX_INFO_LEVELS fInfoLevelId, + _Out_writes_bytes_(sizeof(WIN32_FIND_DATAW)) LPVOID lpFindFileData, + _In_ FINDEX_SEARCH_OPS fSearchOp, _Reserved_ LPVOID lpSearchFilter, + _In_ DWORD dwAdditionalFlags) { + using pFindFirstFileExFromAppW = HANDLE(WINAPI *)(_In_ LPCWSTR lpFileName, _In_ FINDEX_INFO_LEVELS fInfoLevelId, + _Out_writes_bytes_(sizeof(WIN32_FIND_DATAW)) LPVOID lpFindFileData, + _In_ FINDEX_SEARCH_OPS fSearchOp, _Reserved_ LPVOID lpSearchFilter, + _In_ DWORD dwAdditionalFlags); + static const auto findFirstFileExFromAppW = + reinterpret_cast(GetProcAddress(GetFromAppModule(), "FindFirstFileExFromAppW")); + if (findFirstFileExFromAppW != nullptr) { + return findFirstFileExFromAppW(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, + dwAdditionalFlags); + } + + return FindFirstFileExW(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); +} +} // namespace td +#endif +#endif diff --git a/tdutils/td/utils/port/path.cpp b/tdutils/td/utils/port/path.cpp index 5935d5ed1..f2f53c69d 100644 --- a/tdutils/td/utils/port/path.cpp +++ b/tdutils/td/utils/port/path.cpp @@ -14,6 +14,7 @@ #include "td/utils/ScopeGuard.h" #if TD_PORT_WINDOWS +#include "td/utils/port/FromApp.h" #include "td/utils/port/wstring_convert.h" #include "td/utils/Random.h" #endif @@ -390,7 +391,11 @@ Status WalkPath::do_run(CSlice path, const detail::WalkFunction &func) { Status mkdir(CSlice dir, int32 mode) { TRY_RESULT(wdir, to_wstring(dir)); +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) auto status = CreateDirectoryW(wdir.c_str(), nullptr); +#else + auto status = td::CreateDirectoryFromAppW(wdir.c_str(), nullptr); +#endif if (status == 0 && GetLastError() != ERROR_ALREADY_EXISTS) { return OS_ERROR(PSLICE() << "Can't create directory \"" << dir << '"'); } @@ -400,7 +405,11 @@ Status mkdir(CSlice dir, int32 mode) { Status rename(CSlice from, CSlice to) { TRY_RESULT(wfrom, to_wstring(from)); TRY_RESULT(wto, to_wstring(to)); +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) auto status = MoveFileExW(wfrom.c_str(), wto.c_str(), MOVEFILE_REPLACE_EXISTING); +#else + auto status = td::MoveFileExFromAppW(wfrom.c_str(), wto.c_str(), MOVEFILE_REPLACE_EXISTING); +#endif if (status == 0) { return OS_ERROR(PSLICE() << "Can't rename \"" << from << "\" to \"" << to << '\"'); } @@ -443,7 +452,11 @@ Status chdir(CSlice dir) { Status rmdir(CSlice dir) { TRY_RESULT(wdir, to_wstring(dir)); +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) int status = RemoveDirectoryW(wdir.c_str()); +#else + int status = td::RemoveDirectoryFromAppW(wdir.c_str()); +#endif if (!status) { return OS_ERROR(PSLICE() << "Can't delete directory \"" << dir << '"'); } @@ -452,7 +465,11 @@ Status rmdir(CSlice dir) { Status unlink(CSlice path) { TRY_RESULT(wpath, to_wstring(path)); +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) int status = DeleteFileW(wpath.c_str()); +#else + int status = td::DeleteFileFromAppW(wpath.c_str()); +#endif if (!status) { return OS_ERROR(PSLICE() << "Can't unlink \"" << path << '"'); } @@ -549,7 +566,12 @@ static Result walk_path_dir(const std::wstring &dir_name, const std::function &func) { std::wstring name = dir_name + L"\\*"; WIN32_FIND_DATA file_data; +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) auto handle = FindFirstFileExW(name.c_str(), FindExInfoStandard, &file_data, FindExSearchNameMatch, nullptr, 0); +#else + auto handle = + td::FindFirstFileExFromAppW(name.c_str(), FindExInfoStandard, &file_data, FindExSearchNameMatch, nullptr, 0); +#endif if (handle == INVALID_HANDLE_VALUE) { return OS_ERROR(PSLICE() << "FindFirstFileEx" << tag("name", from_wstring(name).ok())); } From d628f9fa02fb93f5a257d8f16b947cfe01979b05 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 23 Dec 2020 18:08:34 +0300 Subject: [PATCH 15/22] FromApp method fixes. --- tdutils/td/utils/port/FileFd.cpp | 3 +- tdutils/td/utils/port/FromApp.h | 121 ++++++++++++------------------- tdutils/td/utils/port/path.cpp | 20 ----- 3 files changed, 50 insertions(+), 94 deletions(-) diff --git a/tdutils/td/utils/port/FileFd.cpp b/tdutils/td/utils/port/FileFd.cpp index 9795128eb..274595b87 100644 --- a/tdutils/td/utils/port/FileFd.cpp +++ b/tdutils/td/utils/port/FileFd.cpp @@ -212,7 +212,8 @@ Result FileFd::open(CSlice filepath, int32 flags, int32 mode) { extended_parameters.dwSize = sizeof(extended_parameters); extended_parameters.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; extended_parameters.dwFileFlags = native_flags; - auto handle = td::CreateFile2FromAppW(w_filepath.c_str(), desired_access, share_mode, creation_disposition, &extended_parameters); + auto handle = td::CreateFile2FromAppW(w_filepath.c_str(), desired_access, share_mode, creation_disposition, + &extended_parameters); #endif if (handle == INVALID_HANDLE_VALUE) { return OS_ERROR(PSLICE() << "File \"" << filepath << "\" can't be " << PrintFlags{flags}); diff --git a/tdutils/td/utils/port/FromApp.h b/tdutils/td/utils/port/FromApp.h index d969ad34b..16627b6e0 100644 --- a/tdutils/td/utils/port/FromApp.h +++ b/tdutils/td/utils/port/FromApp.h @@ -1,115 +1,90 @@ #pragma once + #include "td/utils/common.h" #ifdef TD_PORT_WINDOWS -#include + +namespace td { + #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) inline HMODULE GetKernelModule() { - static HMODULE kernelModule; - if (kernelModule == nullptr) { + static const auto kernel_module = []() -> HMODULE { MEMORY_BASIC_INFORMATION mbi; if (VirtualQuery(VirtualQuery, &mbi, sizeof(MEMORY_BASIC_INFORMATION))) { - kernelModule = reinterpret_cast(mbi.AllocationBase); + return reinterpret_cast(mbi.AllocationBase); } - } - - return kernelModule; + return nullptr; + }(); + return kernel_module; } inline HMODULE LoadLibrary(LPCTSTR lpFileName) { - typedef HMODULE(WINAPI * pLoadLibrary)(_In_ LPCTSTR); - static const auto procLoadLibrary = reinterpret_cast(GetProcAddress(GetKernelModule(), "LoadLibraryW")); - - return procLoadLibrary(lpFileName); + using pLoadLibrary = HMODULE(WINAPI *)(_In_ LPCTSTR); + static const auto proc_load_library = + reinterpret_cast(GetProcAddress(GetKernelModule(), "LoadLibraryW")); + return proc_load_library(lpFileName); } inline HMODULE GetFromAppModule() { - static const HMODULE fromAppModule = LoadLibrary(L"api-ms-win-core-file-fromapp-l1-1-0.dll"); - return fromAppModule; + static const HMODULE from_app_module = LoadLibrary(L"api-ms-win-core-file-fromapp-l1-1-0.dll"); + return from_app_module; +} +#endif + +template +T *get_from_app_function(const char *name, T *original_func) { +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + return original_func; +#else + static T *func = [name, original_func]() -> T * { + auto func_pointer = GetProcAddress(GetFromAppModule(), name); + if (func_pointer == nullptr) { + return original_func; + } + return reinterpret_cast(func_pointer); + }(); + return func; +#endif } -namespace td { inline HANDLE CreateFile2FromAppW(_In_ LPCWSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, _In_ DWORD dwCreationDisposition, _In_opt_ LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams) { - using pCreateFile2FromAppW = - HANDLE(WINAPI *)(_In_ LPCWSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, - _In_ DWORD dwCreationDisposition, _In_opt_ LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams); - static const auto createFile2FromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "CreateFile2FromAppW")); - if (createFile2FromAppW != nullptr) { - return createFile2FromAppW(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams); - } - - return CreateFile2(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams); + auto func = get_from_app_function<0>("CreateFile2FromAppW", &CreateFile2); + return func(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams); } inline BOOL CreateDirectoryFromAppW(_In_ LPCWSTR lpPathName, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes) { - using pCreateDirectoryFromAppW = - BOOL(WINAPI *)(_In_ LPCWSTR lpPathName, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes); - static const auto createDirectoryFromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "CreateDirectoryFromAppW")); - if (createDirectoryFromAppW != nullptr) { - return createDirectoryFromAppW(lpPathName, lpSecurityAttributes); - } - - return CreateDirectoryW(lpPathName, lpSecurityAttributes); + auto func = get_from_app_function<1>("CreateDirectoryFromAppW", &CreateDirectory); + return func(lpPathName, lpSecurityAttributes); } inline BOOL RemoveDirectoryFromAppW(_In_ LPCWSTR lpPathName) { - using pRemoveDirectoryFromAppW = BOOL(WINAPI *)(_In_ LPCWSTR lpPathName); - static const auto removeDirectoryFromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "RemoveDirectoryFromAppW")); - if (removeDirectoryFromAppW != nullptr) { - return removeDirectoryFromAppW(lpPathName); - } - - return RemoveDirectoryW(lpPathName); + auto func = get_from_app_function<2>("RemoveDirectoryFromAppW", &RemoveDirectory); + return func(lpPathName); } inline BOOL DeleteFileFromAppW(_In_ LPCWSTR lpFileName) { - using pDeleteFileFromAppW = BOOL(WINAPI *)(_In_ LPCWSTR lpFileName); - static const auto deleteFileFromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "DeleteFileFromAppW")); - if (deleteFileFromAppW != nullptr) { - return deleteFileFromAppW(lpFileName); - } - - return DeleteFileW(lpFileName); + auto func = get_from_app_function<3>("DeleteFileFromAppW", &DeleteFile); + return func(lpFileName); } inline BOOL MoveFileExFromAppW(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) { - using pMoveFileFromAppW = BOOL(WINAPI *)(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName); - static const auto moveFileFromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "MoveFileFromAppW")); - if (moveFileFromAppW != nullptr) { - if (dwFlags == MOVEFILE_REPLACE_EXISTING) { - DeleteFileFromAppW(lpNewFileName); - } - - return moveFileFromAppW(lpExistingFileName, lpNewFileName); + auto func = get_from_app_function<4>("MoveFileFromAppW", &MoveFileEx); + if (func != &MoveFileEx && (dwFlags & MOVEFILE_REPLACE_EXISTING) != 0) { + td::DeleteFileFromAppW(lpNewFileName); } - - return MoveFileEx(lpExistingFileName, lpNewFileName, dwFlags); + return func(lpExistingFileName, lpNewFileName, dwFlags); } inline HANDLE FindFirstFileExFromAppW(_In_ LPCWSTR lpFileName, _In_ FINDEX_INFO_LEVELS fInfoLevelId, _Out_writes_bytes_(sizeof(WIN32_FIND_DATAW)) LPVOID lpFindFileData, _In_ FINDEX_SEARCH_OPS fSearchOp, _Reserved_ LPVOID lpSearchFilter, _In_ DWORD dwAdditionalFlags) { - using pFindFirstFileExFromAppW = HANDLE(WINAPI *)(_In_ LPCWSTR lpFileName, _In_ FINDEX_INFO_LEVELS fInfoLevelId, - _Out_writes_bytes_(sizeof(WIN32_FIND_DATAW)) LPVOID lpFindFileData, - _In_ FINDEX_SEARCH_OPS fSearchOp, _Reserved_ LPVOID lpSearchFilter, - _In_ DWORD dwAdditionalFlags); - static const auto findFirstFileExFromAppW = - reinterpret_cast(GetProcAddress(GetFromAppModule(), "FindFirstFileExFromAppW")); - if (findFirstFileExFromAppW != nullptr) { - return findFirstFileExFromAppW(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, - dwAdditionalFlags); - } - - return FindFirstFileExW(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); + auto func = get_from_app_function<5>("FindFirstFileExFromAppW", &FindFirstFileEx); + return func(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); } + } // namespace td -#endif + #endif diff --git a/tdutils/td/utils/port/path.cpp b/tdutils/td/utils/port/path.cpp index f2f53c69d..58bfb1792 100644 --- a/tdutils/td/utils/port/path.cpp +++ b/tdutils/td/utils/port/path.cpp @@ -391,11 +391,7 @@ Status WalkPath::do_run(CSlice path, const detail::WalkFunction &func) { Status mkdir(CSlice dir, int32 mode) { TRY_RESULT(wdir, to_wstring(dir)); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) - auto status = CreateDirectoryW(wdir.c_str(), nullptr); -#else auto status = td::CreateDirectoryFromAppW(wdir.c_str(), nullptr); -#endif if (status == 0 && GetLastError() != ERROR_ALREADY_EXISTS) { return OS_ERROR(PSLICE() << "Can't create directory \"" << dir << '"'); } @@ -405,11 +401,7 @@ Status mkdir(CSlice dir, int32 mode) { Status rename(CSlice from, CSlice to) { TRY_RESULT(wfrom, to_wstring(from)); TRY_RESULT(wto, to_wstring(to)); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) - auto status = MoveFileExW(wfrom.c_str(), wto.c_str(), MOVEFILE_REPLACE_EXISTING); -#else auto status = td::MoveFileExFromAppW(wfrom.c_str(), wto.c_str(), MOVEFILE_REPLACE_EXISTING); -#endif if (status == 0) { return OS_ERROR(PSLICE() << "Can't rename \"" << from << "\" to \"" << to << '\"'); } @@ -452,11 +444,7 @@ Status chdir(CSlice dir) { Status rmdir(CSlice dir) { TRY_RESULT(wdir, to_wstring(dir)); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) - int status = RemoveDirectoryW(wdir.c_str()); -#else int status = td::RemoveDirectoryFromAppW(wdir.c_str()); -#endif if (!status) { return OS_ERROR(PSLICE() << "Can't delete directory \"" << dir << '"'); } @@ -465,11 +453,7 @@ Status rmdir(CSlice dir) { Status unlink(CSlice path) { TRY_RESULT(wpath, to_wstring(path)); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) - int status = DeleteFileW(wpath.c_str()); -#else int status = td::DeleteFileFromAppW(wpath.c_str()); -#endif if (!status) { return OS_ERROR(PSLICE() << "Can't unlink \"" << path << '"'); } @@ -566,12 +550,8 @@ static Result walk_path_dir(const std::wstring &dir_name, const std::function &func) { std::wstring name = dir_name + L"\\*"; WIN32_FIND_DATA file_data; -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) - auto handle = FindFirstFileExW(name.c_str(), FindExInfoStandard, &file_data, FindExSearchNameMatch, nullptr, 0); -#else auto handle = td::FindFirstFileExFromAppW(name.c_str(), FindExInfoStandard, &file_data, FindExSearchNameMatch, nullptr, 0); -#endif if (handle == INVALID_HANDLE_VALUE) { return OS_ERROR(PSLICE() << "FindFirstFileEx" << tag("name", from_wstring(name).ok())); } From c80b566c4939ccf2e6d8baf5c9d10b42b435ffb6 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 23 Dec 2020 19:25:01 +0300 Subject: [PATCH 16/22] Fix tdweb build. --- tdactor/td/actor/ConcurrentScheduler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tdactor/td/actor/ConcurrentScheduler.cpp b/tdactor/td/actor/ConcurrentScheduler.cpp index 4c41d92bd..e6b45aec2 100644 --- a/tdactor/td/actor/ConcurrentScheduler.cpp +++ b/tdactor/td/actor/ConcurrentScheduler.cpp @@ -138,10 +138,12 @@ void ConcurrentScheduler::finish() { #endif if (ExitGuard::is_exited()) { +#if !TD_THREAD_UNSUPPORTED && !TD_EVENTFD_UNSUPPORTED // prevent closing of schedulers from already killed by OS threads for (auto &thread : threads_) { thread.detach(); } +#endif #if TD_PORT_WINDOWS iocp_->interrupt_loop(); From 0787c642ce158753e86ca760121b0e9632dbeba4 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 23 Dec 2020 19:38:58 +0300 Subject: [PATCH 17/22] Fix dlog_print usage on Tizen. --- tdutils/td/utils/logging.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tdutils/td/utils/logging.cpp b/tdutils/td/utils/logging.cpp index 06c38b69f..099a25dd4 100644 --- a/tdutils/td/utils/logging.cpp +++ b/tdutils/td/utils/logging.cpp @@ -203,19 +203,19 @@ class DefaultLog : public LogInterface { #elif TD_TIZEN switch (log_level) { case VERBOSITY_NAME(FATAL): - dlog_print(DLOG_ERROR, DLOG_TAG, slice.c_str()); + dlog_print(DLOG_ERROR, DLOG_TAG, "%s", slice.c_str()); break; case VERBOSITY_NAME(ERROR): - dlog_print(DLOG_ERROR, DLOG_TAG, slice.c_str()); + dlog_print(DLOG_ERROR, DLOG_TAG, "%s", slice.c_str()); break; case VERBOSITY_NAME(WARNING): - dlog_print(DLOG_WARN, DLOG_TAG, slice.c_str()); + dlog_print(DLOG_WARN, DLOG_TAG, "%s", slice.c_str()); break; case VERBOSITY_NAME(INFO): - dlog_print(DLOG_INFO, DLOG_TAG, slice.c_str()); + dlog_print(DLOG_INFO, DLOG_TAG, "%s", slice.c_str()); break; default: - dlog_print(DLOG_DEBUG, DLOG_TAG, slice.c_str()); + dlog_print(DLOG_DEBUG, DLOG_TAG, "%s", slice.c_str()); break; } #elif TD_EMSCRIPTEN From c1a16acd537c8b0d6255b0f7a46a0aade0065774 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 24 Dec 2020 17:12:50 +0300 Subject: [PATCH 18/22] Don't check that Stdin/Stdout/Stderr are unlocked on exit. --- tdutils/td/utils/port/StdStreams.cpp | 3 ++- tdutils/td/utils/port/detail/PollableFd.h | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tdutils/td/utils/port/StdStreams.cpp b/tdutils/td/utils/port/StdStreams.cpp index 30603e1de..ef903bf72 100644 --- a/tdutils/td/utils/port/StdStreams.cpp +++ b/tdutils/td/utils/port/StdStreams.cpp @@ -24,7 +24,8 @@ namespace td { template static FileFd &get_file_fd() { static FileFd result = FileFd::from_native_fd(NativeFd(id, true)); - static auto guard = ScopeExit() + [&] { + static ExitGuard exit_guard; + static auto guard = SCOPE_EXIT { result.move_as_native_fd().release(); }; return result; diff --git a/tdutils/td/utils/port/detail/PollableFd.h b/tdutils/td/utils/port/detail/PollableFd.h index d8a0d8d7c..e03e00cd8 100644 --- a/tdutils/td/utils/port/detail/PollableFd.h +++ b/tdutils/td/utils/port/detail/PollableFd.h @@ -7,6 +7,7 @@ #pragma once #include "td/utils/common.h" +#include "td/utils/ExitGuard.h" #include "td/utils/format.h" #include "td/utils/List.h" #include "td/utils/logging.h" @@ -124,8 +125,10 @@ class PollableFdInfo : private ListNode { ~PollableFdInfo() { VLOG(fd) << native_fd() << " destroy PollableFdInfo"; - bool was_locked = lock_.test_and_set(std::memory_order_acquire); - CHECK(!was_locked); + if (!ExitGuard::is_exited()) { + bool was_locked = lock_.test_and_set(std::memory_order_acquire); + CHECK(!was_locked); + } } void add_flags_from_poll(PollFlags flags) { From 1b92e2d57abf012530db362a274a673e82b667a0 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 24 Dec 2020 17:16:56 +0300 Subject: [PATCH 19/22] Return back ScopeExit usage. --- tdutils/td/utils/port/StdStreams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tdutils/td/utils/port/StdStreams.cpp b/tdutils/td/utils/port/StdStreams.cpp index ef903bf72..cc6d28b38 100644 --- a/tdutils/td/utils/port/StdStreams.cpp +++ b/tdutils/td/utils/port/StdStreams.cpp @@ -25,7 +25,7 @@ template static FileFd &get_file_fd() { static FileFd result = FileFd::from_native_fd(NativeFd(id, true)); static ExitGuard exit_guard; - static auto guard = SCOPE_EXIT { + static auto guard = ScopeExit() + [&] { result.move_as_native_fd().release(); }; return result; From b582eb346ac7060c8ff71f9376dd5e362afc0d68 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 24 Dec 2020 18:43:26 +0300 Subject: [PATCH 20/22] Undo move_as_native_fd changes. --- tdutils/td/utils/port/StdStreams.cpp | 1 - tdutils/td/utils/port/detail/PollableFd.h | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tdutils/td/utils/port/StdStreams.cpp b/tdutils/td/utils/port/StdStreams.cpp index cc6d28b38..30603e1de 100644 --- a/tdutils/td/utils/port/StdStreams.cpp +++ b/tdutils/td/utils/port/StdStreams.cpp @@ -24,7 +24,6 @@ namespace td { template static FileFd &get_file_fd() { static FileFd result = FileFd::from_native_fd(NativeFd(id, true)); - static ExitGuard exit_guard; static auto guard = ScopeExit() + [&] { result.move_as_native_fd().release(); }; diff --git a/tdutils/td/utils/port/detail/PollableFd.h b/tdutils/td/utils/port/detail/PollableFd.h index e03e00cd8..d8a0d8d7c 100644 --- a/tdutils/td/utils/port/detail/PollableFd.h +++ b/tdutils/td/utils/port/detail/PollableFd.h @@ -7,7 +7,6 @@ #pragma once #include "td/utils/common.h" -#include "td/utils/ExitGuard.h" #include "td/utils/format.h" #include "td/utils/List.h" #include "td/utils/logging.h" @@ -125,10 +124,8 @@ class PollableFdInfo : private ListNode { ~PollableFdInfo() { VLOG(fd) << native_fd() << " destroy PollableFdInfo"; - if (!ExitGuard::is_exited()) { - bool was_locked = lock_.test_and_set(std::memory_order_acquire); - CHECK(!was_locked); - } + bool was_locked = lock_.test_and_set(std::memory_order_acquire); + CHECK(!was_locked); } void add_flags_from_poll(PollFlags flags) { From 47e413e0b82024c306e70279c041d7d77a2c0b61 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 24 Dec 2020 19:17:06 +0300 Subject: [PATCH 21/22] Fix BufferedStdinImpl reference counter. --- tdutils/td/utils/port/StdStreams.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tdutils/td/utils/port/StdStreams.cpp b/tdutils/td/utils/port/StdStreams.cpp index 30603e1de..290822724 100644 --- a/tdutils/td/utils/port/StdStreams.cpp +++ b/tdutils/td/utils/port/StdStreams.cpp @@ -127,8 +127,9 @@ class BufferedStdinImpl : public Iocp::Callback { break; } writer_.confirm_append(r_size.ok()); - if (iocp_ref_.post(0, this, nullptr)) { - inc_refcnt(); + inc_refcnt(); + if (!iocp_ref_.post(0, this, nullptr)) { + dec_refcnt(); } } if (!iocp_ref_.post(0, this, nullptr)) { From c1a1fc881c2e2e6c207905eead80af646eb261a8 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 24 Dec 2020 20:49:08 +0300 Subject: [PATCH 22/22] Fix BufferedStdinImpl destruction. --- tdutils/td/utils/port/StdStreams.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tdutils/td/utils/port/StdStreams.cpp b/tdutils/td/utils/port/StdStreams.cpp index 290822724..45823cc67 100644 --- a/tdutils/td/utils/port/StdStreams.cpp +++ b/tdutils/td/utils/port/StdStreams.cpp @@ -133,6 +133,7 @@ class BufferedStdinImpl : public Iocp::Callback { } } if (!iocp_ref_.post(0, this, nullptr)) { + read_thread_.detach(); dec_refcnt(); } }