Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(439)

Unified Diff: chrome/browser/policy/async_policy_provider.cc

Issue 10448118: Add the AsyncPolicyProvider and AsyncPolicyLoader (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix unittest Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/policy/async_policy_provider.cc
diff --git a/chrome/browser/policy/async_policy_provider.cc b/chrome/browser/policy/async_policy_provider.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bc42f39643b88ab230beb6b0d8d8daf327a2ae29
--- /dev/null
+++ b/chrome/browser/policy/async_policy_provider.cc
@@ -0,0 +1,102 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/async_policy_provider.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "chrome/browser/policy/async_policy_loader.h"
+#include "chrome/browser/policy/policy_bundle.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+namespace policy {
+
+namespace {
+
+// Helper for a PostTaskAndReply used as a synchronization point between the
+// UI and FILE threads. See AsyncPolicyProvider::RefreshPolicies.
+void Nop() {}
+
+} // namespace
+
+AsyncPolicyProvider::AsyncPolicyProvider(
+ const PolicyDefinitionList* policy_list,
+ AsyncPolicyLoader* loader)
+ : ConfigurationPolicyProvider(policy_list),
+ loader_(loader),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+ pending_refreshes_(0) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 Rather use base::threading::NonThreadSafe? If you
Joao da Silva 2012/06/04 14:05:06 Done. This also required passing the MessageLoop o
+ // The FILE thread isn't ready early during startup. Post a task to UI to
+ // resume initialization on FILE once the loops are spinning.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&AsyncPolicyProvider::InitWithLoopsReady,
+ weak_factory_.GetWeakPtr()));
+ // Make an immediate synchronous load on startup.
+ OnLoaderReloaded(loader->InitialLoad());
+}
+
+AsyncPolicyProvider::~AsyncPolicyProvider() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // Note on the lifetime of |loader_|:
+ // The |loader_| lives on the FILE thread, and is deleted from here. This
+ // means that posting tasks on the |loader_| to FILE from the
+ // AsyncPolicyProvider is always safe, since a potential DeleteSoon() is only
+ // posted from here. The |loader_| posts back to the AsyncPolicyProvider
+ // through the |update_callback_| on UI, which has a WeakPtr to |this|.
+ BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, loader_);
+}
+
+void AsyncPolicyProvider::RefreshPolicies() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ pending_refreshes_++;
+ // Subtle: RefreshPolicies() has a contract that requires the next policy
+ // update notification (triggered from UpdatePolicy()) to reflect any changes
+ // made before this call. So if a test has modified the policy settings and
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 Seems like this doesn't only apply to tests.
Joao da Silva 2012/06/04 14:05:06 s/test/caller
+ // invoked RefreshPolicies(), then by the next notification these policies
+ // should already be provided.
+ // However, it's also possible that an asynchronous Reload() is in progress
+ // and just posted OnLoaderReloaded() to UI. Therefore a task is posted to
+ // FILE before posting the next Reload, to prevent a potential concurrent
+ // Reload() from triggered a notification too early.
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 s/triggered/triggering/
Joao da Silva 2012/06/04 14:05:06 Done.
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(Nop),
+ base::Bind(&AsyncPolicyProvider::PostRefreshingReload,
+ weak_factory_.GetWeakPtr()));
+}
+
+void AsyncPolicyProvider::InitWithLoopsReady() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&AsyncPolicyLoader::Init,
+ base::Unretained(loader_),
+ base::Bind(&AsyncPolicyProvider::OnLoaderReloaded,
+ weak_factory_.GetWeakPtr())));
+}
+
+void AsyncPolicyProvider::PostRefreshingReload() {
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 The name of this function is not very descriptive,
Joao da Silva 2012/06/04 14:05:06 Done.
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(pending_refreshes_ > 0);
+ pending_refreshes_--;
Mattias Nissler (ping if slow) 2012/06/04 08:48:26 Ah, counters. In this case, it's probably not an i
Joao da Silva 2012/06/04 14:05:06 Redone with a CancellableCallback as suggested off
+ if (pending_refreshes_ == 0) {
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&AsyncPolicyLoader::Reload,
+ base::Unretained(loader_),
+ true /* force */));
+ }
+}
+
+void AsyncPolicyProvider::OnLoaderReloaded(scoped_ptr<PolicyBundle> bundle) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (pending_refreshes_ == 0)
+ UpdatePolicy(bundle.Pass());
+}
+
+} // namespace policy

Powered by Google App Engine
This is Rietveld 408576698