diff options
Diffstat (limited to 'ipc/ipdl/test/cxx/TestUrgentHangs.cpp')
-rw-r--r-- | ipc/ipdl/test/cxx/TestUrgentHangs.cpp | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/ipc/ipdl/test/cxx/TestUrgentHangs.cpp b/ipc/ipdl/test/cxx/TestUrgentHangs.cpp new file mode 100644 index 0000000000..e6139e38c5 --- /dev/null +++ b/ipc/ipdl/test/cxx/TestUrgentHangs.cpp @@ -0,0 +1,174 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: sw=2 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 + +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( + NewNonOwningRunnableMethod( + "_ipdltest::TestUrgentHangsParent::SecondStage", 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( + NewNonOwningRunnableMethod("_ipdltest::TestUrgentHangsParent::ThirdStage", + 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( + NewNonOwningRunnableMethod("ipc::IToplevelProtocol::Close", this, + &TestUrgentHangsParent::Close), + 3000); +} + +mozilla::ipc::IPCResult TestUrgentHangsParent::RecvTest1_2() { + if (!SendTest1_3()) fail("sending Test1_3"); + return IPC_OK(); +} + +mozilla::ipc::IPCResult TestUrgentHangsParent::RecvTestInner() { + mInnerCount++; + return IPC_OK(); +} + +mozilla::ipc::IPCResult TestUrgentHangsParent::RecvTestInnerUrgent() { + mInnerUrgentCount++; + return IPC_OK(); +} + +//----------------------------------------------------------------------------- +// child + +mozilla::ipc::IPCResult TestUrgentHangsChild::RecvTest1_1() { + if (!SendTest1_2()) fail("sending Test1_2"); + + return IPC_OK(); +} + +mozilla::ipc::IPCResult TestUrgentHangsChild::RecvTest1_3() { + PR_Sleep(PR_SecondsToInterval(2)); + + return IPC_OK(); +} + +mozilla::ipc::IPCResult TestUrgentHangsChild::RecvTest2() { + PR_Sleep(PR_SecondsToInterval(2)); + + // Should fail because of the timeout. + if (SendTestInner()) fail("sending TestInner"); + + return IPC_OK(); +} + +mozilla::ipc::IPCResult TestUrgentHangsChild::RecvTest3() { + fail("RecvTest3 should never be called"); + return IPC_OK(); +} + +mozilla::ipc::IPCResult 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 IPC_OK(); +} + +mozilla::ipc::IPCResult TestUrgentHangsChild::RecvTest4_1() { + // This should fail because Test4_1 timed out and hasn't gotten a response + // yet. + if (SendTestInner()) fail("sending TestInner"); + + return IPC_OK(); +} + +mozilla::ipc::IPCResult 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 IPC_OK(); +} + +mozilla::ipc::IPCResult 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 IPC_OK(); +} + +TestUrgentHangsChild::TestUrgentHangsChild() { + MOZ_COUNT_CTOR(TestUrgentHangsChild); +} + +TestUrgentHangsChild::~TestUrgentHangsChild() { + MOZ_COUNT_DTOR(TestUrgentHangsChild); +} + +} // namespace _ipdltest +} // namespace mozilla |