ipc/ipdl/test/cxx/TestBridgeMain.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 "TestBridgeMain.h"
     3 #include "IPDLUnitTests.h"      // fail etc.
     4 #include "IPDLUnitTestSubprocess.h"
     6 using namespace std;
     8 template<>
     9 struct RunnableMethodTraits<mozilla::_ipdltest::TestBridgeMainSubChild>
    10 {
    11     static void RetainCallee(mozilla::_ipdltest::TestBridgeMainSubChild* obj) { }
    12     static void ReleaseCallee(mozilla::_ipdltest::TestBridgeMainSubChild* obj) { }
    13 };
    15 namespace mozilla {
    16 namespace _ipdltest {
    19 //-----------------------------------------------------------------------------
    20 // main process
    21 void
    22 TestBridgeMainParent::Main()
    23 {
    24     if (!SendStart())
    25         fail("sending Start");
    26 }
    28 PTestBridgeMainSubParent*
    29 TestBridgeMainParent::AllocPTestBridgeMainSubParent(Transport* transport,
    30                                                     ProcessId otherProcess)
    31 {
    32     ProcessHandle h;
    33     if (!base::OpenProcessHandle(otherProcess, &h)) {
    34         return nullptr;
    35     }
    37     nsAutoPtr<TestBridgeMainSubParent> a(new TestBridgeMainSubParent(transport));
    38     if (!a->Open(transport, h, XRE_GetIOMessageLoop(), ipc::ParentSide)) {
    39         return nullptr;
    40     }
    41     return a.forget();
    42 }
    44 void
    45 TestBridgeMainParent::ActorDestroy(ActorDestroyReason why)
    46 {
    47     if (NormalShutdown != why)
    48         fail("unexpected destruction!");  
    49     passed("ok");
    50     QuitParent();
    51 }
    53 bool
    54 TestBridgeMainSubParent::RecvHello()
    55 {
    56     return SendHi();
    57 }
    59 bool
    60 TestBridgeMainSubParent::RecvHelloSync()
    61 {
    62     return true;
    63 }
    65 bool
    66 TestBridgeMainSubParent::AnswerHelloRpc()
    67 {
    68     return CallHiRpc();
    69 }
    71 void
    72 TestBridgeMainSubParent::ActorDestroy(ActorDestroyReason why)
    73 {
    74     if (NormalShutdown != why)
    75         fail("unexpected destruction!");
    77     // ActorDestroy() is just a callback from IPDL-generated code,
    78     // which needs the top-level actor (this) to stay alive a little
    79     // longer so other things can be cleaned up.
    80     MessageLoop::current()->PostTask(
    81         FROM_HERE,
    82         new DeleteTask<TestBridgeMainSubParent>(this));
    83     XRE_GetIOMessageLoop()->PostTask(
    84         FROM_HERE,
    85         new DeleteTask<Transport>(mTransport));
    86 }
    88 //-----------------------------------------------------------------------------
    89 // sub process --- child of main
    90 TestBridgeMainChild* gBridgeMainChild;
    92 TestBridgeMainChild::TestBridgeMainChild()
    93     : mSubprocess(nullptr)
    94 {
    95     gBridgeMainChild = this;
    96 }
    98 bool
    99 TestBridgeMainChild::RecvStart()
   100 {
   101     vector<string> subsubArgs;
   102     subsubArgs.push_back("TestBridgeSub");
   104     mSubprocess = new IPDLUnitTestSubprocess();
   105     if (!mSubprocess->SyncLaunch(subsubArgs))
   106         fail("problem launching subprocess");
   108     IPC::Channel* transport = mSubprocess->GetChannel();
   109     if (!transport)
   110         fail("no transport");
   112     TestBridgeSubParent* bsp = new TestBridgeSubParent();
   113     bsp->Open(transport, mSubprocess->GetChildProcessHandle());
   115     bsp->Main();
   116     return true;
   117 }
   119 void
   120 TestBridgeMainChild::ActorDestroy(ActorDestroyReason why)
   121 {
   122     if (NormalShutdown != why)
   123         fail("unexpected destruction!");  
   124     // NB: this is kosher because QuitChild() joins with the IO thread
   125     XRE_GetIOMessageLoop()->PostTask(
   126         FROM_HERE,
   127         new DeleteTask<IPDLUnitTestSubprocess>(mSubprocess));
   128     QuitChild();
   129 }
   131 void
   132 TestBridgeSubParent::Main()
   133 {
   134     if (!SendPing())
   135         fail("sending Ping");
   136 }
   138 bool
   139 TestBridgeSubParent::RecvBridgeEm()
   140 {
   141     if (!PTestBridgeMainSub::Bridge(gBridgeMainChild, this))
   142         fail("bridging Main and Sub");
   143     return true;
   144 }
   146 void
   147 TestBridgeSubParent::ActorDestroy(ActorDestroyReason why)
   148 {
   149     if (NormalShutdown != why)
   150         fail("unexpected destruction!");
   151     gBridgeMainChild->Close();
   153     // ActorDestroy() is just a callback from IPDL-generated code,
   154     // which needs the top-level actor (this) to stay alive a little
   155     // longer so other things can be cleaned up.
   156     MessageLoop::current()->PostTask(
   157         FROM_HERE,
   158         new DeleteTask<TestBridgeSubParent>(this));
   159 }
   161 //-----------------------------------------------------------------------------
   162 // subsub process --- child of sub
   164 static TestBridgeSubChild* gBridgeSubChild;
   166 TestBridgeSubChild::TestBridgeSubChild()
   167 {
   168     gBridgeSubChild = this;   
   169 }
   171 bool
   172 TestBridgeSubChild::RecvPing()
   173 {
   174     if (!SendBridgeEm())
   175         fail("sending BridgeEm");
   176     return true;
   177 }
   179 PTestBridgeMainSubChild*
   180 TestBridgeSubChild::AllocPTestBridgeMainSubChild(Transport* transport,
   181                                                  ProcessId otherProcess)
   182 {
   183     ProcessHandle h;
   184     if (!base::OpenProcessHandle(otherProcess, &h)) {
   185         return nullptr;
   186     }
   188     nsAutoPtr<TestBridgeMainSubChild> a(new TestBridgeMainSubChild(transport));
   189     if (!a->Open(transport, h, XRE_GetIOMessageLoop(), ipc::ChildSide)) {
   190         return nullptr;
   191     }
   193     if (!a->SendHello())
   194         fail("sending Hello");
   196     return a.forget();
   197 }
   199 void
   200 TestBridgeSubChild::ActorDestroy(ActorDestroyReason why)
   201 {
   202     if (NormalShutdown != why)
   203         fail("unexpected destruction!");
   204     QuitChild();
   205 }
   207 bool
   208 TestBridgeMainSubChild::RecvHi()
   209 {
   210     if (!SendHelloSync())
   211         fail("sending HelloSync");
   212     if (!CallHelloRpc())
   213         fail("calling HelloRpc");
   214     if (!mGotHi)
   215         fail("didn't answer HiRpc");
   217     // Need to close the channel without message-processing frames on
   218     // the C++ stack
   219     MessageLoop::current()->PostTask(
   220         FROM_HERE,
   221         NewRunnableMethod(this, &TestBridgeMainSubChild::Close));
   222     return true;
   223 }
   225 bool
   226 TestBridgeMainSubChild::AnswerHiRpc()
   227 {
   228     mGotHi = true;              // d00d
   229     return true;
   230 }
   232 void
   233 TestBridgeMainSubChild::ActorDestroy(ActorDestroyReason why)
   234 {
   235     if (NormalShutdown != why)
   236         fail("unexpected destruction!");  
   238     gBridgeSubChild->Close();
   240     // ActorDestroy() is just a callback from IPDL-generated code,
   241     // which needs the top-level actor (this) to stay alive a little
   242     // longer so other things can be cleaned up.
   243     MessageLoop::current()->PostTask(
   244         FROM_HERE,
   245         new DeleteTask<TestBridgeMainSubChild>(this));
   246     XRE_GetIOMessageLoop()->PostTask(
   247         FROM_HERE,
   248         new DeleteTask<Transport>(mTransport));
   249 }
   251 } // namespace mozilla
   252 } // namespace _ipdltest

mercurial