Skip to content

Commit 07d9d95

Browse files
committed
Adjust locking on cs_ConvergedScraperStatsCache in scraperreport
1 parent 93bddcf commit 07d9d95

File tree

1 file changed

+45
-34
lines changed

1 file changed

+45
-34
lines changed

src/gridcoin/scraper/scraper.cpp

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6324,8 +6324,7 @@ UniValue scraperreport(const UniValue& params, bool fHelp)
63246324

63256325
{
63266326
// This lock order is required to avoid potential deadlocks between this function and other threads.
6327-
LOCK(CScraperManifest::cs_mapManifest);
6328-
LOCK2(CSplitBlob::cs_mapParts, cs_ConvergedScraperStatsCache);
6327+
LOCK2(CScraperManifest::cs_mapManifest, CSplitBlob::cs_mapParts);
63296328

63306329
manifest_map_size = CScraperManifest::mapManifest.size();
63316330
pending_deleted_manifest_map_size = CScraperManifest::mapPendingDeletedManifest.size();
@@ -6335,7 +6334,11 @@ UniValue scraperreport(const UniValue& params, bool fHelp)
63356334

63366335
parts_map_size = CSplitBlob::mapParts.size();
63376336

6338-
if (ConvergedScraperStatsCache.NewFormatSuperblock.WellFormed())
6337+
// Note that we would want to, but cannot, hold the cs_ConvergedScraperStatsCache continuously as the outside lock
6338+
// during this function, because in other areas of the code, cs_ConvergedScraperStatsCache is taken as the INSIDE
6339+
// lock, and this results in a potential deadlock situation. So, cs_ConvergedScraperStatsCache is locked three
6340+
// different times here. The third one is the most important, where it is locked AFTER cs_manifest.
6341+
if (WITH_LOCK(cs_ConvergedScraperStatsCache, return ConvergedScraperStatsCache.NewFormatSuperblock.WellFormed()))
63396342
{
63406343
uint64_t current_convergence_publishing_scrapers = 0;
63416344
uint64_t current_convergence_part_pointer_map_size = 0;
@@ -6353,47 +6356,53 @@ UniValue scraperreport(const UniValue& params, bool fHelp)
63536356
UniValue manifests_with_null_phashes(UniValue::VARR);
63546357
UniValue csplitblobs_invalid_manifests(UniValue::VARR);
63556358

6356-
current_convergence_publishing_scrapers =
6357-
ConvergedScraperStatsCache.Convergence.vIncludedScrapers.size()
6358-
+ ConvergedScraperStatsCache.Convergence.vExcludedScrapers.size();
6359+
uint64_t total_convergences_part_pointer_maps_size = 0;
63596360

6360-
current_convergence_part_pointer_map_size =
6361-
ConvergedScraperStatsCache.Convergence.ConvergedManifestPartPtrsMap.size();
6362-
6363-
past_convergence_map_size =
6364-
ConvergedScraperStatsCache.PastConvergences.size();
6361+
{
6362+
LOCK(cs_ConvergedScraperStatsCache);
63656363

6366-
// Count the number of convergences that are by part (project). Note that these WILL NOT be in the
6367-
// manifest maps, because they are composite manifests that are LOCAL ONLY. If the convergences
6368-
// are at the manifest level, then the CScraperManifest_shared_ptr CScraperConvergedManifest_ptr
6369-
// will point to a manifest that IS ALREADY IN THE mapManifest.
6370-
if (ConvergedScraperStatsCache.Convergence.bByParts) ++number_of_convergences_by_parts;
6364+
current_convergence_publishing_scrapers =
6365+
ConvergedScraperStatsCache.Convergence.vIncludedScrapers.size()
6366+
+ ConvergedScraperStatsCache.Convergence.vExcludedScrapers.size();
63716367

6372-
// Finish adding the number of convergences by parts below in the for loop for the PastConvergences so we
6373-
// don't have to traverse twice.
6368+
current_convergence_part_pointer_map_size =
6369+
ConvergedScraperStatsCache.Convergence.ConvergedManifestPartPtrsMap.size();
63746370

6375-
// This next section will form a set of unique pointers in the global cache
6376-
// and also add the pointers up arithmetically. The difference is the efficiency gain
6377-
// from using pointers rather than copies into the global cache.
6378-
for (const auto& iter : ConvergedScraperStatsCache.Convergence.ConvergedManifestPartPtrsMap)
6379-
{
6380-
global_cache_unique_parts.insert(iter.second);
6381-
}
6371+
past_convergence_map_size =
6372+
ConvergedScraperStatsCache.PastConvergences.size();
63826373

6383-
uint64_t total_convergences_part_pointer_maps_size = current_convergence_part_pointer_map_size;
6374+
// Count the number of convergences that are by part (project). Note that these WILL NOT be in the
6375+
// manifest maps, because they are composite manifests that are LOCAL ONLY. If the convergences
6376+
// are at the manifest level, then the CScraperManifest_shared_ptr CScraperConvergedManifest_ptr
6377+
// will point to a manifest that IS ALREADY IN THE mapManifest.
6378+
if (ConvergedScraperStatsCache.Convergence.bByParts) ++number_of_convergences_by_parts;
63846379

6385-
for (const auto& iter : ConvergedScraperStatsCache.PastConvergences)
6386-
{
6387-
// This increments if the past convergence is by parts because these will NOT be in the manifest maps.
6388-
if (iter.second.second.bByParts) ++number_of_convergences_by_parts;
6380+
// Finish adding the number of convergences by parts below in the for loop for the PastConvergences so we
6381+
// don't have to traverse twice.
63896382

6390-
for (const auto& iter2 : iter.second.second.ConvergedManifestPartPtrsMap)
6383+
// This next section will form a set of unique pointers in the global cache
6384+
// and also add the pointers up arithmetically. The difference is the efficiency gain
6385+
// from using pointers rather than copies into the global cache.
6386+
for (const auto& iter : ConvergedScraperStatsCache.Convergence.ConvergedManifestPartPtrsMap)
63916387
{
6392-
global_cache_unique_parts.insert(iter2.second);
6388+
global_cache_unique_parts.insert(iter.second);
63936389
}
63946390

6395-
total_convergences_part_pointer_maps_size +=
6396-
iter.second.second.ConvergedManifestPartPtrsMap.size();
6391+
total_convergences_part_pointer_maps_size = current_convergence_part_pointer_map_size;
6392+
6393+
for (const auto& iter : ConvergedScraperStatsCache.PastConvergences)
6394+
{
6395+
// This increments if the past convergence is by parts because these will NOT be in the manifest maps.
6396+
if (iter.second.second.bByParts) ++number_of_convergences_by_parts;
6397+
6398+
for (const auto& iter2 : iter.second.second.ConvergedManifestPartPtrsMap)
6399+
{
6400+
global_cache_unique_parts.insert(iter2.second);
6401+
}
6402+
6403+
total_convergences_part_pointer_maps_size +=
6404+
iter.second.second.ConvergedManifestPartPtrsMap.size();
6405+
}
63976406
}
63986407

63996408
global_scraper_net.pushKV("number_of_convergences_by_parts", number_of_convergences_by_parts);
@@ -6466,6 +6475,8 @@ UniValue scraperreport(const UniValue& params, bool fHelp)
64666475
} // valid manifest but null pointer to index hash
64676476
else
64686477
{
6478+
LOCK(cs_ConvergedScraperStatsCache);
6479+
64696480
// The current convergence (i.e. a by parts convergence in the local global cache but not in
64706481
// the published maps?
64716482
if (ConvergedScraperStatsCache.Convergence.CScraperConvergedManifest_ptr.get() != manifest_ptr)

0 commit comments

Comments
 (0)