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

Unified Diff: content/browser/renderer_data_memoizing_store.h

Issue 68543003: Switch CertStore to RenderProcessHostObserver (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix race? 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/renderer_data_memoizing_store.h
diff --git a/content/browser/renderer_data_memoizing_store.h b/content/browser/renderer_data_memoizing_store.h
index e01685b58288c2d9a6f3be81e06ce635da747844..ff55982b1a8b557b368fdf4c553448cae5c32bc6 100644
--- a/content/browser/renderer_data_memoizing_store.h
+++ b/content/browser/renderer_data_memoizing_store.h
@@ -9,13 +9,9 @@
#include "base/bind.h"
#include "base/synchronization/lock.h"
-#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_process_host_observer.h"
namespace content {
@@ -25,19 +21,19 @@ namespace content {
// object is retained. RendererDataMemoizingStore watches for render process
// termination and releases objects that are no longer associated with any
// render process.
+//
+// TODO(jcampan): Rather than watching for render process termination, we should
+// instead be listening to events such as resource cached/
+// removed from cache, and remove the items when we know they
+// are not used anymore.
template <typename T>
-class RendererDataMemoizingStore : public NotificationObserver {
+class RendererDataMemoizingStore : public RenderProcessHostObserver {
public:
RendererDataMemoizingStore() : next_item_id_(1) {
- if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- RegisterForNotification();
- } else {
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&RendererDataMemoizingStore::RegisterForNotification,
- base::Unretained(this)));
- }
+ }
+
+ ~RendererDataMemoizingStore() {
+ DCHECK_EQ(0U, id_to_item_.size()) << "Failed to outlive render processes";
}
// Store adds |item| to this collection, associates it with the given render
@@ -66,6 +62,7 @@ class RendererDataMemoizingStore : public NotificationObserver {
// Let's update process_id_to_item_id_.
std::pair<IDMap::iterator, IDMap::iterator> process_ids =
process_id_to_item_id_.equal_range(process_id);
+ bool already_watching_process = (process_ids.first != process_ids.second);
if (std::find_if(process_ids.first, process_ids.second,
MatchSecond<int>(item_id)) == process_ids.second) {
process_id_to_item_id_.insert(std::make_pair(process_id, item_id));
@@ -79,6 +76,20 @@ class RendererDataMemoizingStore : public NotificationObserver {
item_id_to_process_id_.insert(std::make_pair(item_id, process_id));
}
+ // If we're not doing so already, keep an eye for the process host deletion.
+ if (!already_watching_process) {
+ if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ StartObservingProcess(process_id);
+ } else {
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&RendererDataMemoizingStore::StartObservingProcess,
+ base::Unretained(this),
+ process_id));
+ }
+ }
+
return item_id;
}
@@ -113,23 +124,22 @@ class RendererDataMemoizingStore : public NotificationObserver {
M value;
};
- void RegisterForNotification() {
- // We watch for RenderProcess termination, as this is how we clear
- // items for now.
- // TODO(jcampan): we should be listening to events such as resource cached/
- // removed from cache, and remove the item when we know it
- // is not used anymore.
-
- registrar_.Add(this,
- NOTIFICATION_RENDERER_PROCESS_TERMINATED,
- NotificationService::AllBrowserContextsAndSources());
- registrar_.Add(this,
- NOTIFICATION_RENDERER_PROCESS_CLOSED,
- NotificationService::AllBrowserContextsAndSources());
+ void StartObservingProcess(int process_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ RenderProcessHost* host = RenderProcessHost::FromID(process_id);
+ if (!host) {
+ // We lost the race to observe the host before it was destroyed. Since
+ // this function was called because we're managing objects tied to that
+ // (now destroyed) RenderProcessHost, let's clean up.
+ RemoveRenderProcessItems(process_id);
+ return;
+ }
+
+ host->AddObserver(this);
}
// Remove the item specified by |item_id| from id_to_item_ and item_to_id_.
- // NOTE: the caller (RemoveForRenderProcesHost) must hold lock_.
+ // NOTE: the caller (RemoveRenderProcessItems) must hold lock_.
void RemoveInternal(int item_id) {
typename ItemMap::iterator item_iter = id_to_item_.find(item_id);
DCHECK(item_iter != id_to_item_.end());
@@ -142,8 +152,13 @@ class RendererDataMemoizingStore : public NotificationObserver {
id_to_item_.erase(item_iter);
}
+ void RenderProcessHostDestroyed(RenderProcessHost* host) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ RemoveRenderProcessItems(host->GetID());
+ }
+
// Removes all the items associated with the specified process from the store.
- void RemoveForRenderProcessHost(int process_id) {
+ void RemoveRenderProcessItems(int process_id) {
base::AutoLock auto_lock(lock_);
// We iterate through all the item ids for that process.
@@ -182,20 +197,6 @@ class RendererDataMemoizingStore : public NotificationObserver {
process_id_to_item_id_.erase(process_ids.first, process_ids.second);
}
- // NotificationObserver implementation.
- void Observe(int type,
- const NotificationSource& source,
- const NotificationDetails& details) OVERRIDE {
- DCHECK(type == NOTIFICATION_RENDERER_PROCESS_TERMINATED ||
- type == NOTIFICATION_RENDERER_PROCESS_CLOSED);
- RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
- DCHECK(rph);
- RemoveForRenderProcessHost(rph->GetID());
- }
-
- // Is only used on the UI Thread.
- NotificationRegistrar registrar_;
-
IDMap process_id_to_item_id_;
IDMap item_id_to_process_id_;
ItemMap id_to_item_;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698