Bug 1170231 - Part 2: Regression test for IPC race mediation deadlock. r=dvander, a=lmandel
authorAaron Klotz <aklotz@mozilla.com>
Sun, 07 Jun 2015 22:08:56 -0600
changeset 275372 75e056cdd421db46c419d59a2b73af3eb2876fce
parent 275371 ddc45855ad74539d7d5681bcaaf73fce3bce9b3b
child 275373 dc78e255ac9b2557121382afee8d1591f483e4c5
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander, lmandel
bugs1170231
milestone40.0
Bug 1170231 - Part 2: Regression test for IPC race mediation deadlock. r=dvander, a=lmandel
ipc/ipdl/test/cxx/PTestRaceDeadlock.ipdl
ipc/ipdl/test/cxx/TestRaceDeadlock.cpp
ipc/ipdl/test/cxx/TestRaceDeadlock.h
ipc/ipdl/test/cxx/moz.build
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/PTestRaceDeadlock.ipdl
@@ -0,0 +1,20 @@
+namespace mozilla {
+namespace _ipdltest {
+
+intr protocol PTestRaceDeadlock {
+both:
+    async StartRace();
+
+parent:
+    intr Lose();
+
+child:
+    intr Win();
+    intr Rpc();
+    async __delete__();
+
+/* Tests that race resolution does not cause deadlocks */
+};
+
+} // namespace _ipdltest
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/TestRaceDeadlock.cpp
@@ -0,0 +1,130 @@
+#include "TestRaceDeadlock.h"
+
+#include "IPDLUnitTests.h"      // fail etc.
+
+// #define TEST_TIMEOUT 5000
+
+using namespace mozilla::ipc;
+typedef mozilla::ipc::MessageChannel::Message Message;
+
+namespace mozilla {
+namespace _ipdltest {
+
+static RacyInterruptPolicy
+MediateRace(const Message& parent, const Message& child)
+{
+    return (PTestRaceDeadlock::Msg_Win__ID == parent.type()) ?
+        RIPParentWins : RIPChildWins;
+}
+
+//-----------------------------------------------------------------------------
+// parent
+
+TestRaceDeadlockParent::TestRaceDeadlockParent()
+{
+    MOZ_COUNT_CTOR(TestRaceDeadlockParent);
+}
+
+TestRaceDeadlockParent::~TestRaceDeadlockParent()
+{
+    MOZ_COUNT_DTOR(TestRaceDeadlockParent);
+}
+
+void
+TestRaceDeadlockParent::Main()
+{
+    Test1();
+
+    Close();
+}
+
+bool
+TestRaceDeadlockParent::ShouldContinueFromReplyTimeout()
+{
+    fail("This test should not hang");
+    GetIPCChannel()->CloseWithTimeout();
+    return false;
+}
+
+void
+TestRaceDeadlockParent::Test1()
+{
+#if defined(TEST_TIMEOUT)
+    SetReplyTimeoutMs(TEST_TIMEOUT);
+#endif
+    if (!SendStartRace()) {
+        fail("sending StartRace");
+    }
+    if (!CallRpc()) {
+        fail("calling Rpc");
+    }
+}
+
+bool
+TestRaceDeadlockParent::AnswerLose()
+{
+    return true;
+}
+
+RacyInterruptPolicy
+TestRaceDeadlockParent::MediateInterruptRace(const Message& parent,
+                                       const Message& child)
+{
+    return MediateRace(parent, child);
+}
+
+//-----------------------------------------------------------------------------
+// child
+
+TestRaceDeadlockChild::TestRaceDeadlockChild()
+{
+    MOZ_COUNT_CTOR(TestRaceDeadlockChild);
+}
+
+TestRaceDeadlockChild::~TestRaceDeadlockChild()
+{
+    MOZ_COUNT_DTOR(TestRaceDeadlockChild);
+}
+
+bool
+TestRaceDeadlockParent::RecvStartRace()
+{
+    if (!CallWin()) {
+        fail("calling Win");
+    }
+    return true;
+}
+
+bool
+TestRaceDeadlockChild::RecvStartRace()
+{
+    if (!SendStartRace()) {
+        fail("calling SendStartRace");
+    }
+    if (!CallLose()) {
+        fail("calling Lose");
+    }
+    return true;
+}
+
+bool
+TestRaceDeadlockChild::AnswerWin()
+{
+    return true;
+}
+
+bool
+TestRaceDeadlockChild::AnswerRpc()
+{
+    return true;
+}
+
+RacyInterruptPolicy
+TestRaceDeadlockChild::MediateInterruptRace(const Message& parent,
+                                      const Message& child)
+{
+    return MediateRace(parent, child);
+}
+
+} // namespace _ipdltest
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/TestRaceDeadlock.h
@@ -0,0 +1,75 @@
+#ifndef mozilla__ipdltest_TestRaceDeadlock_h
+#define mozilla__ipdltest_TestRaceDeadlock_h 1
+
+#include "mozilla/_ipdltest/IPDLUnitTests.h"
+
+#include "mozilla/_ipdltest/PTestRaceDeadlockParent.h"
+#include "mozilla/_ipdltest/PTestRaceDeadlockChild.h"
+
+namespace mozilla {
+namespace _ipdltest {
+
+class TestRaceDeadlockParent :
+    public PTestRaceDeadlockParent
+{
+public:
+    TestRaceDeadlockParent();
+    virtual ~TestRaceDeadlockParent();
+
+    static bool RunTestInProcesses() { return true; }
+    static bool RunTestInThreads() { return true; }
+
+    void Main();
+
+protected:
+    virtual bool ShouldContinueFromReplyTimeout() override;
+
+    void Test1();
+
+    virtual bool RecvStartRace() override;
+    virtual bool AnswerLose() override;
+
+    virtual mozilla::ipc::RacyInterruptPolicy
+    MediateInterruptRace(const Message& parent, const Message& child) override;
+
+    virtual void ActorDestroy(ActorDestroyReason why) override
+    {
+        if (NormalShutdown != why)
+            fail("unexpected destruction!");
+        passed("ok");
+        QuitParent();
+    }
+};
+
+
+class TestRaceDeadlockChild :
+    public PTestRaceDeadlockChild
+{
+public:
+    TestRaceDeadlockChild();
+    virtual ~TestRaceDeadlockChild();
+
+protected:
+    virtual bool RecvStartRace() override;
+
+    virtual bool AnswerWin() override;
+
+    virtual bool AnswerRpc() override;
+
+    virtual mozilla::ipc::RacyInterruptPolicy
+    MediateInterruptRace(const Message& parent, const Message& child) override;
+
+    virtual void ActorDestroy(ActorDestroyReason why) override
+    {
+        if (NormalShutdown != why)
+            fail("unexpected destruction!");
+        QuitChild();
+    }
+};
+
+
+} // namespace _ipdltest
+} // namespace mozilla
+
+
+#endif // ifndef mozilla__ipdltest_TestRaceDeadlock_h
--- a/ipc/ipdl/test/cxx/moz.build
+++ b/ipc/ipdl/test/cxx/moz.build
@@ -27,16 +27,17 @@ SOURCES += [
     'TestInterruptRaces.cpp',
     'TestInterruptShutdownRace.cpp',
     'TestJSON.cpp',
     'TestLatency.cpp',
     'TestManyChildAllocs.cpp',
     'TestMultiMgrs.cpp',
     'TestNestedLoops.cpp',
     'TestOpens.cpp',
+    'TestRaceDeadlock.cpp',
     'TestRaceDeferral.cpp',
     'TestRacyInterruptReplies.cpp',
     'TestRacyReentry.cpp',
     'TestRacyUndefer.cpp',
     'TestRPC.cpp',
     'TestSanity.cpp',
     'TestSelfManageRoot.cpp',
     'TestShmem.cpp',
@@ -98,16 +99,17 @@ IPDL_SOURCES += [
     'PTestManyChildAllocsSub.ipdl',
     'PTestMultiMgrs.ipdl',
     'PTestMultiMgrsBottom.ipdl',
     'PTestMultiMgrsLeft.ipdl',
     'PTestMultiMgrsRight.ipdl',
     'PTestNestedLoops.ipdl',
     'PTestOpens.ipdl',
     'PTestOpensOpened.ipdl',
+    'PTestRaceDeadlock.ipdl',
     'PTestRaceDeferral.ipdl',
     'PTestRacyInterruptReplies.ipdl',
     'PTestRacyReentry.ipdl',
     'PTestRacyUndefer.ipdl',
     'PTestRPC.ipdl',
     'PTestSanity.ipdl',
     'PTestSelfManage.ipdl',
     'PTestSelfManageRoot.ipdl',