|
@@ -0,0 +1,144 @@
|
|
|
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
+From: Andrey Belenko <[email protected]>
|
|
|
+Date: Fri, 3 Jul 2020 18:40:01 +0200
|
|
|
+Subject: Backport 1063177
|
|
|
+ (https://chromium-review.googlesource.com/c/chromium/src/+/2111393/)
|
|
|
+
|
|
|
+diff --git a/extensions/browser/api/declarative_net_request/file_sequence_helper.cc b/extensions/browser/api/declarative_net_request/file_sequence_helper.cc
|
|
|
+index 705f376b68470e5199101b2d8d41965e8363b490..45d2e82cd4412356ec59c210a65d49608fe2de99 100644
|
|
|
+--- a/extensions/browser/api/declarative_net_request/file_sequence_helper.cc
|
|
|
++++ b/extensions/browser/api/declarative_net_request/file_sequence_helper.cc
|
|
|
+@@ -6,9 +6,11 @@
|
|
|
+
|
|
|
+ #include <utility>
|
|
|
+
|
|
|
++#include "base/barrier_closure.h"
|
|
|
+ #include "base/bind.h"
|
|
|
+ #include "base/files/file_util.h"
|
|
|
+ #include "base/logging.h"
|
|
|
++#include "base/memory/ref_counted.h"
|
|
|
+ #include "base/metrics/histogram_functions.h"
|
|
|
+ #include "base/metrics/histogram_macros.h"
|
|
|
+ #include "base/stl_util.h"
|
|
|
+@@ -31,53 +33,59 @@ namespace {
|
|
|
+ namespace dnr_api = extensions::api::declarative_net_request;
|
|
|
+
|
|
|
+ // A class to help in re-indexing multiple rulesets.
|
|
|
+-class ReindexHelper {
|
|
|
++class ReindexHelper : public base::RefCountedThreadSafe<ReindexHelper> {
|
|
|
+ public:
|
|
|
+- // Starts re-indexing rulesets. Must be called on the extension file task
|
|
|
+- // runner.
|
|
|
+ using ReindexCallback = base::OnceCallback<void(LoadRequestData)>;
|
|
|
+- static void Start(service_manager::Connector* connector,
|
|
|
+- LoadRequestData data,
|
|
|
+- ReindexCallback callback) {
|
|
|
+- auto* helper = new ReindexHelper(std::move(data), std::move(callback));
|
|
|
+- helper->Start(connector);
|
|
|
+- }
|
|
|
+-
|
|
|
+- private:
|
|
|
+- // We manage our own lifetime.
|
|
|
+ ReindexHelper(LoadRequestData data, ReindexCallback callback)
|
|
|
+ : data_(std::move(data)), callback_(std::move(callback)) {}
|
|
|
+- ~ReindexHelper() = default;
|
|
|
+-
|
|
|
++
|
|
|
++ // Starts re-indexing rulesets. Must be called on the extension file task
|
|
|
++ // runner.
|
|
|
+ void Start(service_manager::Connector* connector) {
|
|
|
+ DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence());
|
|
|
+
|
|
|
+ base::Token token = base::Token::CreateRandom();
|
|
|
+
|
|
|
+- // Post tasks to reindex individual rulesets.
|
|
|
+- bool did_post_task = false;
|
|
|
++ std::vector<RulesetInfo*> rulesets_to_reindex;
|
|
|
++
|
|
|
+ for (auto& ruleset : data_.rulesets) {
|
|
|
+ if (ruleset.did_load_successfully())
|
|
|
+ continue;
|
|
|
++
|
|
|
++ rulesets_to_reindex.push_back(&ruleset);
|
|
|
++ }
|
|
|
+
|
|
|
+- // Using Unretained is safe since this class manages its own lifetime and
|
|
|
+- // |this| won't be deleted until the |callback| returns.
|
|
|
+- auto callback = base::BindOnce(&ReindexHelper::OnReindexCompleted,
|
|
|
+- base::Unretained(this), &ruleset);
|
|
|
+- callback_count_++;
|
|
|
+- did_post_task = true;
|
|
|
+- ruleset.source().IndexAndPersistJSONRuleset(connector, token,
|
|
|
++ // |done_closure| will be invoked once |barrier_closure| is run
|
|
|
++ // |rulesets_to_reindex.size()| times.
|
|
|
++ base::OnceClosure done_closure =
|
|
|
++ base::BindOnce(&ReindexHelper::OnAllRulesetsReindexed, this);
|
|
|
++ base::RepeatingClosure barrier_closure = base::BarrierClosure(
|
|
|
++ rulesets_to_reindex.size(), std::move(done_closure));
|
|
|
++
|
|
|
++ // Post tasks to reindex individual rulesets.
|
|
|
++ for (RulesetInfo* ruleset : rulesets_to_reindex) {
|
|
|
++ auto callback = base::BindOnce(&ReindexHelper::OnReindexCompleted, this,
|
|
|
++ ruleset, barrier_closure);
|
|
|
++ ruleset->source().IndexAndPersistJSONRuleset(connector, token,
|
|
|
+ std::move(callback));
|
|
|
+ }
|
|
|
++ }
|
|
|
++
|
|
|
++private:
|
|
|
++ friend class base::RefCountedThreadSafe<ReindexHelper>;
|
|
|
++ ~ReindexHelper() = default;
|
|
|
+
|
|
|
+- // It's possible that the callbacks return synchronously and we are deleted
|
|
|
+- // at this point. Hence don't use any member variables here. Also, if we
|
|
|
+- // don't post any task, we'll leak. Ensure that's not the case.
|
|
|
+- DCHECK(did_post_task);
|
|
|
++ // Callback invoked when reindexing of all rulesets is completed.
|
|
|
++ void OnAllRulesetsReindexed() {
|
|
|
++ DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence());
|
|
|
++
|
|
|
++ // Our job is done.
|
|
|
++ std::move(callback_).Run(std::move(data_));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Callback invoked when a single ruleset is re-indexed.
|
|
|
+ void OnReindexCompleted(RulesetInfo* ruleset,
|
|
|
++ base::OnceClosure done_closure,
|
|
|
+ IndexAndPersistJSONRulesetResult result) {
|
|
|
+ DCHECK(ruleset);
|
|
|
+
|
|
|
+@@ -108,20 +116,12 @@ class ReindexHelper {
|
|
|
+ UMA_HISTOGRAM_BOOLEAN(
|
|
|
+ "Extensions.DeclarativeNetRequest.RulesetReindexSuccessful",
|
|
|
+ reindexing_success);
|
|
|
+-
|
|
|
+- callback_count_--;
|
|
|
+- DCHECK_GE(callback_count_, 0);
|
|
|
+-
|
|
|
+- if (callback_count_ == 0) {
|
|
|
+- // Our job is done.
|
|
|
+- std::move(callback_).Run(std::move(data_));
|
|
|
+- delete this;
|
|
|
+- }
|
|
|
++
|
|
|
++ std::move(done_closure).Run();
|
|
|
+ }
|
|
|
+
|
|
|
+ LoadRequestData data_;
|
|
|
+ ReindexCallback callback_;
|
|
|
+- int callback_count_ = 0;
|
|
|
+
|
|
|
+ DISALLOW_COPY_AND_ASSIGN(ReindexHelper);
|
|
|
+ };
|
|
|
+@@ -382,8 +382,9 @@ void FileSequenceHelper::LoadRulesets(
|
|
|
+ auto reindex_callback =
|
|
|
+ base::BindOnce(&FileSequenceHelper::OnRulesetsReindexed,
|
|
|
+ weak_factory_.GetWeakPtr(), std::move(ui_callback));
|
|
|
+- ReindexHelper::Start(connector_.get(), std::move(load_data),
|
|
|
+- std::move(reindex_callback));
|
|
|
++ auto reindex_helper = base::MakeRefCounted<ReindexHelper>(
|
|
|
++ std::move(load_data), std::move(reindex_callback));
|
|
|
++ reindex_helper->Start(connector_.get());
|
|
|
+ }
|
|
|
+
|
|
|
+ void FileSequenceHelper::UpdateDynamicRules(
|