ipc/ipdl/test/cxx/TestHangs.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 "base/process_util.h"
     3 #include "TestHangs.h"
     5 #include "IPDLUnitTests.h"      // fail etc.
     7 using base::KillProcess;
     9 template<>
    10 struct RunnableMethodTraits<mozilla::_ipdltest::TestHangsParent>
    11 {
    12     static void RetainCallee(mozilla::_ipdltest::TestHangsParent* obj) { }
    13     static void ReleaseCallee(mozilla::_ipdltest::TestHangsParent* obj) { }
    14 };
    16 namespace mozilla {
    17 namespace _ipdltest {
    19 //-----------------------------------------------------------------------------
    20 // parent
    22 TestHangsParent::TestHangsParent() : mDetectedHang(false)
    23 {
    24     MOZ_COUNT_CTOR(TestHangsParent);
    25 }
    27 TestHangsParent::~TestHangsParent()
    28 {
    29     MOZ_COUNT_DTOR(TestHangsParent);
    30 }
    32 void
    33 TestHangsParent::Main()
    34 {
    35     // Here we try to set things up to test the following sequence of events:
    36     //
    37     // - subprocess causes an OnMaybeDequeueOne() task to be posted to
    38     //   this thread
    39     //
    40     // - subprocess hangs just long enough for the hang timer to expire
    41     //
    42     // - hang-kill code in the parent starts running
    43     //
    44     // - subprocess replies to message while hang code runs
    45     //
    46     // - reply is processed in OnMaybeDequeueOne() before Close() has
    47     //   been called or the channel error notification has been posted
    49     // this tells the subprocess to send us Nonce()
    50     if (!SendStart())
    51         fail("sending Start");
    53     // now we sleep here for a while awaiting the Nonce() message from
    54     // the child.  since we're not blocked on anything, the IO thread
    55     // will enqueue an OnMaybeDequeueOne() task to process that
    56     // message
    57     // 
    58     // NB: PR_Sleep is exactly what we want, only the current thread
    59     // sleeping
    60     PR_Sleep(5000);
    62     // when we call into this, we'll pull the Nonce() message out of
    63     // the mPending queue, but that doesn't matter ... the
    64     // OnMaybeDequeueOne() event will remain
    65     if (CallStackFrame() && mDetectedHang)
    66         fail("should have timed out!");
    68     // the Close() task in the queue will shut us down
    69 }
    71 bool
    72 TestHangsParent::ShouldContinueFromReplyTimeout()
    73 {
    74     mDetectedHang = true;
    76     // so we've detected a timeout after 2 ms ... now we cheat and
    77     // sleep for a long time, to allow the subprocess's reply to come
    78     // in
    80     PR_Sleep(5000);
    82     // reply should be here; we'll post a task to shut things down.
    83     // This must be after OnMaybeDequeueOne() in the event queue.
    84     MessageLoop::current()->PostTask(
    85         FROM_HERE, NewRunnableMethod(this, &TestHangsParent::CleanUp));
    87     return false;
    88 }
    90 bool
    91 TestHangsParent::AnswerStackFrame()
    92 {
    93     if (PTestHangs::HANG != state()) {
    94         if (CallStackFrame())
    95             fail("should have timed out!");
    96     }
    97     else {
    98         // minimum possible, 2 ms.  We want to detecting a hang to race
    99         // with the reply coming in, as reliably as possible
   100         SetReplyTimeoutMs(2);
   102         if (CallHang())
   103             fail("should have timed out!");
   104     }
   106     return true;
   107 }
   109 void
   110 TestHangsParent::CleanUp()
   111 {
   112     if (!KillProcess(OtherProcess(), 0, false))
   113         fail("terminating child process");
   114     Close();
   115 }
   118 //-----------------------------------------------------------------------------
   119 // child
   121 TestHangsChild::TestHangsChild()
   122 {
   123     MOZ_COUNT_CTOR(TestHangsChild);
   124 }
   126 TestHangsChild::~TestHangsChild()
   127 {
   128     MOZ_COUNT_DTOR(TestHangsChild);
   129 }
   131 bool
   132 TestHangsChild::AnswerHang()
   133 {
   134     puts(" (child process is 'hanging' now)");
   136     // just sleep until we're reasonably confident the 1ms hang
   137     // detector fired in the parent process and it's sleeping in
   138     // ShouldContinueFromReplyTimeout()
   139     PR_Sleep(1000);
   141     return true;
   142 }
   144 } // namespace _ipdltest
   145 } // namespace mozilla

mercurial