mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Don't deadlock on a child process for a CPOW (bug 905896, r=cjones).
This commit is contained in:
parent
30e7a9848d
commit
130cd7e1ac
@ -939,6 +939,10 @@ ContentParent::OnChannelConnected(int32_t pid)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set a reply timeout. The only time the parent process will actually
|
||||
// timeout is through urgent messages (which are used by CPOWs).
|
||||
SetReplyTimeoutMs(Preferences::GetInt("dom.ipc.cpow.timeout", 3000));
|
||||
}
|
||||
|
||||
void
|
||||
@ -2797,5 +2801,14 @@ ContentParent::RecvKeywordToURI(const nsCString& aKeyword, OptionalInputStreamPa
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::ShouldContinueFromReplyTimeout()
|
||||
{
|
||||
// The only time ContentParent sends blocking messages is for CPOWs, so
|
||||
// timeouts should only ever occur in electrolysis-enabled sessions.
|
||||
MOZ_ASSERT(Preferences::GetBool("browser.tabs.remote", false));
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -180,6 +180,8 @@ protected:
|
||||
void OnChannelConnected(int32_t pid) MOZ_OVERRIDE;
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
|
||||
bool ShouldContinueFromReplyTimeout() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
static nsDataHashtable<nsStringHashKey, ContentParent*> *sAppContentParents;
|
||||
static nsTArray<ContentParent*>* sNonAppContentParents;
|
||||
|
@ -322,6 +322,15 @@ SyncChannel::ShouldContinueFromTimeout()
|
||||
cont = static_cast<SyncListener*>(mListener.get())->OnReplyTimeout();
|
||||
}
|
||||
|
||||
static enum { UNKNOWN, NOT_DEBUGGING, DEBUGGING } sDebuggingChildren = UNKNOWN;
|
||||
|
||||
if (sDebuggingChildren == UNKNOWN) {
|
||||
sDebuggingChildren = getenv("MOZ_DEBUG_CHILD_PROCESS") ? DEBUGGING : NOT_DEBUGGING;
|
||||
}
|
||||
if (sDebuggingChildren == DEBUGGING) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!cont) {
|
||||
// NB: there's a sublety here. If parents were allowed to
|
||||
// send sync messages to children, then it would be possible
|
||||
|
@ -1,6 +1,8 @@
|
||||
include protocol PTestDataStructuresSub;
|
||||
include PTestDataStructuresCommon;
|
||||
|
||||
include "mozilla/GfxMessageUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
|
@ -9,12 +9,14 @@ parent:
|
||||
sync Test3() returns (uint32_t result);
|
||||
sync Test4_Begin();
|
||||
sync Test4_NestedSync();
|
||||
sync FinalTest_Begin();
|
||||
|
||||
child:
|
||||
async Start();
|
||||
urgent Reply1() returns (uint32_t result);
|
||||
urgent Reply2() returns (uint32_t result);
|
||||
urgent Test4_Reenter();
|
||||
urgent FinalTest_Hang();
|
||||
};
|
||||
|
||||
} // namespace _ipdltest
|
||||
|
@ -3,6 +3,13 @@
|
||||
#include "IPDLUnitTests.h" // fail etc.
|
||||
#include <unistd.h>
|
||||
|
||||
template<>
|
||||
struct RunnableMethodTraits<mozilla::_ipdltest::TestUrgencyParent>
|
||||
{
|
||||
static void RetainCallee(mozilla::_ipdltest::TestUrgencyParent* obj) { }
|
||||
static void ReleaseCallee(mozilla::_ipdltest::TestUrgencyParent* obj) { }
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
@ -74,6 +81,21 @@ TestUrgencyParent::RecvTest4_NestedSync()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TestUrgencyParent::RecvFinalTest_Begin()
|
||||
{
|
||||
SetReplyTimeoutMs(2000);
|
||||
if (CallFinalTest_Hang())
|
||||
fail("should have failed due to timeout");
|
||||
if (!GetIPCChannel()->Unsound_IsClosed())
|
||||
fail("channel should have closed");
|
||||
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(this, &TestUrgencyParent::Close));
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// child
|
||||
|
||||
@ -115,6 +137,10 @@ TestUrgencyChild::RecvStart()
|
||||
if (!SendTest4_Begin())
|
||||
fail("calling SendTest4_Begin");
|
||||
|
||||
// This must be the last test, since the child process may die.
|
||||
if (SendFinalTest_Begin())
|
||||
fail("Final test should not have succeeded");
|
||||
|
||||
Close();
|
||||
|
||||
return true;
|
||||
@ -153,6 +179,13 @@ TestUrgencyChild::AnswerTest4_Reenter()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestUrgencyChild::AnswerFinalTest_Hang()
|
||||
{
|
||||
sleep(10);
|
||||
return true;
|
||||
}
|
||||
|
||||
TestUrgencyChild::TestUrgencyChild()
|
||||
: test_(0)
|
||||
{
|
||||
|
@ -27,14 +27,20 @@ public:
|
||||
bool RecvTest3(uint32_t *value);
|
||||
bool RecvTest4_Begin();
|
||||
bool RecvTest4_NestedSync();
|
||||
bool RecvFinalTest_Begin();
|
||||
|
||||
bool ShouldContinueFromReplyTimeout() MOZ_OVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
if (AbnormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
passed("ok");
|
||||
QuitParent();
|
||||
}
|
||||
|
||||
private:
|
||||
bool inreply_;
|
||||
};
|
||||
@ -51,10 +57,11 @@ public:
|
||||
bool AnswerReply1(uint32_t *reply);
|
||||
bool AnswerReply2(uint32_t *reply);
|
||||
bool AnswerTest4_Reenter();
|
||||
bool AnswerFinalTest_Hang();
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
if (AbnormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
QuitChild();
|
||||
}
|
||||
|
@ -594,7 +594,7 @@ JavaScriptParent::unwrap(JSContext *cx, ObjectId objId)
|
||||
bool
|
||||
JavaScriptParent::ipcfail(JSContext *cx)
|
||||
{
|
||||
JS_ReportError(cx, "catastrophic IPC failure");
|
||||
JS_ReportError(cx, "child process crashed or timedout");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user