Merge commit '3a626f6df2003e4cd834477de65dc900f074adda'
This commit is contained in:
commit
8c0ce47f61
@ -180,7 +180,7 @@ To build `TDLib` in Release mode using MSVC, you will need to additionally speci
|
||||
|
||||
<a name="using-cxx"></a>
|
||||
## Using in CMake C++ projects
|
||||
For C++ projects that use CMake, the best approach is to build `TDLib` as part of your project or to use a prebuilt installation.
|
||||
For C++ projects that use CMake, the best approach is to build `TDLib` as part of your project or to install it system-wide.
|
||||
|
||||
There are several libraries that you could use in your CMake project:
|
||||
|
||||
|
@ -7,7 +7,7 @@ This is an example of building TDLib with `C++/CLI` support and an example of TD
|
||||
* Download and install Microsoft Visual Studio 2015 or later.
|
||||
* Download and install [CMake](https://cmake.org/download/); choose "Add CMake to the system PATH" option while installing.
|
||||
* Install [vcpkg](https://github.com/Microsoft/vcpkg#quick-start) or update it to the latest version using `vcpkg update` and following received instructions.
|
||||
* Install `zlib` and `openssl` for using `vcpkg`:
|
||||
* Install `zlib` and `openssl` using `vcpkg`:
|
||||
```
|
||||
cd <path to vcpkg>
|
||||
.\vcpkg.exe install openssl:x64-windows openssl:x86-windows zlib:x64-windows zlib:x86-windows
|
||||
|
@ -3,7 +3,7 @@
|
||||
To run this example, you will need installed JDK >= 1.6.
|
||||
For Javadoc documentation generation PHP is needed.
|
||||
|
||||
TDLib should be prebuilt for using with Java and installed to local subdirectory `td/` as follows:
|
||||
TDLib should be prebuilt with JNI bindings and installed to local subdirectory `td/` as follows:
|
||||
```
|
||||
cd <path to TDLib sources>
|
||||
mkdir jnibuild
|
||||
|
@ -109,7 +109,7 @@ documentAttributeVideo66#ef02ce6 flags:# round_message:flags.0?true duration:int
|
||||
|
||||
// layer 73
|
||||
|
||||
decryptedMessage#91cc4674 flags:# random_id:long ttl:int message:string media:flags.9?DecryptedMessageMedia entities:flags.7?Vector<MessageEntity> via_bot_name:flags.11?string reply_to_random_id:flags.3?long grouped_id:flags.17?long = DecryptedMessage;
|
||||
decryptedMessage#91cc4674 flags:# silent:flags.5?true random_id:long ttl:int message:string media:flags.9?DecryptedMessageMedia entities:flags.7?Vector<MessageEntity> via_bot_name:flags.11?string reply_to_random_id:flags.3?long grouped_id:flags.17?long = DecryptedMessage;
|
||||
|
||||
// layer 101
|
||||
|
||||
|
Binary file not shown.
@ -71,7 +71,7 @@ AuthManager::AuthManager(int32 api_id, const string &api_hash, ActorShared<> par
|
||||
|
||||
void AuthManager::start_up() {
|
||||
if (state_ == State::LoggingOut) {
|
||||
start_net_query(NetQueryType::LogOut, G()->net_query_creator().create(telegram_api::auth_logOut()));
|
||||
send_log_out_query();
|
||||
} else if (state_ == State::DestroyingKeys) {
|
||||
destroy_auth_keys();
|
||||
}
|
||||
@ -364,10 +364,16 @@ void AuthManager::log_out(uint64 query_id) {
|
||||
LOG(INFO) << "Logging out";
|
||||
G()->td_db()->get_binlog_pmc()->set("auth", "logout");
|
||||
update_state(State::LoggingOut);
|
||||
start_net_query(NetQueryType::LogOut, G()->net_query_creator().create(telegram_api::auth_logOut()));
|
||||
send_log_out_query();
|
||||
}
|
||||
}
|
||||
|
||||
void AuthManager::send_log_out_query() {
|
||||
auto query = G()->net_query_creator().create(telegram_api::auth_logOut());
|
||||
query->set_priority(1);
|
||||
start_net_query(NetQueryType::LogOut, std::move(query));
|
||||
}
|
||||
|
||||
void AuthManager::delete_account(uint64 query_id, const string &reason) {
|
||||
if (state_ != State::Ok && state_ != State::WaitPassword) {
|
||||
return on_query_error(query_id, Status::Error(8, "Need to log in first"));
|
||||
@ -833,6 +839,8 @@ void AuthManager::update_state(State new_state, bool force, bool should_save_sta
|
||||
if (state_ == new_state && !force) {
|
||||
return;
|
||||
}
|
||||
bool skip_update = (state_ == State::LoggingOut || state_ == State::DestroyingKeys) &&
|
||||
(new_state == State::LoggingOut || new_state == State::DestroyingKeys);
|
||||
state_ = new_state;
|
||||
if (should_save_state) {
|
||||
save_state();
|
||||
@ -840,8 +848,10 @@ void AuthManager::update_state(State new_state, bool force, bool should_save_sta
|
||||
if (new_state == State::LoggingOut || new_state == State::DestroyingKeys) {
|
||||
send_closure(G()->state_manager(), &StateManager::on_logging_out, true);
|
||||
}
|
||||
send_closure(G()->td(), &Td::send_update,
|
||||
make_tl_object<td_api::updateAuthorizationState>(get_authorization_state_object(state_)));
|
||||
if (!skip_update) {
|
||||
send_closure(G()->td(), &Td::send_update,
|
||||
make_tl_object<td_api::updateAuthorizationState>(get_authorization_state_object(state_)));
|
||||
}
|
||||
|
||||
if (!pending_get_authorization_state_requests_.empty()) {
|
||||
auto query_ids = std::move(pending_get_authorization_state_requests_);
|
||||
|
@ -217,6 +217,8 @@ class AuthManager : public NetActor {
|
||||
static void on_update_login_token_static(void *td);
|
||||
void send_export_login_token_query();
|
||||
void set_login_token_expires_at(double login_token_expires_at);
|
||||
|
||||
void send_log_out_query();
|
||||
void destroy_auth_keys();
|
||||
|
||||
void on_send_code_result(NetQueryPtr &result);
|
||||
|
@ -37,18 +37,9 @@ class MultiTd : public Actor {
|
||||
CHECK(td.empty());
|
||||
|
||||
string name = "Td";
|
||||
class TdActorContext : public ActorContext {
|
||||
public:
|
||||
explicit TdActorContext(string tag) : tag_(std::move(tag)) {
|
||||
}
|
||||
int32 get_id() const override {
|
||||
return 0x172ae58d;
|
||||
}
|
||||
string tag_;
|
||||
};
|
||||
auto context = std::make_shared<TdActorContext>(to_string(td_id));
|
||||
auto context = std::make_shared<td::ActorContext>();
|
||||
auto old_context = set_context(context);
|
||||
auto old_tag = set_tag(context->tag_);
|
||||
auto old_tag = set_tag(to_string(td_id));
|
||||
td = create_actor<Td>("Td", std::move(callback), options_);
|
||||
set_context(old_context);
|
||||
set_tag(old_tag);
|
||||
|
@ -25,7 +25,7 @@
|
||||
namespace td {
|
||||
|
||||
int MessageEntity::get_type_priority(Type type) {
|
||||
static const int types[] = {50, 50, 50, 50, 50, 90, 91, 20, 11, 10, 49, 49, 50, 50, 92, 93, 0};
|
||||
static const int types[] = {50, 50, 50, 50, 50, 90, 91, 20, 11, 10, 49, 49, 50, 50, 92, 93, 0, 50};
|
||||
return types[static_cast<int32>(type)];
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ class ContactsManager;
|
||||
|
||||
class MessageEntity {
|
||||
public:
|
||||
// don't forget to update get_type_priority()
|
||||
enum class Type : int32 {
|
||||
Mention,
|
||||
Hashtag,
|
||||
|
@ -2056,7 +2056,7 @@ class SendSecretMessageActor : public NetActor {
|
||||
public:
|
||||
void send(DialogId dialog_id, int64 reply_to_random_id, int32 ttl, const string &text, SecretInputMedia media,
|
||||
vector<tl_object_ptr<secret_api::MessageEntity>> &&entities, UserId via_bot_user_id, int64 media_album_id,
|
||||
int64 random_id) {
|
||||
bool disable_notification, int64 random_id) {
|
||||
if (false && !media.empty()) {
|
||||
td->messages_manager_->on_send_secret_message_error(random_id, Status::Error(400, "FILE_PART_1_MISSING"), Auto());
|
||||
stop();
|
||||
@ -2083,13 +2083,16 @@ class SendSecretMessageActor : public NetActor {
|
||||
CHECK(media_album_id < 0);
|
||||
flags |= secret_api::decryptedMessage::GROUPED_ID_MASK;
|
||||
}
|
||||
if (disable_notification) {
|
||||
flags |= secret_api::decryptedMessage::SILENT_MASK;
|
||||
}
|
||||
|
||||
send_closure(G()->secret_chats_manager(), &SecretChatsManager::send_message, dialog_id.get_secret_chat_id(),
|
||||
make_tl_object<secret_api::decryptedMessage>(
|
||||
flags, random_id, ttl, text, std::move(media.decrypted_media_), std::move(entities),
|
||||
td->contacts_manager_->get_user_username(via_bot_user_id), reply_to_random_id, -media_album_id),
|
||||
std::move(media.input_file_),
|
||||
PromiseCreator::event(self_closure(this, &SendSecretMessageActor::done)));
|
||||
send_closure(
|
||||
G()->secret_chats_manager(), &SecretChatsManager::send_message, dialog_id.get_secret_chat_id(),
|
||||
make_tl_object<secret_api::decryptedMessage>(
|
||||
flags, false /*ignored*/, random_id, ttl, text, std::move(media.decrypted_media_), std::move(entities),
|
||||
td->contacts_manager_->get_user_username(via_bot_user_id), reply_to_random_id, -media_album_id),
|
||||
std::move(media.input_file_), PromiseCreator::event(self_closure(this, &SendSecretMessageActor::done)));
|
||||
}
|
||||
|
||||
void done() {
|
||||
@ -3183,9 +3186,13 @@ class DeleteMessagesQuery : public Td::ResultHandler {
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) override {
|
||||
if (!G()->is_expected_error(status) &&
|
||||
(dialog_id_.get_type() == DialogType::User || status.message() != "MESSAGE_DELETE_FORBIDDEN")) {
|
||||
LOG(ERROR) << "Receive error for delete messages: " << status;
|
||||
if (!G()->is_expected_error(status)) {
|
||||
// MESSAGE_DELETE_FORBIDDEN can be returned in group chats when administrator rights was removed
|
||||
// MESSAGE_DELETE_FORBIDDEN can be returned in private chats for bots when revoke time limit exceeded
|
||||
if (status.message() != "MESSAGE_DELETE_FORBIDDEN" ||
|
||||
(dialog_id_.get_type() == DialogType::User && !td->auth_manager_->is_bot())) {
|
||||
LOG(ERROR) << "Receive error for delete messages: " << status;
|
||||
}
|
||||
}
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
@ -6411,7 +6418,7 @@ void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_p
|
||||
auto channel_id = dialog_id.get_channel_id();
|
||||
if (!td_->contacts_manager_->have_channel(channel_id)) {
|
||||
// do not create dialog if there is no info about the channel
|
||||
LOG(WARNING) << "There is no info about " << channel_id << ", so ignore " << oneline(to_string(update));
|
||||
LOG(INFO) << "There is no info about " << channel_id << ", so ignore " << oneline(to_string(update));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -8030,7 +8037,9 @@ void MessagesManager::after_get_difference() {
|
||||
|
||||
vector<FullMessageId> update_message_ids_to_delete;
|
||||
for (auto &it : update_message_ids_) {
|
||||
// this is impossible for ordinary chats because updates coming during getDifference have already been applied
|
||||
// there can be unhandled updateMessageId updates after getDifference even for ordinary chats,
|
||||
// because despite updates coming during getDifference have already been applied,
|
||||
// some of them could be postponed because of pts gap
|
||||
auto full_message_id = it.first;
|
||||
auto dialog_id = full_message_id.get_dialog_id();
|
||||
auto message_id = full_message_id.get_message_id();
|
||||
@ -8059,9 +8068,13 @@ void MessagesManager::after_get_difference() {
|
||||
|
||||
const Dialog *d = get_dialog(dialog_id);
|
||||
CHECK(d != nullptr);
|
||||
LOG(ERROR) << "Receive updateMessageId from " << it.second << " to " << full_message_id
|
||||
<< " but not receive corresponding message, last_new_message_id = " << d->last_new_message_id;
|
||||
if (dialog_id.get_type() != DialogType::Channel) {
|
||||
if (dialog_id.get_type() == DialogType::Channel || pending_updates_.empty() || message_id.is_scheduled() ||
|
||||
message_id <= d->last_new_message_id) {
|
||||
LOG(ERROR) << "Receive updateMessageId from " << it.second << " to " << full_message_id
|
||||
<< " but not receive corresponding message, last_new_message_id = " << d->last_new_message_id;
|
||||
}
|
||||
if (dialog_id.get_type() != DialogType::Channel &&
|
||||
(pending_updates_.empty() || message_id.is_scheduled() || message_id <= d->last_new_message_id)) {
|
||||
dump_debug_message_op(get_dialog(dialog_id));
|
||||
}
|
||||
if (message_id.is_scheduled() || message_id <= d->last_new_message_id) {
|
||||
@ -8849,7 +8862,7 @@ void MessagesManager::delete_dialog_messages_from_updates(DialogId dialog_id, co
|
||||
send_update_delete_messages(dialog_id, std::move(deleted_message_ids), true, false);
|
||||
}
|
||||
|
||||
string MessagesManager::get_search_text(const Message *m) const {
|
||||
string MessagesManager::get_message_search_text(const Message *m) const {
|
||||
if (m->is_content_secret) {
|
||||
return string();
|
||||
}
|
||||
@ -11615,6 +11628,9 @@ void MessagesManager::on_get_secret_message(SecretChatId secret_chat_id, UserId
|
||||
if ((message->flags_ & secret_api::decryptedMessage::MEDIA_MASK) != 0) {
|
||||
flags |= MESSAGE_FLAG_HAS_MEDIA;
|
||||
}
|
||||
if ((message->flags_ & secret_api::decryptedMessage::SILENT_MASK) != 0) {
|
||||
flags |= MESSAGE_FLAG_IS_SILENT;
|
||||
}
|
||||
|
||||
if (!clean_input_string(message->via_bot_name_)) {
|
||||
LOG(WARNING) << "Receive invalid bot username " << message->via_bot_name_;
|
||||
@ -11893,16 +11909,6 @@ std::pair<DialogId, unique_ptr<MessagesManager::Message>> MessagesManager::creat
|
||||
}
|
||||
|
||||
int32 flags = message_info.flags;
|
||||
if (flags &
|
||||
~(MESSAGE_FLAG_IS_OUT | MESSAGE_FLAG_IS_FORWARDED | MESSAGE_FLAG_IS_REPLY | MESSAGE_FLAG_HAS_MENTION |
|
||||
MESSAGE_FLAG_HAS_UNREAD_CONTENT | MESSAGE_FLAG_HAS_REPLY_MARKUP | MESSAGE_FLAG_HAS_ENTITIES |
|
||||
MESSAGE_FLAG_HAS_FROM_ID | MESSAGE_FLAG_HAS_MEDIA | MESSAGE_FLAG_HAS_VIEWS | MESSAGE_FLAG_IS_SENT_VIA_BOT |
|
||||
MESSAGE_FLAG_IS_SILENT | MESSAGE_FLAG_IS_POST | MESSAGE_FLAG_HAS_EDIT_DATE | MESSAGE_FLAG_HAS_AUTHOR_SIGNATURE |
|
||||
MESSAGE_FLAG_HAS_MEDIA_ALBUM_ID | MESSAGE_FLAG_IS_FROM_SCHEDULED | MESSAGE_FLAG_IS_LEGACY |
|
||||
MESSAGE_FLAG_HIDE_EDIT_DATE | MESSAGE_FLAG_IS_RESTRICTED)) {
|
||||
LOG(ERROR) << "Unsupported message flags = " << flags << " received";
|
||||
}
|
||||
|
||||
bool is_outgoing = (flags & MESSAGE_FLAG_IS_OUT) != 0;
|
||||
bool is_silent = (flags & MESSAGE_FLAG_IS_SILENT) != 0;
|
||||
bool is_channel_post = (flags & MESSAGE_FLAG_IS_POST) != 0;
|
||||
@ -19979,7 +19985,14 @@ tl_object_ptr<td_api::message> MessagesManager::get_message_object(DialogId dial
|
||||
auto live_location_date = m->is_failed_to_send ? 0 : m->date;
|
||||
auto date = is_scheduled ? 0 : m->date;
|
||||
auto edit_date = m->hide_edit_date ? 0 : m->edit_date;
|
||||
auto views = m->message_id.is_scheduled() || (m->message_id.is_local() && m->forward_info == nullptr) ? 0 : m->views;
|
||||
auto views = m->views;
|
||||
if (m->message_id.is_scheduled()) {
|
||||
if (m->forward_info == nullptr || is_broadcast_channel(dialog_id)) {
|
||||
views = 0;
|
||||
}
|
||||
} else if (m->message_id.is_local() && m->forward_info == nullptr) {
|
||||
views = 0;
|
||||
}
|
||||
return make_tl_object<td_api::message>(
|
||||
m->message_id.get(), td_->contacts_manager_->get_user_id_object(m->sender_user_id, "sender_user_id"),
|
||||
dialog_id.get(), std::move(sending_state), std::move(scheduling_state), is_outgoing, can_be_edited,
|
||||
@ -20850,7 +20863,7 @@ void MessagesManager::do_send_message(DialogId dialog_id, const Message *m, vect
|
||||
m->reply_to_random_id, m->ttl, message_text->text,
|
||||
get_secret_input_media(content, td_, nullptr, BufferSlice(), layer),
|
||||
get_input_secret_message_entities(message_text->entities, layer), m->via_bot_user_id,
|
||||
m->media_album_id, random_id);
|
||||
m->media_album_id, m->disable_notification, random_id);
|
||||
} else {
|
||||
send_closure(td_->create_net_actor<SendMessageActor>(), &SendMessageActor::send, get_message_flags(m), dialog_id,
|
||||
m->reply_to_message_id, get_message_schedule_date(m), get_input_reply_markup(m->reply_markup),
|
||||
@ -21030,7 +21043,7 @@ void MessagesManager::on_secret_message_media_uploaded(DialogId dialog_id, const
|
||||
}
|
||||
send_closure(td_->create_net_actor<SendSecretMessageActor>(), &SendSecretMessageActor::send, dialog_id,
|
||||
m->reply_to_random_id, m->ttl, "", std::move(secret_input_media), std::move(entities),
|
||||
m->via_bot_user_id, m->media_album_id, random_id);
|
||||
m->via_bot_user_id, m->media_album_id, m->disable_notification, random_id);
|
||||
}));
|
||||
}
|
||||
|
||||
@ -23111,8 +23124,9 @@ Result<vector<MessageId>> MessagesManager::forward_messages(DialogId to_dialog_i
|
||||
m->real_forward_from_message_id = message_id;
|
||||
m->via_bot_user_id = forwarded_message->via_bot_user_id;
|
||||
m->in_game_share = in_game_share;
|
||||
if (forwarded_message->views > 0 && m->forward_info != nullptr) {
|
||||
m->views = 1;
|
||||
if (forwarded_message->views > 0 && m->forward_info != nullptr && m->views == 0 &&
|
||||
!(m->message_id.is_scheduled() && is_broadcast_channel(to_dialog_id))) {
|
||||
m->views = forwarded_message->views;
|
||||
}
|
||||
|
||||
if (is_game) {
|
||||
@ -27385,6 +27399,11 @@ void MessagesManager::set_dialog_photo(DialogId dialog_id, const tl_object_ptr<t
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (input_file == nullptr) {
|
||||
send_edit_dialog_photo_query(dialog_id, FileId(), make_tl_object<telegram_api::inputChatPhotoEmpty>(),
|
||||
std::move(promise));
|
||||
return;
|
||||
}
|
||||
|
||||
const double MAX_ANIMATION_DURATION = 10.0;
|
||||
if (main_frame_timestamp < 0.0 || main_frame_timestamp > MAX_ANIMATION_DURATION) {
|
||||
@ -29352,7 +29371,7 @@ void MessagesManager::add_message_to_database(const Dialog *d, const Message *m,
|
||||
unique_message_id = message_id.get_server_message_id();
|
||||
}
|
||||
// FOR DEBUG
|
||||
// text = get_search_text(m);
|
||||
// text = get_message_search_text(m);
|
||||
// if (!text.empty()) {
|
||||
// search_id = (static_cast<int64>(m->date) << 32) | static_cast<uint32>(Random::secure_int32());
|
||||
// }
|
||||
@ -29361,7 +29380,7 @@ void MessagesManager::add_message_to_database(const Dialog *d, const Message *m,
|
||||
break;
|
||||
case DialogType::SecretChat:
|
||||
random_id = m->random_id;
|
||||
text = get_search_text(m);
|
||||
text = get_message_search_text(m);
|
||||
if (!text.empty()) {
|
||||
search_id = (static_cast<int64>(m->date) << 32) | static_cast<uint32>(m->random_id);
|
||||
}
|
||||
|
@ -2692,7 +2692,7 @@ class MessagesManager : public Actor {
|
||||
|
||||
void try_hide_distance(DialogId dialog_id, const Message *m);
|
||||
|
||||
string get_search_text(const Message *m) const;
|
||||
string get_message_search_text(const Message *m) const;
|
||||
|
||||
unique_ptr<Message> parse_message(DialogId dialog_id, const BufferSlice &value, bool is_scheduled);
|
||||
|
||||
|
@ -1289,7 +1289,7 @@ Status SecretChatActor::do_inbound_message_decrypted(unique_ptr<logevent::Inboun
|
||||
auto old = move_tl_object_as<secret_api::decryptedMessage46>(message->decrypted_message_layer->message_);
|
||||
old->flags_ &= ~secret_api::decryptedMessage::GROUPED_ID_MASK; // just in case
|
||||
message->decrypted_message_layer->message_ = secret_api::make_object<secret_api::decryptedMessage>(
|
||||
old->flags_, old->random_id_, old->ttl_, std::move(old->message_), std::move(old->media_),
|
||||
old->flags_, false /*ignored*/, old->random_id_, old->ttl_, std::move(old->message_), std::move(old->media_),
|
||||
std::move(old->entities_), std::move(old->via_bot_name_), old->reply_to_random_id_, 0);
|
||||
}
|
||||
if (message->decrypted_message_layer->message_->get_id() == secret_api::decryptedMessageService8::ID) {
|
||||
@ -1786,7 +1786,7 @@ void SecretChatActor::on_outbound_outer_send_message_promise(uint64 state_id, Pr
|
||||
promise.set_value(Unit()); // Seems like this message is at least stored to binlog already
|
||||
if (state->send_result_) {
|
||||
state->send_result_({});
|
||||
} else {
|
||||
} else if (state->message->is_sent) {
|
||||
context_->on_send_message_error(state->message->random_id, Status::Error(400, "Message has already been sent"),
|
||||
Auto());
|
||||
}
|
||||
|
@ -3576,6 +3576,10 @@ class CliClient final : public Actor {
|
||||
|
||||
std::tie(chat_id, title) = split(args);
|
||||
send_request(td_api::make_object<td_api::setChatTitle>(as_chat_id(chat_id), title));
|
||||
} else if (op == "scpe") {
|
||||
string chat_id = args;
|
||||
|
||||
send_request(td_api::make_object<td_api::setChatPhoto>(as_chat_id(chat_id), nullptr));
|
||||
} else if (op == "scpp") {
|
||||
string chat_id;
|
||||
string photo_id;
|
||||
|
@ -266,6 +266,13 @@ class NetQuery : public TsListNode<NetQueryDebug> {
|
||||
finish_migrate(cancel_slot_);
|
||||
}
|
||||
|
||||
int8 priority() const {
|
||||
return priority_;
|
||||
}
|
||||
void set_priority(int8 priority) {
|
||||
priority_ = priority;
|
||||
}
|
||||
|
||||
private:
|
||||
State state_ = State::Empty;
|
||||
Type type_ = Type::Common;
|
||||
@ -284,6 +291,7 @@ class NetQuery : public TsListNode<NetQueryDebug> {
|
||||
uint32 session_rand_ = 0;
|
||||
|
||||
bool may_be_lost_ = false;
|
||||
int8 priority_{0};
|
||||
|
||||
template <class T>
|
||||
struct movable_atomic : public std::atomic<T> {
|
||||
|
@ -117,6 +117,25 @@ class GenAuthKeyActor : public Actor {
|
||||
|
||||
} // namespace detail
|
||||
|
||||
void Session::PriorityQueue::push(NetQueryPtr query) {
|
||||
auto priority = query->priority();
|
||||
queries_[priority].push(std::move(query));
|
||||
}
|
||||
|
||||
NetQueryPtr Session::PriorityQueue::pop() {
|
||||
CHECK(!empty());
|
||||
auto it = queries_.begin();
|
||||
auto res = it->second.pop();
|
||||
if (it->second.empty()) {
|
||||
queries_.erase(it);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Session::PriorityQueue::empty() const {
|
||||
return queries_.empty();
|
||||
}
|
||||
|
||||
Session::Session(unique_ptr<Callback> callback, std::shared_ptr<AuthDataShared> shared_auth_data, int32 raw_dc_id,
|
||||
int32 dc_id, bool is_main, bool use_pfs, bool is_cdn, bool need_destroy,
|
||||
const mtproto::AuthKey &tmp_auth_key, std::vector<mtproto::ServerSalt> server_salts)
|
||||
@ -344,7 +363,7 @@ void Session::return_query(NetQueryPtr &&query) {
|
||||
void Session::flush_pending_invoke_after_queries() {
|
||||
while (!pending_invoke_after_queries_.empty()) {
|
||||
auto &query = pending_invoke_after_queries_.front();
|
||||
pending_queries_.push_back(std::move(query));
|
||||
pending_queries_.push(std::move(query));
|
||||
pending_invoke_after_queries_.pop_front();
|
||||
}
|
||||
}
|
||||
@ -359,7 +378,7 @@ void Session::close() {
|
||||
auto &query = it.second.query;
|
||||
query->set_message_id(0);
|
||||
query->cancel_slot_.clear_event();
|
||||
pending_queries_.push_back(std::move(query));
|
||||
pending_queries_.push(std::move(query));
|
||||
}
|
||||
sent_queries_.clear();
|
||||
sent_containers_.clear();
|
||||
@ -367,10 +386,9 @@ void Session::close() {
|
||||
flush_pending_invoke_after_queries();
|
||||
CHECK(sent_queries_.empty());
|
||||
while (!pending_queries_.empty()) {
|
||||
auto &query = pending_queries_.front();
|
||||
auto query = pending_queries_.pop();
|
||||
query->set_error_resend();
|
||||
return_query(std::move(query));
|
||||
pending_queries_.pop_front();
|
||||
}
|
||||
|
||||
callback_->on_closed();
|
||||
@ -905,7 +923,7 @@ void Session::add_query(NetQueryPtr &&net_query) {
|
||||
net_query->debug("Session: pending");
|
||||
LOG_IF(FATAL, UniqueId::extract_type(net_query->id()) == UniqueId::BindKey)
|
||||
<< "Add BindKey query inpo pending_queries_";
|
||||
pending_queries_.emplace_back(std::move(net_query));
|
||||
pending_queries_.push(std::move(net_query));
|
||||
}
|
||||
|
||||
void Session::connection_send_query(ConnectionInfo *info, NetQueryPtr &&net_query, uint64 message_id) {
|
||||
@ -1323,9 +1341,8 @@ void Session::loop() {
|
||||
if (auth_data_.is_ready(Time::now_cached())) {
|
||||
if (need_send_query()) {
|
||||
while (!pending_queries_.empty() && sent_queries_.size() < MAX_INFLIGHT_QUERIES) {
|
||||
auto &query = pending_queries_.front();
|
||||
auto query = pending_queries_.pop();
|
||||
connection_send_query(&main_connection_, std::move(query));
|
||||
pending_queries_.pop_front();
|
||||
need_flush = true;
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,11 @@
|
||||
#include "td/utils/List.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
#include "td/utils/VectorQueue.h"
|
||||
|
||||
#include <array>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
@ -124,7 +126,16 @@ class Session final
|
||||
|
||||
// Do not invalidate iterators of these two containers!
|
||||
// TODO: better data structures
|
||||
std::deque<NetQueryPtr> pending_queries_;
|
||||
struct PriorityQueue {
|
||||
public:
|
||||
void push(NetQueryPtr query);
|
||||
NetQueryPtr pop();
|
||||
bool empty() const;
|
||||
|
||||
private:
|
||||
std::map<int8, VectorQueue<NetQueryPtr>, std::greater<>> queries_;
|
||||
};
|
||||
PriorityQueue pending_queries_;
|
||||
std::map<uint64, Query> sent_queries_;
|
||||
std::deque<NetQueryPtr> pending_invoke_after_queries_;
|
||||
ListNode sent_queries_list_;
|
||||
|
@ -75,7 +75,7 @@ class Actor : public ObserverBase {
|
||||
|
||||
uint64 get_link_token();
|
||||
std::shared_ptr<ActorContext> set_context(std::shared_ptr<ActorContext> context);
|
||||
CSlice set_tag(CSlice tag);
|
||||
string set_tag(string tag);
|
||||
|
||||
void always_wait_for_mailbox();
|
||||
|
||||
|
@ -88,13 +88,13 @@ inline uint64 Actor::get_link_token() {
|
||||
inline std::shared_ptr<ActorContext> Actor::set_context(std::shared_ptr<ActorContext> context) {
|
||||
return info_->set_context(std::move(context));
|
||||
}
|
||||
inline CSlice Actor::set_tag(CSlice tag) {
|
||||
auto &tag_ref = info_->get_context()->tag_;
|
||||
CSlice old_tag;
|
||||
if (tag_ref) {
|
||||
old_tag = CSlice(tag_ref);
|
||||
inline string Actor::set_tag(string tag) {
|
||||
auto *ctx = info_->get_context();
|
||||
string old_tag;
|
||||
if (ctx->tag_) {
|
||||
old_tag = ctx->tag_;
|
||||
}
|
||||
tag_ref = tag.c_str();
|
||||
ctx->set_tag(std::move(tag));
|
||||
Scheduler::on_context_updated();
|
||||
return old_tag;
|
||||
}
|
||||
|
@ -37,7 +37,13 @@ class ActorContext {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_tag(string tag) {
|
||||
tag_storage_ = std::move(tag);
|
||||
tag_ = tag_storage_.c_str();
|
||||
}
|
||||
|
||||
const char *tag_ = nullptr;
|
||||
string tag_storage_; // sometimes tag_ == tag_storage_.c_str()
|
||||
std::weak_ptr<ActorContext> this_ptr_;
|
||||
};
|
||||
|
||||
|
@ -146,7 +146,9 @@ inline const Actor *ActorInfo::get_actor_unsafe() const {
|
||||
inline std::shared_ptr<ActorContext> ActorInfo::set_context(std::shared_ptr<ActorContext> context) {
|
||||
CHECK(is_running());
|
||||
context->this_ptr_ = context;
|
||||
context->tag_ = Scheduler::context()->tag_;
|
||||
if (Scheduler::context()->tag_) {
|
||||
context->set_tag(Scheduler::context()->tag_);
|
||||
}
|
||||
std::swap(context_, context);
|
||||
Scheduler::context() = context_.get();
|
||||
Scheduler::on_context_updated();
|
||||
|
@ -20,15 +20,17 @@ class BinlogActor : public Actor {
|
||||
}
|
||||
void close(Promise<> promise) {
|
||||
binlog_->close().ensure();
|
||||
promise.set_value(Unit());
|
||||
LOG(INFO) << "Finished to close binlog";
|
||||
stop();
|
||||
|
||||
promise.set_value(Unit()); // setting promise can complete closing and destroy the current actor context
|
||||
}
|
||||
void close_and_destroy(Promise<> promise) {
|
||||
binlog_->close_and_destroy().ensure();
|
||||
promise.set_value(Unit());
|
||||
LOG(INFO) << "Finished to destroy binlog";
|
||||
stop();
|
||||
|
||||
promise.set_value(Unit()); // setting promise can complete closing and destroy the current actor context
|
||||
}
|
||||
|
||||
struct Event {
|
||||
|
@ -136,8 +136,17 @@ TEST(Http, reader) {
|
||||
{
|
||||
BufferSlice a("test test");
|
||||
BufferSlice b = std::move(a);
|
||||
#if TD_CLANG
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma clang diagnostic ignored "-Wunknown-warning-option"
|
||||
#pragma clang diagnostic ignored "-Wself-move"
|
||||
#endif
|
||||
a = std::move(a);
|
||||
b = std::move(b);
|
||||
#if TD_CLANG
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
a = std::move(b);
|
||||
BufferSlice c = a.from_slice(a);
|
||||
CHECK(c.size() == a.size());
|
||||
|
@ -881,8 +881,8 @@ class Master : public Actor {
|
||||
LOG(INFO) << "Send message: " << tag("id", id) << tag("text", text) << tag("random_id", random_id);
|
||||
sent_messages_[random_id] = Message{id, text};
|
||||
send_closure(get_by_id(id), &SecretChatProxy::send_message,
|
||||
secret_api::make_object<secret_api::decryptedMessage>(0, random_id, 0, text, Auto(), Auto(), Auto(),
|
||||
Auto(), 0));
|
||||
secret_api::make_object<secret_api::decryptedMessage>(0, false /*ignored*/, random_id, 0, text, Auto(),
|
||||
Auto(), Auto(), Auto(), 0));
|
||||
}
|
||||
void process_net_query(my_api::messages_sendEncryptedService &&message, NetQueryPtr net_query,
|
||||
ActorShared<NetQueryCallback> callback) {
|
||||
|
@ -840,7 +840,7 @@ class Tdclient_login : public Test {
|
||||
|
||||
TEST(Client, Simple) {
|
||||
td::Client client;
|
||||
//client.execute({1, td::td_api::make_object<td::td_api::setLogTagVerbosityLevel>("actor", 1)});
|
||||
// client.execute({1, td::td_api::make_object<td::td_api::setLogTagVerbosityLevel>("actor", 1)});
|
||||
client.send({3, td::make_tl_object<td::td_api::testSquareInt>(3)});
|
||||
while (true) {
|
||||
auto result = client.receive(10);
|
||||
|
Loading…
Reference in New Issue
Block a user