Index: content/browser/renderer_host/pepper/pepper_file_message_filter.cc |
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 5de7fbf19fcda606694d66f38d7f78e7f1cf80e5..e07bb990a01974cab3aa72a76a4b58b9386e0b33 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; |