Bug 677711 - Kill plugin processes when the child detects the browser is hung. r=bsmedberg

This commit is contained in:
Jim Mathies 2011-08-16 05:25:34 -05:00
Родитель 7f0b8bcc42
Коммит 140b1c3ff8
5 изменённых файлов: 52 добавлений и 12 удалений

Просмотреть файл

@ -112,6 +112,8 @@ child:
nsString aDisplayName,
nsString aIconPath);
async SetParentHangTimeout(uint32_t seconds);
parent:
/**
* This message is only used on X11 platforms.

Просмотреть файл

@ -44,6 +44,7 @@
#endif
#include "mozilla/plugins/PluginModuleChild.h"
#include "mozilla/ipc/SyncChannel.h"
#ifdef MOZ_WIDGET_GTK2
#include <gtk/gtk.h>
@ -513,6 +514,24 @@ PluginModuleChild::ExitedCxxStack()
#endif
bool
PluginModuleChild::RecvSetParentHangTimeout(const uint32_t& aSeconds)
{
#ifdef XP_WIN
SetReplyTimeoutMs(((aSeconds > 0) ? (1000 * aSeconds) : 0));
#endif
return true;
}
bool
PluginModuleChild::ShouldContinueFromReplyTimeout()
{
#ifdef XP_WIN
NS_RUNTIMEABORT("terminating child process");
#endif
return true;
}
bool
PluginModuleChild::InitGraphics()
{

Просмотреть файл

@ -111,6 +111,9 @@ protected:
return MediateRace(parent, child);
}
NS_OVERRIDE
virtual bool ShouldContinueFromReplyTimeout();
// Implement the PPluginModuleChild interface
virtual bool AnswerNP_GetEntryPoints(NPError* rv);
virtual bool AnswerNP_Initialize(NativeThreadId* tid, NPError* rv);
@ -168,6 +171,9 @@ protected:
const nsString& aDisplayName,
const nsString& aIconPath);
virtual bool
RecvSetParentHangTimeout(const uint32_t& aSeconds);
virtual void
ActorDestroy(ActorDestroyReason why);

Просмотреть файл

@ -79,7 +79,8 @@ using namespace mozilla;
using namespace mozilla::plugins;
using namespace mozilla::plugins::parent;
static const char kTimeoutPref[] = "dom.ipc.plugins.timeoutSecs";
static const char kChildTimeoutPref[] = "dom.ipc.plugins.timeoutSecs";
static const char kParentTimeoutPref[] = "dom.ipc.plugins.parentTimeoutSecs";
static const char kLaunchTimeoutPref[] = "dom.ipc.plugins.processLaunchTimeoutSecs";
template<>
@ -109,7 +110,7 @@ PluginModuleParent::LoadModule(const char* aFilePath)
parent->Open(parent->mSubprocess->GetChannel(),
parent->mSubprocess->GetChildProcessHandle());
TimeoutChanged(kTimeoutPref, parent);
TimeoutChanged(kChildTimeoutPref, parent);
return parent.forget();
}
@ -131,7 +132,8 @@ PluginModuleParent::PluginModuleParent(const char* aFilePath)
NS_ERROR("Out of memory");
}
Preferences::RegisterCallback(TimeoutChanged, kTimeoutPref, this);
Preferences::RegisterCallback(TimeoutChanged, kChildTimeoutPref, this);
Preferences::RegisterCallback(TimeoutChanged, kParentTimeoutPref, this);
}
PluginModuleParent::~PluginModuleParent()
@ -156,7 +158,8 @@ PluginModuleParent::~PluginModuleParent()
mSubprocess = nsnull;
}
Preferences::UnregisterCallback(TimeoutChanged, kTimeoutPref, this);
Preferences::UnregisterCallback(TimeoutChanged, kChildTimeoutPref, this);
Preferences::UnregisterCallback(TimeoutChanged, kParentTimeoutPref, this);
}
#ifdef MOZ_CRASHREPORTER
@ -226,14 +229,17 @@ int
PluginModuleParent::TimeoutChanged(const char* aPref, void* aModule)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thead!");
NS_ABORT_IF_FALSE(!strcmp(aPref, kTimeoutPref),
"unexpected pref callback");
PRInt32 timeoutSecs = Preferences::GetInt(kTimeoutPref, 0);
int32 timeoutMs = (timeoutSecs > 0) ? (1000 * timeoutSecs) :
SyncChannel::kNoTimeout;
static_cast<PluginModuleParent*>(aModule)->SetReplyTimeoutMs(timeoutMs);
if (!strcmp(aPref, kChildTimeoutPref)) {
// The timeout value used by the parent for children
PRInt32 timeoutSecs = Preferences::GetInt(kChildTimeoutPref, 0);
int32 timeoutMs = (timeoutSecs > 0) ? (1000 * timeoutSecs) :
SyncChannel::kNoTimeout;
static_cast<PluginModuleParent*>(aModule)->SetReplyTimeoutMs(timeoutMs);
} else if (!strcmp(aPref, kParentTimeoutPref)) {
// The timeout value used by the child for its parent
PRInt32 timeoutSecs = Preferences::GetInt(kParentTimeoutPref, 0);
static_cast<PluginModuleParent*>(aModule)->SendSetParentHangTimeout(timeoutSecs);
}
return 0;
}
@ -921,6 +927,8 @@ PluginModuleParent::NPP_New(NPMIMEType pluginType, NPP instance,
return NS_ERROR_FAILURE;
}
TimeoutChanged(kParentTimeoutPref, this);
return NS_OK;
}

Просмотреть файл

@ -1453,6 +1453,10 @@ pref("dom.max_script_run_time", 10);
// How long a plugin is allowed to process a synchronous IPC message
// before we consider it "hung".
pref("dom.ipc.plugins.timeoutSecs", 45);
// How long a plugin process will wait for a response from the parent
// to a synchronous request before terminating itself. After this
// point the child assumes the parent is hung.
pref("dom.ipc.plugins.parentTimeoutSecs", 15);
// How long a plugin launch is allowed to take before
// we consider it failed.
pref("dom.ipc.plugins.processLaunchTimeoutSecs", 45);
@ -1460,6 +1464,7 @@ pref("dom.ipc.plugins.processLaunchTimeoutSecs", 45);
// No timeout in DEBUG builds
pref("dom.ipc.plugins.timeoutSecs", 0);
pref("dom.ipc.plugins.processLaunchTimeoutSecs", 0);
pref("dom.ipc.plugins.parentTimeoutSecs", 0);
#endif
// Disable oopp for standard java. They run their own process isolation (which