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

Unified Diff: chrome/browser/extensions/lazy_background_task_queue.cc

Issue 10114015: Fix bug where transient pages would miss events dispatched while it was (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 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/extensions/lazy_background_task_queue.cc
diff --git a/chrome/browser/extensions/lazy_background_task_queue.cc b/chrome/browser/extensions/lazy_background_task_queue.cc
index bb1b1a21d238d00fc82d0f2161d915a13776e8f1..93d56768459decb8d6280a371dc15614962ca6bd 100644
--- a/chrome/browser/extensions/lazy_background_task_queue.cc
+++ b/chrome/browser/extensions/lazy_background_task_queue.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/extensions/lazy_background_task_queue.h"
#include "base/callback.h"
+#include "base/message_loop.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_service.h"
@@ -43,10 +44,12 @@ bool LazyBackgroundTaskQueue::ShouldEnqueueTask(
Profile* profile, const Extension* extension) {
DCHECK(extension);
if (extension->has_lazy_background_page()) {
- ExtensionProcessManager* pm = profile->GetExtensionProcessManager();
+ ExtensionProcessManager* pm =
+ ExtensionSystem::Get(profile)->process_manager();
ExtensionHost* background_host =
pm->GetBackgroundHostForExtension(extension->id());
- if (!background_host || !background_host->did_stop_loading())
+ if (!background_host || !background_host->did_stop_loading() ||
+ pm->IsBackgroundHostClosing(extension->id()))
return true;
}
@@ -66,14 +69,8 @@ void LazyBackgroundTaskQueue::AddPendingTask(
// If this is the first enqueued task, ensure the background page
Yoyo Zhou 2012/04/19 21:47:13 This comment needs an "and we are not waiting for
Matt Perry 2012/04/19 22:21:53 Done.
// is loaded.
- const Extension* extension =
- ExtensionSystem::Get(profile)->extension_service()->
- extensions()->GetByID(extension_id);
- DCHECK(extension->has_lazy_background_page());
- ExtensionProcessManager* pm =
- ExtensionSystem::Get(profile)->process_manager();
- pm->IncrementLazyKeepaliveCount(extension);
- pm->CreateBackgroundHost(extension, extension->GetBackgroundURL());
+ if (pending_page_loads_.count(key) == 0)
+ StartLazyBackgroundPage(profile, extension_id);
} else {
tasks_list = it->second.get();
}
@@ -81,6 +78,26 @@ void LazyBackgroundTaskQueue::AddPendingTask(
tasks_list->push_back(task);
}
+void LazyBackgroundTaskQueue::StartLazyBackgroundPage(
+ Profile* profile, const std::string& extension_id) {
+ ExtensionProcessManager* pm =
+ ExtensionSystem::Get(profile)->process_manager();
+ if (pm->IsBackgroundHostClosing(extension_id)) {
+ // When the background host finishes closing, we will reload it.
+ pending_page_loads_.insert(PendingTasksKey(profile, extension_id));
+ return;
+ }
+
+ const Extension* extension =
+ ExtensionSystem::Get(profile)->extension_service()->
+ extensions()->GetByID(extension_id);
+ DCHECK(extension->has_lazy_background_page());
+ pm->IncrementLazyKeepaliveCount(extension);
+ pm->CreateBackgroundHost(extension, extension->GetBackgroundURL());
+
+ pending_page_loads_.erase(PendingTasksKey(profile, extension_id));
+}
+
void LazyBackgroundTaskQueue::ProcessPendingTasks(
ExtensionHost* host,
Profile* profile,
@@ -130,15 +147,24 @@ void LazyBackgroundTaskQueue::Observe(
break;
}
case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: {
- // Notify consumers about the load failure when the background host dies.
- // This can happen if the extension crashes. This is not strictly
- // necessary, since we also unload the extension in that case (which
- // dispatches the tasks below), but is a good extra precaution.
Profile* profile = content::Source<Profile>(source).ptr();
ExtensionHost* host = content::Details<ExtensionHost>(details).ptr();
if (host->extension_host_type() ==
chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
- ProcessPendingTasks(NULL, profile, host->extension());
+ PendingTasksKey key(profile, host->extension()->id());
+ if (pending_page_loads_.count(key) > 0) {
+ // We were waiting for the background page to unload. We can start it
+ // up again and dispatch any queued events.
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ &LazyBackgroundTaskQueue::StartLazyBackgroundPage,
+ base::Unretained(this), profile, host->extension()->id()));
Yoyo Zhou 2012/04/19 21:47:13 If we might be receiving this notification near sh
Matt Perry 2012/04/19 22:21:53 Done.
+ } else {
+ // This may be a load failure (e.g. a crash). In that case, notify
+ // consumers about the load failure. This is not strictly necessary,
+ // since we also unload the extension in that case (which dispatches
+ // the tasks below), but is a good extra precaution.
+ ProcessPendingTasks(NULL, profile, host->extension());
+ }
}
break;
}

Powered by Google App Engine
This is Rietveld 408576698