ipc/ipdl/test/cxx/TestInterruptShutdownRace.cpp

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

     1 #include "TestInterruptShutdownRace.h"
     3 #include "IPDLUnitTests.h"      // fail etc.
     4 #include "IPDLUnitTestSubprocess.h"
     6 template<>
     7 struct RunnableMethodTraits<mozilla::_ipdltest::TestInterruptShutdownRaceParent>
     8 {
     9     static void RetainCallee(mozilla::_ipdltest::TestInterruptShutdownRaceParent* obj) { }
    10     static void ReleaseCallee(mozilla::_ipdltest::TestInterruptShutdownRaceParent* obj) { }
    11 };
    14 namespace mozilla {
    15 namespace _ipdltest {
    17 //-----------------------------------------------------------------------------
    18 // parent
    20 namespace {
    22 // NB: this test does its own shutdown, rather than going through
    23 // QuitParent(), because it's testing degenerate edge cases
    25 void DeleteSubprocess()
    26 {
    27     delete gSubprocess;
    28     gSubprocess = nullptr;
    29 }
    31 void Done()
    32 {
    33     passed(__FILE__);
    34     QuitParent();
    35 }
    37 } // namespace <anon>
    39 TestInterruptShutdownRaceParent::TestInterruptShutdownRaceParent()
    40 {
    41     MOZ_COUNT_CTOR(TestInterruptShutdownRaceParent);
    42 }
    44 TestInterruptShutdownRaceParent::~TestInterruptShutdownRaceParent()
    45 {
    46     MOZ_COUNT_DTOR(TestInterruptShutdownRaceParent);
    47 }
    49 void
    50 TestInterruptShutdownRaceParent::Main()
    51 {
    52     if (!SendStart())
    53         fail("sending Start");
    54 }
    56 bool
    57 TestInterruptShutdownRaceParent::RecvStartDeath()
    58 {
    59     // this will be ordered before the OnMaybeDequeueOne event of
    60     // Orphan in the queue
    61     MessageLoop::current()->PostTask(
    62         FROM_HERE,
    63         NewRunnableMethod(this,
    64                           &TestInterruptShutdownRaceParent::StartShuttingDown));
    65     return true;
    66 }
    68 void
    69 TestInterruptShutdownRaceParent::StartShuttingDown()
    70 {
    71     // NB: we sleep here to try and avoid receiving the Orphan message
    72     // while waiting for the CallExit() reply.  if we fail at that, it
    73     // will cause the test to pass spuriously, because there won't be
    74     // an OnMaybeDequeueOne task for Orphan
    75     PR_Sleep(2000);
    77     if (CallExit())
    78         fail("connection was supposed to be interrupted");
    80     Close();
    82     delete static_cast<TestInterruptShutdownRaceParent*>(gParentActor);
    83     gParentActor = nullptr;
    85     XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
    86                                      NewRunnableFunction(DeleteSubprocess));
    88     // this is ordered after the OnMaybeDequeueOne event in the queue
    89     MessageLoop::current()->PostTask(FROM_HERE,
    90                                      NewRunnableFunction(Done));
    92     // |this| has been deleted, be mindful
    93 }
    95 bool
    96 TestInterruptShutdownRaceParent::RecvOrphan()
    97 {
    98     // it would be nice to fail() here, but we'll process this message
    99     // while waiting for the reply CallExit().  The OnMaybeDequeueOne
   100     // task will still be in the queue, it just wouldn't have had any
   101     // work to do, if we hadn't deleted ourself
   102     return true;
   103 }
   105 //-----------------------------------------------------------------------------
   106 // child
   108 TestInterruptShutdownRaceChild::TestInterruptShutdownRaceChild()
   109 {
   110     MOZ_COUNT_CTOR(TestInterruptShutdownRaceChild);
   111 }
   113 TestInterruptShutdownRaceChild::~TestInterruptShutdownRaceChild()
   114 {
   115     MOZ_COUNT_DTOR(TestInterruptShutdownRaceChild);
   116 }
   118 bool
   119 TestInterruptShutdownRaceChild::RecvStart()
   120 {
   121     if (!SendStartDeath())
   122         fail("sending StartDeath");
   124     // See comment in StartShuttingDown(): we want to send Orphan()
   125     // while the parent is in its PR_Sleep()
   126     PR_Sleep(1000);
   128     if (!SendOrphan())
   129         fail("sending Orphan");
   131     return true;
   132 }
   134 bool
   135 TestInterruptShutdownRaceChild::AnswerExit()
   136 {
   137     _exit(0);
   138     NS_RUNTIMEABORT("unreached");
   139     return false;
   140 }
   143 } // namespace _ipdltest
   144 } // namespace mozilla

mercurial