mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 12:50:09 +00:00
Bug 564086, part r: Test IPDL |bridge|
This commit is contained in:
parent
777e4d37f8
commit
8c842dccb2
@ -59,6 +59,7 @@ EXPORT_LIBRARY = 1
|
||||
|
||||
IPDLTESTS = \
|
||||
TestBlockChild \
|
||||
TestBridgeMain \
|
||||
TestCrashCleanup \
|
||||
TestDataStructures \
|
||||
TestDesc \
|
||||
@ -89,7 +90,9 @@ ifeq ($(OS_ARCH),Linux)
|
||||
IPDLTESTS += TestSysVShmem
|
||||
endif
|
||||
|
||||
EXTRA_PROTOCOLS =
|
||||
EXTRA_PROTOCOLS = \
|
||||
TestBridgeSub \
|
||||
$(NULL)
|
||||
|
||||
IPDLTESTSRCS = $(addsuffix .cpp,$(IPDLTESTS))
|
||||
IPDLTESTHDRS = $(addprefix $(srcdir)/,$(addsuffix .h,$(IPDLTESTS)))
|
||||
|
24
ipc/ipdl/test/cxx/PTestBridgeMain.ipdl
Normal file
24
ipc/ipdl/test/cxx/PTestBridgeMain.ipdl
Normal file
@ -0,0 +1,24 @@
|
||||
include protocol PTestBridgeSub;
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
|
||||
protocol PTestBridgeMain {
|
||||
child spawns PTestBridgeSub;
|
||||
|
||||
child:
|
||||
Start();
|
||||
|
||||
parent:
|
||||
__delete__();
|
||||
|
||||
state START:
|
||||
send Start goto DEAD;
|
||||
state DEAD:
|
||||
recv __delete__;
|
||||
};
|
||||
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace _ipdltest
|
33
ipc/ipdl/test/cxx/PTestBridgeMainSub.ipdl
Normal file
33
ipc/ipdl/test/cxx/PTestBridgeMainSub.ipdl
Normal file
@ -0,0 +1,33 @@
|
||||
include protocol PTestBridgeMain;
|
||||
include protocol PTestBridgeSub;
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
// (Bridge protocols can have different semantics than the endpoints
|
||||
// they bridge)
|
||||
rpc protocol PTestBridgeMainSub {
|
||||
bridges PTestBridgeMain, PTestBridgeSub;
|
||||
|
||||
child:
|
||||
Hi();
|
||||
rpc HiRpc();
|
||||
|
||||
parent:
|
||||
Hello();
|
||||
sync HelloSync();
|
||||
rpc HelloRpc();
|
||||
__delete__();
|
||||
|
||||
state START: recv Hello goto HI;
|
||||
state HI: send Hi goto HELLO_SYNC;
|
||||
state HELLO_SYNC: recv HelloSync goto HELLO_RPC;
|
||||
state HELLO_RPC: answer HelloRpc goto HI_RPC;
|
||||
state HI_RPC: call HiRpc goto DEAD;
|
||||
state DEAD:
|
||||
recv __delete__;
|
||||
};
|
||||
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace _ipdltest
|
24
ipc/ipdl/test/cxx/PTestBridgeSub.ipdl
Normal file
24
ipc/ipdl/test/cxx/PTestBridgeSub.ipdl
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
|
||||
protocol PTestBridgeSub {
|
||||
child:
|
||||
Ping();
|
||||
|
||||
parent:
|
||||
BridgeEm();
|
||||
__delete__();
|
||||
|
||||
state START:
|
||||
send Ping goto BRIDGEEM;
|
||||
state BRIDGEEM:
|
||||
recv BridgeEm goto DEAD;
|
||||
state DEAD:
|
||||
recv __delete__;
|
||||
};
|
||||
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace _ipdltest
|
252
ipc/ipdl/test/cxx/TestBridgeMain.cpp
Normal file
252
ipc/ipdl/test/cxx/TestBridgeMain.cpp
Normal file
@ -0,0 +1,252 @@
|
||||
#include "TestBridgeMain.h"
|
||||
|
||||
#include "IPDLUnitTests.h" // fail etc.
|
||||
#include "IPDLUnitTestSubprocess.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
template<>
|
||||
struct RunnableMethodTraits<mozilla::_ipdltest::TestBridgeMainSubChild>
|
||||
{
|
||||
static void RetainCallee(mozilla::_ipdltest::TestBridgeMainSubChild* obj) { }
|
||||
static void ReleaseCallee(mozilla::_ipdltest::TestBridgeMainSubChild* obj) { }
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// main process
|
||||
void
|
||||
TestBridgeMainParent::Main()
|
||||
{
|
||||
if (!SendStart())
|
||||
fail("sending Start");
|
||||
}
|
||||
|
||||
PTestBridgeMainSubParent*
|
||||
TestBridgeMainParent::AllocPTestBridgeMainSub(Transport* transport,
|
||||
ProcessId otherProcess)
|
||||
{
|
||||
ProcessHandle h;
|
||||
if (!base::OpenProcessHandle(otherProcess, &h)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsAutoPtr<TestBridgeMainSubParent> a(new TestBridgeMainSubParent(transport));
|
||||
if (!a->Open(transport, h, XRE_GetIOMessageLoop(), AsyncChannel::Parent)) {
|
||||
return nsnull;
|
||||
}
|
||||
return a.forget();
|
||||
}
|
||||
|
||||
void
|
||||
TestBridgeMainParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
passed("ok");
|
||||
QuitParent();
|
||||
}
|
||||
|
||||
bool
|
||||
TestBridgeMainSubParent::RecvHello()
|
||||
{
|
||||
return SendHi();
|
||||
}
|
||||
|
||||
bool
|
||||
TestBridgeMainSubParent::RecvHelloSync()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestBridgeMainSubParent::AnswerHelloRpc()
|
||||
{
|
||||
return CallHiRpc();
|
||||
}
|
||||
|
||||
void
|
||||
TestBridgeMainSubParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
|
||||
// ActorDestroy() is just a callback from IPDL-generated code,
|
||||
// which needs the top-level actor (this) to stay alive a little
|
||||
// longer so other things can be cleaned up.
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
new DeleteTask<TestBridgeMainSubParent>(this));
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
new DeleteTask<Transport>(mTransport));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// sub process --- child of main
|
||||
TestBridgeMainChild* gBridgeMainChild;
|
||||
|
||||
TestBridgeMainChild::TestBridgeMainChild()
|
||||
: mSubprocess(nsnull)
|
||||
{
|
||||
gBridgeMainChild = this;
|
||||
}
|
||||
|
||||
bool
|
||||
TestBridgeMainChild::RecvStart()
|
||||
{
|
||||
vector<string> subsubArgs;
|
||||
subsubArgs.push_back("TestBridgeSub");
|
||||
|
||||
mSubprocess = new IPDLUnitTestSubprocess();
|
||||
if (!mSubprocess->SyncLaunch(subsubArgs))
|
||||
fail("problem launching subprocess");
|
||||
|
||||
IPC::Channel* transport = mSubprocess->GetChannel();
|
||||
if (!transport)
|
||||
fail("no transport");
|
||||
|
||||
TestBridgeSubParent* bsp = new TestBridgeSubParent();
|
||||
bsp->Open(transport, mSubprocess->GetChildProcessHandle());
|
||||
|
||||
bsp->Main();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TestBridgeMainChild::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
// NB: this is kosher because QuitChild() joins with the IO thread
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
new DeleteTask<IPDLUnitTestSubprocess>(mSubprocess));
|
||||
QuitChild();
|
||||
}
|
||||
|
||||
void
|
||||
TestBridgeSubParent::Main()
|
||||
{
|
||||
if (!SendPing())
|
||||
fail("sending Ping");
|
||||
}
|
||||
|
||||
bool
|
||||
TestBridgeSubParent::RecvBridgeEm()
|
||||
{
|
||||
if (!PTestBridgeMainSub::Bridge(gBridgeMainChild, this))
|
||||
fail("bridging Main and Sub");
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TestBridgeSubParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
gBridgeMainChild->Close();
|
||||
|
||||
// ActorDestroy() is just a callback from IPDL-generated code,
|
||||
// which needs the top-level actor (this) to stay alive a little
|
||||
// longer so other things can be cleaned up.
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
new DeleteTask<TestBridgeSubParent>(this));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// subsub process --- child of sub
|
||||
|
||||
static TestBridgeSubChild* gBridgeSubChild;
|
||||
|
||||
TestBridgeSubChild::TestBridgeSubChild()
|
||||
{
|
||||
gBridgeSubChild = this;
|
||||
}
|
||||
|
||||
bool
|
||||
TestBridgeSubChild::RecvPing()
|
||||
{
|
||||
if (!SendBridgeEm())
|
||||
fail("sending BridgeEm");
|
||||
return true;
|
||||
}
|
||||
|
||||
PTestBridgeMainSubChild*
|
||||
TestBridgeSubChild::AllocPTestBridgeMainSub(Transport* transport,
|
||||
ProcessId otherProcess)
|
||||
{
|
||||
ProcessHandle h;
|
||||
if (!base::OpenProcessHandle(otherProcess, &h)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsAutoPtr<TestBridgeMainSubChild> a(new TestBridgeMainSubChild(transport));
|
||||
if (!a->Open(transport, h, XRE_GetIOMessageLoop(), AsyncChannel::Child)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (!a->SendHello())
|
||||
fail("sending Hello");
|
||||
|
||||
return a.forget();
|
||||
}
|
||||
|
||||
void
|
||||
TestBridgeSubChild::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
QuitChild();
|
||||
}
|
||||
|
||||
bool
|
||||
TestBridgeMainSubChild::RecvHi()
|
||||
{
|
||||
if (!SendHelloSync())
|
||||
fail("sending HelloSync");
|
||||
if (!CallHelloRpc())
|
||||
fail("calling HelloRpc");
|
||||
if (!mGotHi)
|
||||
fail("didn't answer HiRpc");
|
||||
|
||||
// Need to close the channel without message-processing frames on
|
||||
// the C++ stack
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(this, &TestBridgeMainSubChild::Close));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TestBridgeMainSubChild::AnswerHiRpc()
|
||||
{
|
||||
mGotHi = true; // d00d
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TestBridgeMainSubChild::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (NormalShutdown != why)
|
||||
fail("unexpected destruction!");
|
||||
|
||||
gBridgeSubChild->Close();
|
||||
|
||||
// ActorDestroy() is just a callback from IPDL-generated code,
|
||||
// which needs the top-level actor (this) to stay alive a little
|
||||
// longer so other things can be cleaned up.
|
||||
MessageLoop::current()->PostTask(
|
||||
FROM_HERE,
|
||||
new DeleteTask<TestBridgeMainSubChild>(this));
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
new DeleteTask<Transport>(mTransport));
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
} // namespace _ipdltest
|
152
ipc/ipdl/test/cxx/TestBridgeMain.h
Normal file
152
ipc/ipdl/test/cxx/TestBridgeMain.h
Normal file
@ -0,0 +1,152 @@
|
||||
#ifndef mozilla__ipdltest_TestBridgeMain_h
|
||||
#define mozilla__ipdltest_TestBridgeMain_h 1
|
||||
|
||||
#include "mozilla/_ipdltest/IPDLUnitTests.h"
|
||||
|
||||
#include "mozilla/_ipdltest/PTestBridgeMainParent.h"
|
||||
#include "mozilla/_ipdltest/PTestBridgeMainChild.h"
|
||||
|
||||
#include "mozilla/_ipdltest/PTestBridgeSubParent.h"
|
||||
#include "mozilla/_ipdltest/PTestBridgeSubChild.h"
|
||||
|
||||
#include "mozilla/_ipdltest/PTestBridgeMainSubParent.h"
|
||||
#include "mozilla/_ipdltest/PTestBridgeMainSubChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace _ipdltest {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// "Main" process
|
||||
//
|
||||
class TestBridgeMainParent :
|
||||
public PTestBridgeMainParent
|
||||
{
|
||||
public:
|
||||
TestBridgeMainParent() {}
|
||||
virtual ~TestBridgeMainParent() {}
|
||||
|
||||
void Main();
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual PTestBridgeMainSubParent*
|
||||
AllocPTestBridgeMainSub(Transport* transport,
|
||||
ProcessId otherProcess);
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
};
|
||||
|
||||
class TestBridgeMainSubParent :
|
||||
public PTestBridgeMainSubParent
|
||||
{
|
||||
public:
|
||||
TestBridgeMainSubParent(Transport* aTransport)
|
||||
: mTransport(aTransport)
|
||||
{}
|
||||
virtual ~TestBridgeMainSubParent() {}
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual bool RecvHello();
|
||||
NS_OVERRIDE
|
||||
virtual bool RecvHelloSync();
|
||||
NS_OVERRIDE
|
||||
virtual bool AnswerHelloRpc();
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
|
||||
Transport* mTransport;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// "Sub" process --- child of "main"
|
||||
//
|
||||
class TestBridgeSubParent;
|
||||
|
||||
class TestBridgeMainChild :
|
||||
public PTestBridgeMainChild
|
||||
{
|
||||
public:
|
||||
TestBridgeMainChild();
|
||||
virtual ~TestBridgeMainChild() {}
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual bool RecvStart();
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
|
||||
IPDLUnitTestSubprocess* mSubprocess;
|
||||
};
|
||||
|
||||
class TestBridgeSubParent :
|
||||
public PTestBridgeSubParent
|
||||
{
|
||||
public:
|
||||
TestBridgeSubParent() {}
|
||||
virtual ~TestBridgeSubParent() {}
|
||||
|
||||
void Main();
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual bool RecvBridgeEm();
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// "Subsub" process --- child of "sub"
|
||||
//
|
||||
class TestBridgeSubChild :
|
||||
public PTestBridgeSubChild
|
||||
{
|
||||
public:
|
||||
TestBridgeSubChild();
|
||||
virtual ~TestBridgeSubChild() {}
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual bool RecvPing();
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual PTestBridgeMainSubChild*
|
||||
AllocPTestBridgeMainSub(Transport* transport,
|
||||
ProcessId otherProcess);
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
};
|
||||
|
||||
class TestBridgeMainSubChild :
|
||||
public PTestBridgeMainSubChild
|
||||
{
|
||||
public:
|
||||
TestBridgeMainSubChild(Transport* aTransport)
|
||||
: mGotHi(false)
|
||||
, mTransport(aTransport)
|
||||
{}
|
||||
virtual ~TestBridgeMainSubChild() {}
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual bool RecvHi();
|
||||
NS_OVERRIDE
|
||||
virtual bool AnswerHiRpc();
|
||||
|
||||
NS_OVERRIDE
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
|
||||
bool mGotHi;
|
||||
Transport* mTransport;
|
||||
};
|
||||
|
||||
} // namespace _ipdltest
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
#endif // ifndef mozilla__ipdltest_TestBridgeMain_h
|
@ -1,5 +1,8 @@
|
||||
IPDLSRCS = \
|
||||
PTestBlockChild.ipdl \
|
||||
PTestBridgeMain.ipdl \
|
||||
PTestBridgeSub.ipdl \
|
||||
PTestBridgeMainSub.ipdl \
|
||||
PTestCrashCleanup.ipdl \
|
||||
PTestDataStructures.ipdl \
|
||||
PTestDataStructuresSub.ipdl \
|
||||
|
Loading…
x
Reference in New Issue
Block a user