@@ -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