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

Unified Diff: chrome/browser/plugin_data_remover.cc

Issue 6308001: When clearing plugin data at shutdown, wait for it to finish. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: whoops Created 9 years, 11 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/plugin_data_remover.cc
diff --git a/chrome/browser/plugin_data_remover.cc b/chrome/browser/plugin_data_remover.cc
index 4e6ac7f3c71bf5ca4a9ba8d6be6bad0c2e75bd59..1b2c6c31744bc41717c510b8e0956ecf92d27de7 100644
--- a/chrome/browser/plugin_data_remover.cc
+++ b/chrome/browser/plugin_data_remover.cc
@@ -7,6 +7,7 @@
#include "base/message_loop_proxy.h"
#include "base/metrics/histogram.h"
#include "base/version.h"
+#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/plugin_service.h"
#include "chrome/common/plugin_messages.h"
@@ -28,6 +29,9 @@ const uint64 kClearAllData = 0;
PluginDataRemover::PluginDataRemover()
: is_removing_(false),
+ has_browser_ref_(false),
+ plugin_process_(NULL),
+ handle_(base::kNullProcessHandle),
channel_(NULL) { }
PluginDataRemover::~PluginDataRemover() {
@@ -36,16 +40,22 @@ PluginDataRemover::~PluginDataRemover() {
BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_);
}
-void PluginDataRemover::StartRemoving(base::Time begin_time, Task* done_task) {
+void PluginDataRemover::StartRemoving(const base::Time& begin_time,
+ bool terminate,
+ Task* done_task) {
DCHECK(!done_task_.get());
DCHECK(!is_removing_);
remove_start_time_ = base::Time::Now();
begin_time_ = begin_time;
+ terminate_process_ = terminate;
message_loop_ = base::MessageLoopProxy::CreateForCurrentThread();
done_task_.reset(done_task);
is_removing_ = true;
+ // Don't quit the main message loop until the process has started.
+ g_browser_process->AddRefModule();
+ has_browser_ref_ = true;
AddRef();
PluginService::GetInstance()->OpenChannelToPlugin(
GURL(), kFlashMimeType, this);
@@ -57,6 +67,20 @@ void PluginDataRemover::StartRemoving(base::Time begin_time, Task* done_task) {
kRemovalTimeoutMs);
}
+void PluginDataRemover::WaitForPluginToExit() {
+ DCHECK(terminate_process_);
+ if (!is_removing_)
+ return;
+ DCHECK_NE(base::kNullProcessHandle, handle_);
+ base::Time start_time(base::Time::Now());
+ bool result = base::WaitForSingleProcess(handle_, kRemovalTimeoutMs);
+ UMA_HISTOGRAM_TIMES("ClearPluginData.wait_at_shutdown",
+ base::Time::Now() - start_time);
+ UMA_HISTOGRAM_TIMES("ClearPluginData.time_at_shutdown",
+ base::Time::Now() - remove_start_time_);
+ DCHECK(result) << "Error waiting for plugin process";
+}
+
int PluginDataRemover::ID() {
// Generate an ID for the browser process.
return ChildProcessInfo::GenerateChildProcessUniqueId();
@@ -70,11 +94,24 @@ void PluginDataRemover::SetPluginInfo(
const webkit::npapi::WebPluginInfo& info) {
}
+void PluginDataRemover::OnPluginProcessFound(PluginProcessHost* process) {
+ plugin_process_ = process;
+}
+
void PluginDataRemover::OnChannelOpened(const IPC::ChannelHandle& handle) {
ConnectToChannel(handle);
+ DCHECK(has_browser_ref_);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &PluginDataRemover::ReleaseBrowserProcess));
+ has_browser_ref_ = false;
Release();
}
+void PluginDataRemover::ReleaseBrowserProcess() {
+ g_browser_process->ReleaseModule();
+}
+
void PluginDataRemover::ConnectToChannel(const IPC::ChannelHandle& handle) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -85,7 +122,7 @@ void PluginDataRemover::ConnectToChannel(const IPC::ChannelHandle& handle) {
DCHECK(!channel_);
channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this);
if (!channel_->Connect()) {
- LOG(DFATAL) << "Couldn't connect to plugin";
+ NOTREACHED() << "Couldn't connect to plugin";
SignalDone();
return;
}
@@ -94,27 +131,51 @@ void PluginDataRemover::ConnectToChannel(const IPC::ChannelHandle& handle) {
new PluginMsg_ClearSiteData(std::string(),
kClearAllData,
begin_time_))) {
- LOG(DFATAL) << "Couldn't send ClearSiteData message";
+ NOTREACHED() << "Couldn't send ClearSiteData message";
SignalDone();
+ return;
+ }
+
+ // Save the process handle so we can wait for the process to exit.
+ handle_ = plugin_process_->handle();
+ if (terminate_process_) {
+ plugin_process_->ForceShutdown();
}
}
void PluginDataRemover::OnError() {
- NOTREACHED() << "Couldn't open plugin channel";
+ LOG(DFATAL) << "Couldn't open plugin channel";
SignalDone();
+ if (has_browser_ref_) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &PluginDataRemover::ReleaseBrowserProcess));
+ has_browser_ref_ = false;
+ }
Release();
}
void PluginDataRemover::OnClearSiteDataResult(bool success) {
- if (!success)
- LOG(DFATAL) << "ClearSiteData returned error";
+ LOG_IF(DFATAL, !success) << "ClearSiteData returned error";
UMA_HISTOGRAM_TIMES("ClearPluginData.time",
base::Time::Now() - remove_start_time_);
SignalDone();
}
+void PluginDataRemover::OnPluginShuttingDown() {
+ VLOG(1) << "Plugin shutting down";
+}
+
void PluginDataRemover::OnTimeout() {
- NOTREACHED() << "Timed out";
+ if (is_removing_) {
+ LOG(DFATAL) << "Timed out";
+ if (has_browser_ref_) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &PluginDataRemover::ReleaseBrowserProcess));
+ has_browser_ref_ = false;
+ }
+ }
SignalDone();
}
@@ -122,6 +183,8 @@ bool PluginDataRemover::OnMessageReceived(const IPC::Message& msg) {
IPC_BEGIN_MESSAGE_MAP(PluginDataRemover, msg)
IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult,
OnClearSiteDataResult)
+ IPC_MESSAGE_HANDLER(PluginHostMsg_PluginShuttingDown,
+ OnPluginShuttingDown)
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
@@ -129,8 +192,10 @@ bool PluginDataRemover::OnMessageReceived(const IPC::Message& msg) {
}
void PluginDataRemover::OnChannelError() {
- LOG(DFATAL) << "Channel error";
- SignalDone();
+ if (is_removing_) {
+ NOTREACHED() << "Channel error";
+ SignalDone();
+ }
}
void PluginDataRemover::SignalDone() {

Powered by Google App Engine
This is Rietveld 408576698