RsGxsNetService::receiveTurtleSearchResults fix deadlock

Avoid notifing observer while the mutex is locked by storing results in
a temporary set
This commit is contained in:
Gioacchino Mazzurco 2018-08-16 14:26:41 +02:00
parent b4dd89dd87
commit b7f5d4286f
No known key found for this signature in database
GPG Key ID: A1FBCA3872E87051

View File

@ -5181,10 +5181,14 @@ bool RsGxsNetService::clearDistantSearchResults(const TurtleRequestId& id)
} }
void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req, const std::list<RsGxsGroupSummary>& group_infos) void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req, const std::list<RsGxsGroupSummary>& group_infos)
{ {
RS_STACK_MUTEX(mNxsMutex) ; std::set<RsGxsGroupId> groupsToNotifyResults;
{
RS_STACK_MUTEX(mNxsMutex);
RsGxsGrpMetaTemporaryMap grpMeta; RsGxsGrpMetaTemporaryMap grpMeta;
std::map<RsGxsGroupId,RsGxsGroupSummary>& search_results_map(mDistantSearchResults[req]) ; std::map<RsGxsGroupId,RsGxsGroupSummary>&
search_results_map(mDistantSearchResults[req]);
for(auto it(group_infos.begin());it!=group_infos.end();++it) for(auto it(group_infos.begin());it!=group_infos.end();++it)
if(search_results_map.find((*it).mGroupId) == search_results_map.end()) if(search_results_map.find((*it).mGroupId) == search_results_map.end())
@ -5192,32 +5196,36 @@ void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req, const std:
mDataStore->retrieveGxsGrpMetaData(grpMeta); mDataStore->retrieveGxsGrpMetaData(grpMeta);
std::list<RsGxsGroupSummary> filtered_results ;
// only keep groups that are not locally known, and groups that are not already in the mDistantSearchResults structure // only keep groups that are not locally known, and groups that are not already in the mDistantSearchResults structure
for(auto it(group_infos.begin());it!=group_infos.end();++it) for(auto it(group_infos.begin());it!=group_infos.end();++it)
if(grpMeta[(*it).mGroupId] == NULL) if(grpMeta[(*it).mGroupId] == NULL)
{ {
filtered_results.push_back(*it) ; const RsGxsGroupId& grpId((*it).mGroupId);
auto it2 = search_results_map.find((*it).mGroupId) ; groupsToNotifyResults.insert(grpId);
auto it2 = search_results_map.find(grpId);
if(it2 != search_results_map.end()) if(it2 != search_results_map.end())
{ {
// update existing data // update existing data
it2->second.mPopularity++ ; it2->second.mPopularity++;
it2->second.mNumberOfMessages = std::max(it2->second.mNumberOfMessages,(*it).mNumberOfMessages) ; it2->second.mNumberOfMessages = std::max(
it2->second.mNumberOfMessages,
(*it).mNumberOfMessages );
} }
else else
{ {
search_results_map[(*it).mGroupId] = *it; search_results_map[grpId] = *it;
search_results_map[(*it).mGroupId].mPopularity = 1; // number of results so far search_results_map[grpId].mPopularity = 1; // number of results so far
} }
}
} // end RS_STACK_MUTEX(mNxsMutex);
mObserver->receiveDistantSearchResults(req,(*it).mGroupId) ; for(const RsGxsGroupId& grpId : groupsToNotifyResults)
} mObserver->receiveDistantSearchResults(req, grpId);
} }
void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len) void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len)