зеркало из https://github.com/mozilla/gecko-dev.git
228 строки
4.9 KiB
C++
228 строки
4.9 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: sw=4 ts=4 et :
|
|
*/
|
|
#include "TestUrgentHangs.h"
|
|
|
|
#include "IPDLUnitTests.h" // fail etc.
|
|
#include "prthread.h"
|
|
#if defined(OS_POSIX)
|
|
#include <unistd.h>
|
|
#else
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
template<>
|
|
struct RunnableMethodTraits<mozilla::_ipdltest::TestUrgentHangsParent>
|
|
{
|
|
static void RetainCallee(mozilla::_ipdltest::TestUrgentHangsParent* obj) { }
|
|
static void ReleaseCallee(mozilla::_ipdltest::TestUrgentHangsParent* obj) { }
|
|
};
|
|
|
|
namespace mozilla {
|
|
namespace _ipdltest {
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// parent
|
|
|
|
TestUrgentHangsParent::TestUrgentHangsParent()
|
|
: mInnerCount(0),
|
|
mInnerUrgentCount(0)
|
|
{
|
|
MOZ_COUNT_CTOR(TestUrgentHangsParent);
|
|
}
|
|
|
|
TestUrgentHangsParent::~TestUrgentHangsParent()
|
|
{
|
|
MOZ_COUNT_DTOR(TestUrgentHangsParent);
|
|
}
|
|
|
|
void
|
|
TestUrgentHangsParent::Main()
|
|
{
|
|
SetReplyTimeoutMs(1000);
|
|
|
|
// Should succeed despite the nested sleep call because the content process
|
|
// responded to the transaction.
|
|
if (!SendTest1_1())
|
|
fail("sending Test1_1");
|
|
|
|
// Fails with a timeout.
|
|
if (SendTest2())
|
|
fail("sending Test2");
|
|
|
|
// Also fails since we haven't gotten a response for Test2 yet.
|
|
if (SendTest3())
|
|
fail("sending Test3");
|
|
|
|
// Do a second round of testing once the reply to Test2 comes back.
|
|
MessageLoop::current()->PostDelayedTask(
|
|
FROM_HERE,
|
|
NewRunnableMethod(this, &TestUrgentHangsParent::SecondStage),
|
|
3000);
|
|
}
|
|
|
|
void
|
|
TestUrgentHangsParent::SecondStage()
|
|
{
|
|
// Send an async message that waits 2 seconds and then sends a sync message
|
|
// (which should be processed).
|
|
if (!SendTest4())
|
|
fail("sending Test4");
|
|
|
|
// Send a sync message that will time out because the child is waiting
|
|
// inside RecvTest4.
|
|
if (SendTest4_1())
|
|
fail("sending Test4_1");
|
|
|
|
MessageLoop::current()->PostDelayedTask(
|
|
FROM_HERE,
|
|
NewRunnableMethod(this, &TestUrgentHangsParent::ThirdStage),
|
|
3000);
|
|
}
|
|
|
|
void
|
|
TestUrgentHangsParent::ThirdStage()
|
|
{
|
|
// The third stage does the same thing as the second stage except that the
|
|
// child sends an urgent message to us. In this case, we actually answer
|
|
// that message unconditionally.
|
|
|
|
// Send an async message that waits 2 seconds and then sends a sync message
|
|
// (which should be processed).
|
|
if (!SendTest5())
|
|
fail("sending Test5");
|
|
|
|
// Send a sync message that will time out because the child is waiting
|
|
// inside RecvTest5.
|
|
if (SendTest5_1())
|
|
fail("sending Test5_1");
|
|
|
|
// Close the channel after the child finishes its work in RecvTest5.
|
|
MessageLoop::current()->PostDelayedTask(
|
|
FROM_HERE,
|
|
NewRunnableMethod(this, &TestUrgentHangsParent::Close),
|
|
3000);
|
|
}
|
|
|
|
bool
|
|
TestUrgentHangsParent::RecvTest1_2()
|
|
{
|
|
if (!SendTest1_3())
|
|
fail("sending Test1_3");
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
TestUrgentHangsParent::RecvTestInner()
|
|
{
|
|
mInnerCount++;
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
TestUrgentHangsParent::RecvTestInnerUrgent()
|
|
{
|
|
mInnerUrgentCount++;
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// child
|
|
|
|
bool
|
|
TestUrgentHangsChild::RecvTest1_1()
|
|
{
|
|
if (!SendTest1_2())
|
|
fail("sending Test1_2");
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
TestUrgentHangsChild::RecvTest1_3()
|
|
{
|
|
PR_Sleep(PR_SecondsToInterval(2));
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
TestUrgentHangsChild::RecvTest2()
|
|
{
|
|
PR_Sleep(PR_SecondsToInterval(2));
|
|
|
|
// Should fail because of the timeout.
|
|
if (SendTestInner())
|
|
fail("sending TestInner");
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
TestUrgentHangsChild::RecvTest3()
|
|
{
|
|
fail("RecvTest3 should never be called");
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
TestUrgentHangsChild::RecvTest4()
|
|
{
|
|
PR_Sleep(PR_SecondsToInterval(2));
|
|
|
|
// This won't fail because we should handle Test4_1 here before actually
|
|
// sending TestInner to the parent.
|
|
if (!SendTestInner())
|
|
fail("sending TestInner");
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
TestUrgentHangsChild::RecvTest4_1()
|
|
{
|
|
// This should fail because Test4_1 timed out and hasn't gotten a response
|
|
// yet.
|
|
if (SendTestInner())
|
|
fail("sending TestInner");
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
TestUrgentHangsChild::RecvTest5()
|
|
{
|
|
PR_Sleep(PR_SecondsToInterval(2));
|
|
|
|
// This message will actually be handled by the parent even though it's in
|
|
// the timeout state.
|
|
if (!SendTestInnerUrgent())
|
|
fail("sending TestInner");
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
TestUrgentHangsChild::RecvTest5_1()
|
|
{
|
|
// This message will actually be handled by the parent even though it's in
|
|
// the timeout state.
|
|
if (!SendTestInnerUrgent())
|
|
fail("sending TestInner");
|
|
|
|
return true;
|
|
}
|
|
|
|
TestUrgentHangsChild::TestUrgentHangsChild()
|
|
{
|
|
MOZ_COUNT_CTOR(TestUrgentHangsChild);
|
|
}
|
|
|
|
TestUrgentHangsChild::~TestUrgentHangsChild()
|
|
{
|
|
MOZ_COUNT_DTOR(TestUrgentHangsChild);
|
|
}
|
|
|
|
} // namespace _ipdltest
|
|
} // namespace mozilla
|