summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/renderer_host/pepper/pepper_file_message_filter.cc51
-rw-r--r--content/browser/renderer_host/pepper/pepper_file_message_filter.h2
-rw-r--r--content/browser/web_contents/web_contents_impl.cc17
3 files changed, 69 insertions, 1 deletions
diff --git a/content/browser/renderer_host/pepper/pepper_file_message_filter.cc b/content/browser/renderer_host/pepper/pepper_file_message_filter.cc
index 5de7fbf..e07bb99 100644
--- a/content/browser/renderer_host/pepper/pepper_file_message_filter.cc
+++ b/content/browser/renderer_host/pepper/pepper_file_message_filter.cc
@@ -8,8 +8,10 @@
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
+#include "base/metrics/field_trial.h"
#include "base/platform_file.h"
#include "base/process_util.h"
+#include "base/threading/sequenced_worker_pool.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/public/browser/browser_thread.h"
@@ -60,20 +62,67 @@ IPC::PlatformFileForTransit PlatformFileToPlatformFileForTransit(
return file;
}
+// Run a field trial comparing the effect of the FILE thread versus
+// blocking worker pool on hung-plugin reports.
+// TODO(shess): Remove once the workpool is proven superior.
+// http://crbug.com/153383
+const char* const kIOFieldTrialName = "FlapperIOThread";
+const char* const kPoolGroupName = "PoolThread";
+const char* const kFileGroupName = "FileThread";
+
+bool g_use_file_thread = true;
+
+void ActivateThreadFieldTrial() {
+ static bool activated = false;
+ if (activated)
+ return;
+
+ activated = true;
+
+ // The field trial will expire on Jan 1st, 2014.
+ scoped_refptr<base::FieldTrial> trial(
+ base::FieldTrialList::FactoryGetFieldTrial(
+ kIOFieldTrialName, 1000, kPoolGroupName, 2014, 1, 1, NULL));
+
+ // 50% goes into the FILE thread group.
+ trial->AppendGroup(kFileGroupName, 500);
+
+ g_use_file_thread = (trial->group_name() == kFileGroupName);
+}
+
} // namespace
PepperFileMessageFilter::PepperFileMessageFilter(int child_id)
: child_id_(child_id),
channel_(NULL) {
+ ActivateThreadFieldTrial();
}
void PepperFileMessageFilter::OverrideThreadForMessage(
const IPC::Message& message,
BrowserThread::ID* thread) {
- if (IPC_MESSAGE_CLASS(message) == PepperFileMsgStart)
+ if (IPC_MESSAGE_CLASS(message) == PepperFileMsgStart && g_use_file_thread)
*thread = BrowserThread::FILE;
}
+base::TaskRunner* PepperFileMessageFilter::OverrideTaskRunnerForMessage(
+ const IPC::Message& message) {
+ // The blocking pool provides a pool of threads to run file
+ // operations, instead of a single thread which might require
+ // queuing time. Since these messages are synchronous as sent from
+ // the plugin, the sending thread cannot send a new message until
+ // this one returns, so there is no need to sequence tasks here. If
+ // the plugin has multiple threads, it cannot make assumptions about
+ // ordering of IPC message sends, so it cannot make assumptions
+ // about ordering of operations caused by those IPC messages.
+ if (IPC_MESSAGE_CLASS(message) == PepperFileMsgStart) {
+ // Should never get here if using the FILE thread.
+ DCHECK(!g_use_file_thread);
+ return BrowserThread::GetBlockingPool();
+ }
+ return NULL;
+}
+
bool PepperFileMessageFilter::OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) {
bool handled = true;
diff --git a/content/browser/renderer_host/pepper/pepper_file_message_filter.h b/content/browser/renderer_host/pepper/pepper_file_message_filter.h
index c5065f1..074d655 100644
--- a/content/browser/renderer_host/pepper/pepper_file_message_filter.h
+++ b/content/browser/renderer_host/pepper/pepper_file_message_filter.h
@@ -36,6 +36,8 @@ class PepperFileMessageFilter : public content::BrowserMessageFilter {
virtual void OverrideThreadForMessage(
const IPC::Message& message,
content::BrowserThread::ID* thread) OVERRIDE;
+ virtual base::TaskRunner* OverrideTaskRunnerForMessage(
+ const IPC::Message& message) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) OVERRIDE;
virtual void OnDestruct() const OVERRIDE;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 4e94230..089d1f9 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/command_line.h"
+#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/metrics/stats_counters.h"
#include "base/string16.h"
@@ -2339,6 +2340,22 @@ void WebContentsImpl::OnSetSelectedColorInColorChooser(int color_chooser_id,
void WebContentsImpl::OnPepperPluginHung(int plugin_child_id,
const FilePath& path,
bool is_hung) {
+ HISTOGRAM_COUNTS("Pepper.PluginHung", 1);
+
+ // Determine how often hangs happen when using worker pool versus
+ // FILE thread. kFieldTrialName needs to match the value in
+ // pepper_file_message_filter.cc, but plumbing that through would be
+ // disruptive for temporary code.
+ // TODO(shess): Remove once the workpool is proven superior.
+ // http://crbug.com/153383
+ static const char* const kFieldTrialName = "FlapperIOThread";
+ static const bool hung_trial_exists =
+ base::FieldTrialList::TrialExists(kFieldTrialName);
+ if (hung_trial_exists) {
+ HISTOGRAM_COUNTS(base::FieldTrial::MakeName("Pepper.PluginHung",
+ kFieldTrialName), 1);
+ }
+
FOR_EACH_OBSERVER(WebContentsObserver, observers_,
PluginHungStatusChanged(plugin_child_id, path, is_hung));
}