Bug 521929, part 3: IPDL/C++ test.
authorChris Jones <jones.chris.g@gmail.com>
Thu, 21 Jan 2010 20:04:11 -0600
changeset 37475 c1e297cb449ee147e27d078d6e0b067760782ac9
parent 37474 925601df843fdb59381d9c9a5e26961b8ae855c1
child 37476 d4d28cc35858af6c0007b61a057d628b12d3b8be
push id11325
push userbsmedberg@mozilla.com
push dateMon, 25 Jan 2010 14:50:07 +0000
treeherderautoland@38e86af96757 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs521929
milestone1.9.3a1pre
Bug 521929, part 3: IPDL/C++ test.
ipc/ipdl/test/cxx/Makefile.in
ipc/ipdl/test/cxx/PTestRacyRPCReplies.ipdl
ipc/ipdl/test/cxx/TestRacyRPCReplies.cpp
ipc/ipdl/test/cxx/TestRacyRPCReplies.h
ipc/ipdl/test/cxx/ipdl.mk
--- a/ipc/ipdl/test/cxx/Makefile.in
+++ b/ipc/ipdl/test/cxx/Makefile.in
@@ -60,16 +60,17 @@ EXPORT_LIBRARY = 1
 # Please keep these organized in the order "easy"-to-"hard"
 IPDLTESTS = \
   TestSanity  \
   TestRPCErrorCleanup \
   TestCrashCleanup \
   TestSyncWakeup \
   TestLatency \
   TestRPCRaces \
+  TestRacyRPCReplies  \
   TestManyChildAllocs  \
   TestDesc \
   TestShmem \
   TestShutdown \
   TestArrays \
   $(NULL)
 
 IPDLTESTSRCS = $(addsuffix .cpp,$(IPDLTESTS))
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/PTestRacyRPCReplies.ipdl
@@ -0,0 +1,27 @@
+namespace mozilla {
+namespace _ipdltest {
+
+rpc protocol PTestRacyRPCReplies {
+child:
+    rpc R() returns (int replyNum);
+    async __delete__();
+
+parent:
+    async A();
+
+
+state START:
+    call R goto S1;
+
+state S1:
+    recv A goto S2;
+
+state S2:
+    call R goto DYING;
+
+state DYING:
+    send __delete__;
+};
+
+} // namespace _ipdltest
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/TestRacyRPCReplies.cpp
@@ -0,0 +1,78 @@
+#include "TestRacyRPCReplies.h"
+
+#include "IPDLUnitTests.h"      // fail etc.
+
+namespace mozilla {
+namespace _ipdltest {
+
+//-----------------------------------------------------------------------------
+// parent
+
+TestRacyRPCRepliesParent::TestRacyRPCRepliesParent()
+{
+    MOZ_COUNT_CTOR(TestRacyRPCRepliesParent);
+}
+
+TestRacyRPCRepliesParent::~TestRacyRPCRepliesParent()
+{
+    MOZ_COUNT_DTOR(TestRacyRPCRepliesParent);
+}
+
+void
+TestRacyRPCRepliesParent::Main()
+{
+    int replyNum = -1;
+    if (!CallR(&replyNum))
+        fail("calling R()");
+
+    if (1 != replyNum)
+        fail("this should have been the first reply to R()");
+
+    Close();
+}
+
+bool
+TestRacyRPCRepliesParent::RecvA()
+{
+    int replyNum = -1;
+    // this R() call races with the reply being generated by the other
+    // side to the R() call from Main().  This is a pretty nasty edge
+    // case for which one could argue we're breaking in-order message
+    // delivery, since this side will process the second reply to R()
+    // before the first.
+    if (!CallR(&replyNum))
+        fail("calling R()");
+
+    if (2 != replyNum)
+        fail("this should have been the second reply to R()");
+
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+// child
+
+TestRacyRPCRepliesChild::TestRacyRPCRepliesChild() : mReplyNum(0)
+{
+    MOZ_COUNT_CTOR(TestRacyRPCRepliesChild);
+}
+
+TestRacyRPCRepliesChild::~TestRacyRPCRepliesChild()
+{
+    MOZ_COUNT_DTOR(TestRacyRPCRepliesChild);
+}
+
+bool
+TestRacyRPCRepliesChild::AnswerR(int* replyNum)
+{
+    *replyNum = ++mReplyNum;
+
+    if (1 == *replyNum)
+        SendA();
+
+    return true;
+}
+
+
+} // namespace _ipdltest
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/TestRacyRPCReplies.h
@@ -0,0 +1,65 @@
+#ifndef mozilla__ipdltest_TestRacyRPCReplies_h
+#define mozilla__ipdltest_TestRacyRPCReplies_h 1
+
+#include "mozilla/_ipdltest/IPDLUnitTests.h"
+
+#include "mozilla/_ipdltest/PTestRacyRPCRepliesParent.h"
+#include "mozilla/_ipdltest/PTestRacyRPCRepliesChild.h"
+
+namespace mozilla {
+namespace _ipdltest {
+
+
+class TestRacyRPCRepliesParent :
+    public PTestRacyRPCRepliesParent
+{
+public:
+    TestRacyRPCRepliesParent();
+    virtual ~TestRacyRPCRepliesParent();
+
+    void Main();
+
+protected:    
+    NS_OVERRIDE
+    virtual bool RecvA();
+
+    NS_OVERRIDE
+    virtual void ActorDestroy(ActorDestroyReason why)
+    {
+        if (NormalShutdown != why)
+            fail("unexpected destruction!");  
+        passed("ok");
+        QuitParent();
+    }
+};
+
+
+class TestRacyRPCRepliesChild :
+    public PTestRacyRPCRepliesChild
+{
+public:
+    TestRacyRPCRepliesChild();
+    virtual ~TestRacyRPCRepliesChild();
+
+protected:
+    NS_OVERRIDE
+    virtual bool AnswerR(int* replyNum);
+
+    NS_OVERRIDE
+    virtual void ActorDestroy(ActorDestroyReason why)
+    {
+        if (NormalShutdown != why)
+            fail("unexpected destruction!");
+        QuitChild();
+    }
+
+private:
+    int mReplyNum;
+};
+
+
+} // namespace _ipdltest
+} // namespace mozilla
+
+
+#endif // ifndef mozilla__ipdltest_TestRacyRPCReplies_h
--- a/ipc/ipdl/test/cxx/ipdl.mk
+++ b/ipc/ipdl/test/cxx/ipdl.mk
@@ -3,16 +3,17 @@ IPDLSRCS =					\
   PTestArraysSub.ipdl				\
   PTestCrashCleanup.ipdl			\
   PTestDesc.ipdl				\
   PTestDescSub.ipdl				\
   PTestDescSubsub.ipdl				\
   PTestLatency.ipdl				\
   PTestManyChildAllocs.ipdl			\
   PTestManyChildAllocsSub.ipdl			\
+  PTestRacyRPCReplies.ipdl			\
   PTestRPCErrorCleanup.ipdl			\
   PTestRPCRaces.ipdl				\
   PTestSanity.ipdl				\
   PTestShmem.ipdl				\
   PTestShutdown.ipdl				\
   PTestShutdownSub.ipdl				\
   PTestShutdownSubsub.ipdl			\
   PTestSyncWakeup.ipdl				\