ContactsManager partial locking when cleaning

This commit is contained in:
Andrea Cavalli 2020-08-02 00:24:48 +02:00
parent ee676d0a52
commit 35fe9a1409
2 changed files with 212 additions and 116 deletions

View File

@ -282,7 +282,7 @@ class GetWebAuthorizationsQuery : public Td::ResultHandler {
results->websites_.push_back(make_tl_object<td_api::connectedWebsite>(
authorization->hash_, authorization->domain_,
td->contacts_manager_->get_user_id_object(bot_user_id, "GetWebAuthorizationsQuery"), authorization->browser_,
td->contacts_manager_->get_user_id_object_internal(bot_user_id, "GetWebAuthorizationsQuery"), authorization->browser_,
authorization->platform_, authorization->date_created_, authorization->date_active_, authorization->ip_,
authorization->region_));
}
@ -2760,17 +2760,17 @@ tl_object_ptr<td_api::ChatStatistics> ContactsManager::convert_megagroup_stats(
auto top_senders = transform(std::move(obj->top_posters_), [this](auto &&top_poster) {
return td_api::make_object<td_api::chatStatisticsMessageSenderInfo>(
this->get_user_id_object(UserId(top_poster->user_id_), "get_top_senders"), top_poster->messages_,
this->get_user_id_object_internal(UserId(top_poster->user_id_), "get_top_senders"), top_poster->messages_,
top_poster->avg_chars_);
});
auto top_administrators = transform(std::move(obj->top_admins_), [this](auto &&top_admin) {
return td_api::make_object<td_api::chatStatisticsAdministratorActionsInfo>(
this->get_user_id_object(UserId(top_admin->user_id_), "get_top_administrators"), top_admin->deleted_,
this->get_user_id_object_internal(UserId(top_admin->user_id_), "get_top_administrators"), top_admin->deleted_,
top_admin->kicked_, top_admin->banned_);
});
auto top_inviters = transform(std::move(obj->top_inviters_), [this](auto &&top_inviter) {
return td_api::make_object<td_api::chatStatisticsInviterInfo>(
this->get_user_id_object(UserId(top_inviter->user_id_), "get_top_inviters"), top_inviter->invitations_);
this->get_user_id_object_internal(UserId(top_inviter->user_id_), "get_top_inviters"), top_inviter->invitations_);
});
return make_tl_object<td_api::chatStatisticsSupergroup>(
@ -4689,7 +4689,7 @@ tl_object_ptr<td_api::users> ContactsManager::get_blocked_users_object(int64 ran
if (it == found_blocked_users_.end()) {
return nullptr;
}
auto result = get_users_object(it->second.first, it->second.second);
auto result = get_users_object_internal(it->second.first, it->second.second);
found_blocked_users_.erase(it);
return result;
}
@ -4957,7 +4957,7 @@ void ContactsManager::on_load_imported_contacts_finished() {
LOG(INFO) << "Finished to load " << all_imported_contacts_.size() << " imported contacts";
for (const auto &contact : all_imported_contacts_) {
get_user_id_object(contact.get_user_id(), "on_load_imported_contacts_finished"); // to ensure updateUser
get_user_id_object_internal(contact.get_user_id(), "on_load_imported_contacts_finished"); // to ensure updateUser
}
if (need_clear_imported_contacts_) {
@ -6873,7 +6873,7 @@ void ContactsManager::on_imported_contacts(int64 random_id, vector<UserId> impor
std::unordered_map<size_t, int32> unique_id_to_unimported_contact_invites;
for (size_t i = 0; i < add_size; i++) {
auto unique_id = imported_contacts_pos_[i];
get_user_id_object(imported_contact_user_ids[i], "on_imported_contacts"); // to ensure updateUser
get_user_id_object_internal(imported_contact_user_ids[i], "on_imported_contacts"); // to ensure updateUser
all_imported_contacts_[unique_id].set_user_id(imported_contact_user_ids[i]);
unique_id_to_unimported_contact_invites[unique_id] = unimported_contact_invites[i];
}
@ -8144,7 +8144,7 @@ void ContactsManager::on_binlog_secret_chat_event(BinlogEvent &&event) {
log_event_parse(log_event, event.data_).ensure();
auto secret_chat_id = log_event.secret_chat_id;
if (have_secret_chat(secret_chat_id)) {
if (have_secret_chat_internal(secret_chat_id)) {
LOG(ERROR) << "Skip adding already added " << secret_chat_id;
binlog_erase(G()->td_db()->get_binlog(), event.id_);
return;
@ -9012,7 +9012,7 @@ void ContactsManager::update_user_full(UserFull *user_full, UserId user_id, bool
CHECK(u == nullptr || u->is_update_user_sent);
}
send_closure(G()->td(), &Td::send_update,
make_tl_object<td_api::updateUserFullInfo>(get_user_id_object(user_id, "updateUserFullInfo"),
make_tl_object<td_api::updateUserFullInfo>(get_user_id_object_internal(user_id, "updateUserFullInfo"),
get_user_full_info_object(user_id, user_full)));
user_full->need_send_update = false;
}
@ -9052,7 +9052,7 @@ void ContactsManager::update_chat_full(ChatFull *chat_full, ChatId chat_id, bool
}
send_closure(
G()->td(), &Td::send_update,
make_tl_object<td_api::updateBasicGroupFullInfo>(get_basic_group_id_object(chat_id, "update_chat_full"),
make_tl_object<td_api::updateBasicGroupFullInfo>(get_basic_group_id_object_internal(chat_id, "update_chat_full"),
get_basic_group_full_info_object(chat_full)));
chat_full->need_send_update = false;
}
@ -9103,7 +9103,7 @@ void ContactsManager::update_channel_full(ChannelFull *channel_full, ChannelId c
}
send_closure(
G()->td(), &Td::send_update,
make_tl_object<td_api::updateSupergroupFullInfo>(get_supergroup_id_object(channel_id, "update_channel_full"),
make_tl_object<td_api::updateSupergroupFullInfo>(get_supergroup_id_object_internal(channel_id, "update_channel_full"),
get_supergroup_full_info_object(channel_full)));
channel_full->need_send_update = false;
}
@ -9697,7 +9697,9 @@ void ContactsManager::on_update_user_photo(UserId user_id, tl_object_ptr<telegra
void ContactsManager::on_update_user_photo(User *u, UserId user_id,
tl_object_ptr<telegram_api::UserProfilePhoto> &&photo, const char *source) {
if (td_->auth_manager_->is_bot() && !G()->parameters().use_file_db && !u->is_photo_inited) {
auto &old_photo = pending_user_photos_[user_id];
auto find_old_photo = pending_user_photos_.find(user_id);
if (find_old_photo != pending_user_photos_.end()) {
auto &old_photo = find_old_photo->second;
if (!LOG_IS_STRIPPED(ERROR) && to_string(old_photo) == to_string(photo)) {
return;
}
@ -9708,6 +9710,7 @@ void ContactsManager::on_update_user_photo(User *u, UserId user_id,
drop_user_photos(user_id, is_empty, true, "on_update_user_photo");
return;
}
}
do_update_user_photo(u, user_id, std::move(photo), source);
}
@ -10441,8 +10444,8 @@ tl_object_ptr<td_api::chatMember> ContactsManager::get_chat_member_object(
const DialogParticipant &dialog_participant) const {
UserId participant_user_id = dialog_participant.user_id;
return td_api::make_object<td_api::chatMember>(
get_user_id_object(participant_user_id, "chatMember.user_id"),
get_user_id_object(dialog_participant.inviter_user_id, "chatMember.inviter_user_id"),
get_user_id_object_internal(participant_user_id, "chatMember.user_id"),
get_user_id_object_internal(dialog_participant.inviter_user_id, "chatMember.inviter_user_id"),
dialog_participant.joined_date, dialog_participant.status.get_chat_member_status_object(),
get_bot_info_object(participant_user_id));
}
@ -12981,6 +12984,7 @@ bool ContactsManager::get_channel_full(ChannelId channel_id, bool force, Promise
}
void ContactsManager::reload_channel_full(ChannelId channel_id, Promise<Unit> &&promise, const char *source) {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
send_get_channel_full_query(get_channel_full(channel_id, "reload_channel_full"), channel_id, std::move(promise),
source);
}
@ -13015,6 +13019,11 @@ void ContactsManager::send_get_channel_full_query(ChannelFull *channel_full, Cha
}
bool ContactsManager::have_secret_chat(SecretChatId secret_chat_id) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return have_secret_chat_internal(secret_chat_id);
}
bool ContactsManager::have_secret_chat_internal(SecretChatId secret_chat_id) const {
return secret_chats_.count(secret_chat_id) > 0;
}
@ -13045,11 +13054,12 @@ ContactsManager::SecretChat *ContactsManager::get_secret_chat(SecretChatId secre
bool ContactsManager::get_secret_chat(SecretChatId secret_chat_id, bool force, Promise<Unit> &&promise) {
if (!secret_chat_id.is_valid()) {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
promise.set_error(Status::Error(6, "Invalid secret chat identifier"));
return false;
}
if (!have_secret_chat(secret_chat_id)) {
if (!have_secret_chat_internal(secret_chat_id)) {
if (!force && G()->parameters().use_chat_info_db) {
send_closure_later(actor_id(this), &ContactsManager::load_secret_chat_from_database, nullptr, secret_chat_id,
std::move(promise));
@ -13067,6 +13077,7 @@ bool ContactsManager::get_secret_chat(SecretChatId secret_chat_id, bool force, P
void ContactsManager::on_update_secret_chat(SecretChatId secret_chat_id, int64 access_hash, UserId user_id,
SecretChatState state, bool is_outbound, int32 ttl, int32 date,
string key_hash, int32 layer, FolderId initial_folder_id) {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
LOG(INFO) << "Update " << secret_chat_id << " with " << user_id << " and access_hash " << access_hash;
auto *secret_chat = add_secret_chat(secret_chat_id);
if (access_hash != secret_chat->access_hash) {
@ -13119,6 +13130,12 @@ void ContactsManager::on_update_secret_chat(SecretChatId secret_chat_id, int64 a
std::pair<int32, vector<UserId>> ContactsManager::search_among_users(const vector<UserId> &user_ids,
const string &query, int32 limit) {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return search_among_users_internal(user_ids, query, limit);
}
std::pair<int32, vector<UserId>> ContactsManager::search_among_users_internal(const vector<UserId> &user_ids,
const string &query, int32 limit) {
Hints hints; // TODO cache Hints
for (auto user_id : user_ids) {
@ -13137,6 +13154,7 @@ std::pair<int32, vector<UserId>> ContactsManager::search_among_users(const vecto
DialogParticipant ContactsManager::get_chat_participant(ChatId chat_id, UserId user_id, bool force,
Promise<Unit> &&promise) {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
LOG(INFO) << "Trying to get " << user_id << " as member of " << chat_id;
if (force) {
promise.set_value(Unit());
@ -13158,6 +13176,7 @@ std::pair<int32, vector<DialogParticipant>> ContactsManager::search_chat_partici
DialogParticipantsFilter filter,
bool force,
Promise<Unit> &&promise) {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
if (limit < 0) {
promise.set_error(Status::Error(3, "Parameter limit must be non-negative"));
return {};
@ -13203,12 +13222,13 @@ std::pair<int32, vector<DialogParticipant>> ContactsManager::search_chat_partici
}
int32 total_count;
std::tie(total_count, user_ids) = search_among_users(user_ids, query, limit);
std::tie(total_count, user_ids) = search_among_users_internal(user_ids, query, limit);
return {total_count, transform(user_ids, [&](UserId user_id) { return *get_chat_participant(chat_full, user_id); })};
}
DialogParticipant ContactsManager::get_channel_participant(ChannelId channel_id, UserId user_id, int64 &random_id,
bool force, Promise<Unit> &&promise) {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
LOG(INFO) << "Trying to get " << user_id << " as member of " << channel_id << " with random_id " << random_id;
if (random_id != 0) {
// request has already been sent before
@ -13271,6 +13291,7 @@ DialogParticipant ContactsManager::get_channel_participant(ChannelId channel_id,
std::pair<int32, vector<DialogParticipant>> ContactsManager::get_channel_participants(
ChannelId channel_id, const tl_object_ptr<td_api::SupergroupMembersFilter> &filter, const string &additional_query,
int32 offset, int32 limit, int32 additional_limit, int64 &random_id, bool force, Promise<Unit> &&promise) {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
if (random_id != 0) {
// request has already been sent before
auto it = received_channel_participants_.find(random_id);
@ -13284,7 +13305,7 @@ std::pair<int32, vector<DialogParticipant>> ContactsManager::get_channel_partici
}
auto user_ids = transform(result.second, [](const auto &participant) { return participant.user_id; });
std::pair<int32, vector<UserId>> result_user_ids = search_among_users(user_ids, additional_query, additional_limit);
std::pair<int32, vector<UserId>> result_user_ids = search_among_users_internal(user_ids, additional_query, additional_limit);
result.first = result_user_ids.first;
std::unordered_set<UserId, UserIdHash> result_user_ids_set(result_user_ids.second.begin(),
@ -13350,6 +13371,7 @@ void ContactsManager::send_get_channel_participants_query(ChannelId channel_id,
vector<DialogAdministrator> ContactsManager::get_dialog_administrators(DialogId dialog_id, int left_tries,
Promise<Unit> &&promise) {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
auto it = dialog_administrators_.find(dialog_id);
if (it != dialog_administrators_.end()) {
promise.set_value(Unit());
@ -13954,6 +13976,11 @@ td_api::object_ptr<td_api::updateUser> ContactsManager::get_update_unknown_user_
}
int32 ContactsManager::get_user_id_object(UserId user_id, const char *source) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return get_user_id_object_internal(user_id, source);
}
int32 ContactsManager::get_user_id_object_internal(UserId user_id, const char *source) const {
if (user_id.is_valid() && get_user(user_id) == nullptr && unknown_users_.count(user_id) == 0) {
LOG(ERROR) << "Have no info about " << user_id << " from " << source;
unknown_users_.insert(user_id);
@ -13963,6 +13990,7 @@ int32 ContactsManager::get_user_id_object(UserId user_id, const char *source) co
}
tl_object_ptr<td_api::user> ContactsManager::get_user_object(UserId user_id) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return get_user_object(user_id, get_user(user_id));
}
@ -13988,18 +14016,30 @@ tl_object_ptr<td_api::user> ContactsManager::get_user_object(UserId user_id, con
}
vector<int32> ContactsManager::get_user_ids_object(const vector<UserId> &user_ids, const char *source) const {
return transform(user_ids, [this, source](UserId user_id) { return get_user_id_object(user_id, source); });
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return get_user_ids_object_internal(user_ids, source);
}
vector<int32> ContactsManager::get_user_ids_object_internal(const vector<UserId> &user_ids, const char *source) const {
return transform(user_ids, [this, source](UserId user_id) { return get_user_id_object_internal(user_id, source); });
}
tl_object_ptr<td_api::users> ContactsManager::get_users_object(int32 total_count,
const vector<UserId> &user_ids) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return get_users_object_internal(total_count, user_ids);
}
tl_object_ptr<td_api::users> ContactsManager::get_users_object_internal(int32 total_count,
const vector<UserId> &user_ids) const {
if (total_count == -1) {
total_count = narrow_cast<int32>(user_ids.size());
}
return td_api::make_object<td_api::users>(total_count, get_user_ids_object(user_ids, "get_users_object"));
return td_api::make_object<td_api::users>(total_count, get_user_ids_object_internal(user_ids, "get_users_object"));
}
tl_object_ptr<td_api::userFullInfo> ContactsManager::get_user_full_info_object(UserId user_id) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return get_user_full_info_object(user_id, get_user_full(user_id));
}
@ -14020,6 +14060,11 @@ td_api::object_ptr<td_api::updateBasicGroup> ContactsManager::get_update_unknown
}
int32 ContactsManager::get_basic_group_id_object(ChatId chat_id, const char *source) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return get_basic_group_id_object_internal(chat_id, source);
}
int32 ContactsManager::get_basic_group_id_object_internal(ChatId chat_id, const char *source) const {
if (chat_id.is_valid() && get_chat(chat_id) == nullptr && unknown_chats_.count(chat_id) == 0) {
LOG(ERROR) << "Have no info about " << chat_id << " from " << source;
unknown_chats_.insert(chat_id);
@ -14029,6 +14074,7 @@ int32 ContactsManager::get_basic_group_id_object(ChatId chat_id, const char *sou
}
tl_object_ptr<td_api::basicGroup> ContactsManager::get_basic_group_object(ChatId chat_id) {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return get_basic_group_object(chat_id, get_chat(chat_id));
}
@ -14045,10 +14091,11 @@ tl_object_ptr<td_api::basicGroup> ContactsManager::get_basic_group_object(ChatId
tl_object_ptr<td_api::basicGroup> ContactsManager::get_basic_group_object_const(ChatId chat_id, const Chat *c) const {
return make_tl_object<td_api::basicGroup>(
chat_id.get(), c->participant_count, get_chat_status(c).get_chat_member_status_object(), c->is_active,
get_supergroup_id_object(c->migrated_to_channel_id, "get_basic_group_object"));
get_supergroup_id_object_internal(c->migrated_to_channel_id, "get_basic_group_object"));
}
tl_object_ptr<td_api::basicGroupFullInfo> ContactsManager::get_basic_group_full_info_object(ChatId chat_id) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return get_basic_group_full_info_object(get_chat_full(chat_id));
}
@ -14057,7 +14104,7 @@ tl_object_ptr<td_api::basicGroupFullInfo> ContactsManager::get_basic_group_full_
CHECK(chat_full != nullptr);
return make_tl_object<td_api::basicGroupFullInfo>(
get_chat_photo_object(td_->file_manager_.get(), chat_full->photo), chat_full->description,
get_user_id_object(chat_full->creator_user_id, "basicGroupFullInfo"),
get_user_id_object_internal(chat_full->creator_user_id, "basicGroupFullInfo"),
transform(chat_full->participants,
[this](const DialogParticipant &chat_participant) { return get_chat_member_object(chat_participant); }),
chat_full->invite_link);
@ -14071,6 +14118,11 @@ td_api::object_ptr<td_api::updateSupergroup> ContactsManager::get_update_unknown
}
int32 ContactsManager::get_supergroup_id_object(ChannelId channel_id, const char *source) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return get_supergroup_id_object_internal(channel_id, source);
}
int32 ContactsManager::get_supergroup_id_object_internal(ChannelId channel_id, const char *source) const {
if (channel_id.is_valid() && get_channel(channel_id) == nullptr && unknown_channels_.count(channel_id) == 0) {
LOG(ERROR) << "Have no info about " << channel_id << " received from " << source;
unknown_channels_.insert(channel_id);
@ -14080,6 +14132,7 @@ int32 ContactsManager::get_supergroup_id_object(ChannelId channel_id, const char
}
tl_object_ptr<td_api::supergroup> ContactsManager::get_supergroup_object(ChannelId channel_id) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return get_supergroup_object(channel_id, get_channel(channel_id));
}
@ -14094,6 +14147,7 @@ tl_object_ptr<td_api::supergroup> ContactsManager::get_supergroup_object(Channel
}
tl_object_ptr<td_api::supergroupFullInfo> ContactsManager::get_supergroup_full_info_object(ChannelId channel_id) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
return get_supergroup_full_info_object(get_channel_full(channel_id));
}
@ -14114,7 +14168,7 @@ tl_object_ptr<td_api::supergroupFullInfo> ContactsManager::get_supergroup_full_i
channel_full->can_set_sticker_set, channel_full->can_set_location, channel_full->stats_dc_id.is_exact(),
channel_full->is_all_history_available, channel_full->sticker_set_id.get(),
channel_full->location.get_chat_location_object(), channel_full->invite_link,
get_basic_group_id_object(channel_full->migrated_from_chat_id, "get_supergroup_full_info_object"),
get_basic_group_id_object_internal(channel_full->migrated_from_chat_id, "get_supergroup_full_info_object"),
channel_full->migrated_from_max_message_id.get());
}
@ -14165,7 +14219,7 @@ tl_object_ptr<td_api::secretChat> ContactsManager::get_secret_chat_object(Secret
tl_object_ptr<td_api::secretChat> ContactsManager::get_secret_chat_object_const(SecretChatId secret_chat_id,
const SecretChat *secret_chat) const {
return td_api::make_object<td_api::secretChat>(
secret_chat_id.get(), get_user_id_object(secret_chat->user_id, "secretChat"),
secret_chat_id.get(), get_user_id_object_internal(secret_chat->user_id, "secretChat"),
get_secret_chat_state_object(secret_chat->state), secret_chat->is_outbound, secret_chat->ttl,
secret_chat->key_hash, secret_chat->layer);
}
@ -14184,6 +14238,7 @@ td_api::object_ptr<td_api::botInfo> ContactsManager::get_bot_info_object(UserId
tl_object_ptr<td_api::chatInviteLinkInfo> ContactsManager::get_chat_invite_link_info_object(
const string &invite_link) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
auto it = invite_link_infos_.find(invite_link);
if (it == invite_link_infos_.end()) {
return nullptr;
@ -14217,7 +14272,7 @@ tl_object_ptr<td_api::chatInviteLinkInfo> ContactsManager::get_chat_invite_link_
LOG(ERROR) << "Have no information about " << chat_id;
}
chat_type = td_api::make_object<td_api::chatTypeBasicGroup>(
get_basic_group_id_object(chat_id, "get_chat_invite_link_info_object"));
get_basic_group_id_object_internal(chat_id, "get_chat_invite_link_info_object"));
break;
}
case DialogType::Channel: {
@ -14236,7 +14291,7 @@ tl_object_ptr<td_api::chatInviteLinkInfo> ContactsManager::get_chat_invite_link_
LOG(ERROR) << "Have no information about " << channel_id;
}
chat_type = td_api::make_object<td_api::chatTypeSupergroup>(
get_supergroup_id_object(channel_id, "get_chat_invite_link_info_object"), !is_megagroup);
get_supergroup_id_object_internal(channel_id, "get_chat_invite_link_info_object"), !is_megagroup);
break;
}
default:
@ -14247,7 +14302,7 @@ tl_object_ptr<td_api::chatInviteLinkInfo> ContactsManager::get_chat_invite_link_
invite_link_photo = as_fake_dialog_photo(invite_link_info->photo);
photo = &invite_link_photo;
participant_count = invite_link_info->participant_count;
member_user_ids = get_user_ids_object(invite_link_info->participant_user_ids, "get_chat_invite_link_info_object");
member_user_ids = get_user_ids_object_internal(invite_link_info->participant_user_ids, "get_chat_invite_link_info_object");
is_public = invite_link_info->is_public;
if (invite_link_info->is_chat) {
@ -14274,6 +14329,7 @@ tl_object_ptr<td_api::chatInviteLinkInfo> ContactsManager::get_chat_invite_link_
}
UserId ContactsManager::get_support_user(Promise<Unit> &&promise) {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
if (support_user_id_.is_valid()) {
promise.set_value(Unit());
return support_user_id_;
@ -14284,6 +14340,7 @@ UserId ContactsManager::get_support_user(Promise<Unit> &&promise) {
}
void ContactsManager::after_get_difference() {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
if (td_->auth_manager_->is_bot()) {
return;
}
@ -14291,6 +14348,7 @@ void ContactsManager::after_get_difference() {
}
void ContactsManager::get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const {
std::shared_lock<std::shared_timed_mutex> readerLock(memory_cleanup_mutex);
for (auto user_id : unknown_users_) {
if (!have_min_user(user_id)) {
updates.push_back(get_update_unknown_user_object(user_id));
@ -14307,7 +14365,7 @@ void ContactsManager::get_current_state(vector<td_api::object_ptr<td_api::Update
}
}
for (auto secret_chat_id : unknown_secret_chats_) {
if (!have_secret_chat(secret_chat_id)) {
if (!have_secret_chat_internal(secret_chat_id)) {
updates.push_back(get_update_unknown_secret_chat_object(secret_chat_id));
}
}
@ -14342,6 +14400,7 @@ void ContactsManager::get_current_state(vector<td_api::object_ptr<td_api::Update
}
void ContactsManager::memory_cleanup() {
std::lock_guard<std::shared_timed_mutex> writerLock(memory_cleanup_mutex);
users_.clear();
users_.rehash(0);
users_full_.clear();
@ -14352,6 +14411,8 @@ void ContactsManager::memory_cleanup() {
user_photos_.rehash(0);
unknown_users_.clear();
unknown_users_.rehash(0);
pending_user_photos_.clear();
pending_user_photos_.rehash(0);
user_profile_photo_file_source_ids_.clear();
user_profile_photo_file_source_ids_.rehash(0);
my_photo_file_id_.clear();
@ -14386,18 +14447,28 @@ void ContactsManager::memory_cleanup() {
invite_link_infos_.rehash(0);
dialog_access_by_invite_link_.clear();
dialog_access_by_invite_link_.rehash(0);
load_user_from_database_queries_.clear();
load_user_from_database_queries_.rehash(0);
loaded_from_database_users_.clear();
loaded_from_database_users_.rehash(0);
unavailable_user_fulls_.clear();
unavailable_user_fulls_.rehash(0);
unavailable_bot_infos_.clear();
unavailable_bot_infos_.rehash(0);
load_chat_from_database_queries_.clear();
load_chat_from_database_queries_.rehash(0);
loaded_from_database_chats_.clear();
loaded_from_database_chats_.rehash(0);
unavailable_chat_fulls_.clear();
unavailable_chat_fulls_.rehash(0);
load_channel_from_database_queries_.clear();
load_channel_from_database_queries_.rehash(0);
loaded_from_database_channels_.clear();
loaded_from_database_channels_.rehash(0);
unavailable_channel_fulls_.clear();
unavailable_channel_fulls_.rehash(0);
load_secret_chat_from_database_queries_.clear();
load_secret_chat_from_database_queries_.rehash(0);
loaded_from_database_secret_chats_.clear();
loaded_from_database_secret_chats_.rehash(0);
dialog_administrators_.clear();
@ -14414,6 +14485,11 @@ void ContactsManager::memory_cleanup() {
cached_channel_participants_.rehash(0);
found_blocked_users_.clear();
found_blocked_users_.rehash(0);
load_contacts_queries_.clear();
load_imported_contacts_queries_.clear();
all_imported_contacts_.clear();
users_nearby_.clear();
channels_nearby_.clear();
all_users_nearby_.clear();
all_users_nearby_.rehash(0);
linked_channel_ids_.clear();
@ -14422,7 +14498,8 @@ void ContactsManager::memory_cleanup() {
restricted_user_ids_.rehash(0);
restricted_channel_ids_.clear();
restricted_channel_ids_.rehash(0);
restricted_channel_ids_.clear();
restricted_channel_ids_.rehash(0);
next_all_imported_contacts_.clear();
imported_contact_user_ids_.clear();
unimported_contact_invites_.clear();
}
} // namespace td

View File

@ -47,6 +47,7 @@
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <shared_mutex>
namespace td {
@ -469,12 +470,14 @@ class ContactsManager : public Actor {
bool get_channel(ChannelId channel_id, int left_tries, Promise<Unit> &&promise);
void reload_channel(ChannelId chnanel_id, Promise<Unit> &&promise);
bool get_channel_full(ChannelId channel_id, bool force, Promise<Unit> &&promise);
bool get_channel_full_internal(ChannelId channel_id, bool force, Promise<Unit> &&promise);
FileSourceId get_channel_full_file_source_id(ChannelId channel_id);
void reload_channel_full(ChannelId channel_id, Promise<Unit> &&promise, const char *source);
bool is_channel_public(ChannelId channel_id) const;
bool have_secret_chat(SecretChatId secret_chat_id) const;
bool have_secret_chat_internal(SecretChatId secret_chat_id) const;
bool have_secret_chat_force(SecretChatId secret_chat_id);
bool get_secret_chat(SecretChatId secret_chat_id, bool force, Promise<Unit> &&promise);
bool get_secret_chat_full(SecretChatId secret_chat_id, Promise<Unit> &&promise);
@ -489,6 +492,8 @@ class ContactsManager : public Actor {
std::pair<int32, vector<UserId>> search_among_users(const vector<UserId> &user_ids, const string &query, int32 limit);
std::pair<int32, vector<UserId>> search_among_users_internal(const vector<UserId> &user_ids, const string &query, int32 limit);
DialogParticipant get_chat_participant(ChatId chat_id, UserId user_id, bool force, Promise<Unit> &&promise);
std::pair<int32, vector<DialogParticipant>> search_chat_participants(ChatId chat_id, const string &query, int32 limit,
@ -513,22 +518,32 @@ class ContactsManager : public Actor {
int32 get_user_id_object(UserId user_id, const char *source) const;
int32 get_user_id_object_internal(UserId user_id, const char *source) const;
tl_object_ptr<td_api::user> get_user_object(UserId user_id) const;
vector<int32> get_user_ids_object(const vector<UserId> &user_ids, const char *source) const;
vector<int32> get_user_ids_object_internal(const vector<UserId> &user_ids, const char *source) const;
tl_object_ptr<td_api::users> get_users_object(int32 total_count, const vector<UserId> &user_ids) const;
tl_object_ptr<td_api::users> get_users_object_internal(int32 total_count, const vector<UserId> &user_ids) const;
tl_object_ptr<td_api::userFullInfo> get_user_full_info_object(UserId user_id) const;
int32 get_basic_group_id_object(ChatId chat_id, const char *source) const;
int32 get_basic_group_id_object_internal(ChatId chat_id, const char *source) const;
tl_object_ptr<td_api::basicGroup> get_basic_group_object(ChatId chat_id);
tl_object_ptr<td_api::basicGroupFullInfo> get_basic_group_full_info_object(ChatId chat_id) const;
int32 get_supergroup_id_object(ChannelId channel_id, const char *source) const;
int32 get_supergroup_id_object_internal(ChannelId channel_id, const char *source) const;
tl_object_ptr<td_api::supergroup> get_supergroup_object(ChannelId channel_id) const;
tl_object_ptr<td_api::supergroupFullInfo> get_supergroup_full_info_object(ChannelId channel_id) const;
@ -1086,7 +1101,9 @@ class ContactsManager : public Actor {
Channel *add_channel(ChannelId channel_id, const char *source);
const ChannelFull *get_channel_full(ChannelId channel_id) const;
const ChannelFull *get_channel_full_internal(ChannelId channel_id) const;
ChannelFull *get_channel_full(ChannelId channel_id, const char *source);
ChannelFull *get_channel_full_internal(ChannelId channel_id, const char *source);
ChannelFull *get_channel_full_force(ChannelId channel_id, const char *source);
ChannelFull *add_channel_full(ChannelId channel_id);
@ -1587,6 +1604,8 @@ class ContactsManager : public Actor {
MultiTimeout user_nearby_timeout_{"UserNearbyTimeout"};
MultiTimeout slow_mode_delay_timeout_{"SlowModeDelayTimeout"};
MultiTimeout invite_link_info_expire_timeout_{"InviteLinkInfoExpireTimeout"};
mutable std::shared_timed_mutex memory_cleanup_mutex;
};
} // namespace td