summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/plugin_loader_posix.cc16
-rw-r--r--content/browser/plugin_loader_posix.h2
-rw-r--r--content/browser/plugin_loader_posix_unittest.cc37
-rw-r--r--content/browser/plugin_service.cc5
4 files changed, 52 insertions, 8 deletions
diff --git a/content/browser/plugin_loader_posix.cc b/content/browser/plugin_loader_posix.cc
index a1ccaac..14d7c02 100644
--- a/content/browser/plugin_loader_posix.cc
+++ b/content/browser/plugin_loader_posix.cc
@@ -46,6 +46,7 @@ void PluginLoaderPosix::OnProcessCrashed(int exit_code) {
canonical_list_.erase(canonical_list_.begin(),
canonical_list_.begin() + next_load_index_ + 1);
next_load_index_ = 0;
+
LoadPluginsInternal();
}
@@ -83,6 +84,11 @@ void PluginLoaderPosix::GetPluginsToLoad() {
void PluginLoaderPosix::LoadPluginsInternal() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Check if the list is empty or all plugins have already been loaded before
+ // forking.
+ if (MaybeRunPendingCallbacks())
+ return;
+
if (load_start_time_.is_null())
load_start_time_ = base::TimeTicks::Now();
@@ -107,7 +113,7 @@ void PluginLoaderPosix::OnPluginLoaded(const webkit::WebPluginInfo& plugin) {
++next_load_index_;
- RunPendingCallbacks();
+ MaybeRunPendingCallbacks();
}
void PluginLoaderPosix::OnPluginLoadFailed(const FilePath& plugin_path) {
@@ -120,7 +126,7 @@ void PluginLoaderPosix::OnPluginLoadFailed(const FilePath& plugin_path) {
++next_load_index_;
MaybeAddInternalPlugin(plugin_path);
- RunPendingCallbacks();
+ MaybeRunPendingCallbacks();
}
bool PluginLoaderPosix::MaybeAddInternalPlugin(const FilePath& plugin_path) {
@@ -137,9 +143,9 @@ bool PluginLoaderPosix::MaybeAddInternalPlugin(const FilePath& plugin_path) {
return false;
}
-void PluginLoaderPosix::RunPendingCallbacks() {
+bool PluginLoaderPosix::MaybeRunPendingCallbacks() {
if (next_load_index_ < canonical_list_.size())
- return;
+ return false;
PluginList::Singleton()->SetPlugins(loaded_plugins_);
for (std::vector<PendingCallback>::iterator it = callbacks_.begin();
@@ -154,6 +160,8 @@ void PluginLoaderPosix::RunPendingCallbacks() {
(base::TimeTicks::Now() - load_start_time_)
* base::Time::kMicrosecondsPerMillisecond);
load_start_time_ = base::TimeTicks();
+
+ return true;
}
PluginLoaderPosix::PendingCallback::PendingCallback(
diff --git a/content/browser/plugin_loader_posix.h b/content/browser/plugin_loader_posix.h
index 97fe8bb..0651450 100644
--- a/content/browser/plugin_loader_posix.h
+++ b/content/browser/plugin_loader_posix.h
@@ -87,7 +87,7 @@ class CONTENT_EXPORT PluginLoaderPosix : public UtilityProcessHost::Client,
// Runs all the registered callbacks on each's target loop if the condition
// for ending the load process is done (i.e. the |next_load_index_| is outside
// the ranage of the |canonical_list_|).
- void RunPendingCallbacks();
+ bool MaybeRunPendingCallbacks();
// The process host for which this is a client.
UtilityProcessHost* process_host_;
diff --git a/content/browser/plugin_loader_posix_unittest.cc b/content/browser/plugin_loader_posix_unittest.cc
index 5b83ae4..e1345ee 100644
--- a/content/browser/plugin_loader_posix_unittest.cc
+++ b/content/browser/plugin_loader_posix_unittest.cc
@@ -41,6 +41,10 @@ class MockPluginLoaderPosix : public PluginLoaderPosix {
return &internal_plugins_;
}
+ void RealLoadPluginsInternal() {
+ PluginLoaderPosix::LoadPluginsInternal();
+ }
+
void TestOnPluginLoaded(const webkit::WebPluginInfo& plugin) {
OnPluginLoaded(plugin);
}
@@ -279,3 +283,36 @@ TEST_F(PluginLoaderPosixTest, InternalPlugin) {
message_loop()->RunAllPending();
EXPECT_EQ(1, did_callback);
}
+
+TEST_F(PluginLoaderPosixTest, AllCrashed) {
+ int did_callback = 0;
+ PluginService::GetPluginsCallback callback =
+ base::Bind(&VerifyCallback, base::Unretained(&did_callback));
+
+ plugin_loader()->LoadPlugins(message_loop()->message_loop_proxy(), callback);
+
+ // Spin the loop so that the canonical list of plugins can be set.
+ EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(1);
+ message_loop()->RunAllPending();
+ AddThreePlugins();
+
+ EXPECT_EQ(0u, plugin_loader()->next_load_index());
+
+ // Mock the first two calls like normal.
+ testing::Expectation first =
+ EXPECT_CALL(*plugin_loader(), LoadPluginsInternal()).Times(2);
+ // On the last call, go through the default impl.
+ EXPECT_CALL(*plugin_loader(), LoadPluginsInternal())
+ .After(first)
+ .WillOnce(
+ testing::Invoke(plugin_loader(),
+ &MockPluginLoaderPosix::RealLoadPluginsInternal));
+ plugin_loader()->OnProcessCrashed(42);
+ plugin_loader()->OnProcessCrashed(42);
+ plugin_loader()->OnProcessCrashed(42);
+
+ message_loop()->RunAllPending();
+ EXPECT_EQ(1, did_callback);
+
+ EXPECT_EQ(0u, plugin_loader()->loaded_plugins().size());
+}
diff --git a/content/browser/plugin_service.cc b/content/browser/plugin_service.cc
index 13f52d3..7d2c811 100644
--- a/content/browser/plugin_service.cc
+++ b/content/browser/plugin_service.cc
@@ -67,8 +67,7 @@ static void GetPluginsForGroupsCallback(
// Callback set on the PluginList to assert that plugin loading happens on the
// correct thread.
void WillLoadPluginsCallback() {
- // TODO(rsesek): Change these to CHECKs.
-#if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX))
+#if defined(OS_WIN)
CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
#else
CHECK(false) << "Plugin loading should happen out-of-process.";
@@ -500,7 +499,7 @@ void PluginService::GetPlugins(const GetPluginsCallback& callback) {
scoped_refptr<base::MessageLoopProxy> target_loop(
MessageLoop::current()->message_loop_proxy());
-#if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX))
+#if defined(OS_WIN)
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
base::Bind(&PluginService::GetPluginsInternal, base::Unretained(this),
target_loop, callback));