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

Unified Diff: chrome/browser/component_updater/component_updater_service.cc

Issue 25713007: Component updater on-demand logic with ResourceThrottle (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: xxx Created 7 years, 1 month 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/component_updater/component_updater_service.cc
===================================================================
--- chrome/browser/component_updater/component_updater_service.cc (revision 232565)
+++ chrome/browser/component_updater/component_updater_service.cc (working copy)
@@ -15,6 +15,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
@@ -31,6 +32,8 @@
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/extensions/extension.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/resource_controller.h"
+#include "content/public/browser/resource_throttle.h"
#include "content/public/browser/utility_process_host.h"
#include "content/public/browser/utility_process_host_client.h"
#include "net/base/escape.h"
@@ -38,6 +41,7 @@
#include "net/base/net_errors.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
+#include "net/url_request/url_request.h"
#include "net/url_request/url_request_status.h"
#include "url/gurl.h"
@@ -237,6 +241,52 @@
CrxComponentInfo::~CrxComponentInfo() {
}
+///////////////////////////////////////////////////////////////////////////////
+// In charge of blocking url requests until the |crx_id| component has been
+// updated. This class is touched solely from the IO thread. The UI thread
+// can post tasks to it via weak pointers. By default the request is blocked
+// unless the CrxUpdateService calls Unblock().
+// The lifetime is controlled by Chrome's resource loader so the component
+// updater cannot touch objects from this class except via weak pointers.
+class CUResourceThrottle
+ : public content::ResourceThrottle,
+ public base::SupportsWeakPtr<CUResourceThrottle> {
+ public:
+ explicit CUResourceThrottle(const net::URLRequest* request);
+ virtual ~CUResourceThrottle();
+ // Overriden from ResourceThrottle.
+ virtual void WillStartRequest(bool* defer) OVERRIDE;
+ virtual void WillRedirectRequest(const GURL& new_url, bool* defer) OVERRIDE;
+
+ // Component updater calls this function via PostTask to unblock the request.
+ void Unblock();
+
+ typedef std::vector<base::WeakPtr<CUResourceThrottle> > WeakPtrVector;
+
+ private:
+ enum State {
+ NEW,
+ BLOCKED,
+ UNBLOCKED
+ };
+
+ State state_;
+};
+
+void UnblockResourceThrottle(base::WeakPtr<CUResourceThrottle> rt) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&CUResourceThrottle::Unblock, rt));
+}
+
+void UnblockandReapAllThrottles(CUResourceThrottle::WeakPtrVector* throttles) {
+ CUResourceThrottle::WeakPtrVector::iterator it;
+ for (it = throttles->begin(); it != throttles->end(); ++it)
+ UnblockResourceThrottle(*it);
+ throttles->clear();
+}
+
//////////////////////////////////////////////////////////////////////////////
// The one and only implementation of the ComponentUpdateService interface. In
// charge of running the show. The main method is ProcessPendingItems() which
@@ -263,6 +313,8 @@
virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE;
virtual void GetComponents(
std::vector<CrxComponentInfo>* components) OVERRIDE;
+ virtual content::ResourceThrottle* GetOnDemandResourceThrottle(
+ net::URLRequest* request, const std::string& crx_id) OVERRIDE;
// The only purpose of this class is to forward the
// UtilityProcessHostClient callbacks so CrxUpdateService does
@@ -343,6 +395,8 @@
bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query);
+ Status OnDemandUpdateInternal(CrxUpdateItem* item);
+
void ProcessPendingItems();
CrxUpdateItem* FindReadyComponent();
@@ -375,6 +429,9 @@
bool HasOnDemandItems() const;
+ void OnNewResourceThrottle(base::WeakPtr<CUResourceThrottle> rt,
+ const std::string& crx_id);
+
scoped_ptr<ComponentUpdateService::Configurator> config_;
scoped_ptr<ComponentPatcher> component_patcher_;
@@ -559,6 +616,13 @@
break;
}
}
+
+ // Free possible pending network requests.
+ if ((to == CrxUpdateItem::kUpdated) ||
+ (to == CrxUpdateItem::kUpToDate) ||
+ (to == CrxUpdateItem::kNoUpdate)) {
+ UnblockandReapAllThrottles(&item->throttles);
+ }
}
// Changes all the components in |work_items_| that have |from| status to
@@ -648,11 +712,13 @@
// |component_id| is a value returned from GetCrxComponentID().
ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate(
const std::string& component_id) {
- CrxUpdateItem* uit;
- uit = FindUpdateItemById(component_id);
+ return OnDemandUpdateInternal(FindUpdateItemById(component_id));
+}
+
+ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateInternal(
+ CrxUpdateItem* uit) {
if (!uit)
return kError;
-
// Check if the request is too soon.
base::TimeDelta delta = base::Time::Now() - uit->last_check;
if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay()))
@@ -1080,6 +1146,66 @@
}
}
+content::ResourceThrottle* CrxUpdateService::GetOnDemandResourceThrottle(
+ net::URLRequest* request, const std::string& crx_id) {
+ // We give the raw pointer to the caller, who will delete it at will
+ // and we keep for ourselves a weak pointer to it so we can post tasks
+ // from the UI thread without having to track lifetime directly.
+ CUResourceThrottle* rt = new CUResourceThrottle(request);
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&CrxUpdateService::OnNewResourceThrottle,
+ base::Unretained(this),
+ rt->AsWeakPtr(),
+ crx_id));
+ return rt;
+}
+
+void CrxUpdateService::OnNewResourceThrottle(
+ base::WeakPtr<CUResourceThrottle> rt, const std::string& crx_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // Check if we can on-demand update, else unblock the request anyway.
+ CrxUpdateItem* item = FindUpdateItemById(crx_id);
+ Status status = OnDemandUpdateInternal(item);
+ if (status == kOk || status == kInProgress) {
+ item->throttles.push_back(rt);
+ return;
+ }
+ UnblockResourceThrottle(rt);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+CUResourceThrottle::CUResourceThrottle(const net::URLRequest* request)
+ : state_(NEW) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+}
+
+CUResourceThrottle::~CUResourceThrottle() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+}
+
+void CUResourceThrottle::WillStartRequest(bool* defer) {
+ if (state_ != UNBLOCKED) {
+ state_ = BLOCKED;
+ *defer = true;
+ } else {
+ *defer = false;
+ }
+}
+
+void CUResourceThrottle::WillRedirectRequest(const GURL& new_url, bool* defer) {
+ WillStartRequest(defer);
+}
+
+void CUResourceThrottle::Unblock() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (state_ == BLOCKED)
+ controller()->Resume();
+ state_ = UNBLOCKED;
+}
+
// The component update factory. Using the component updater as a singleton
// is the job of the browser process.
ComponentUpdateService* ComponentUpdateServiceFactory(
« no previous file with comments | « chrome/browser/component_updater/component_updater_service.h ('k') | chrome/browser/component_updater/crx_update_item.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698