summaryrefslogtreecommitdiffstats
path: root/ipc/ipdl/test/cxx/TestEndpointBridgeMain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/ipdl/test/cxx/TestEndpointBridgeMain.cpp')
-rw-r--r--ipc/ipdl/test/cxx/TestEndpointBridgeMain.cpp226
1 files changed, 226 insertions, 0 deletions
diff --git a/ipc/ipdl/test/cxx/TestEndpointBridgeMain.cpp b/ipc/ipdl/test/cxx/TestEndpointBridgeMain.cpp
new file mode 100644
index 0000000000..4a4366f0ba
--- /dev/null
+++ b/ipc/ipdl/test/cxx/TestEndpointBridgeMain.cpp
@@ -0,0 +1,226 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+
+#include "TestEndpointBridgeMain.h"
+
+#include "base/task.h"
+#include "IPDLUnitTests.h" // fail etc.
+#include "IPDLUnitTestSubprocess.h"
+
+using namespace std;
+
+namespace mozilla {
+namespace _ipdltest {
+
+//-----------------------------------------------------------------------------
+// main process
+void TestEndpointBridgeMainParent::Main() {
+ if (!SendStart()) {
+ fail("sending Start");
+ }
+}
+
+mozilla::ipc::IPCResult TestEndpointBridgeMainParent::RecvBridged(
+ Endpoint<PTestEndpointBridgeMainSubParent>&& endpoint) {
+ TestEndpointBridgeMainSubParent* a = new TestEndpointBridgeMainSubParent();
+ if (!endpoint.Bind(a)) {
+ fail("Bind failed");
+ }
+ return IPC_OK();
+}
+
+void TestEndpointBridgeMainParent::ActorDestroy(ActorDestroyReason why) {
+ if (NormalShutdown != why) {
+ fail("unexpected destruction!");
+ }
+ passed("ok");
+ QuitParent();
+}
+
+mozilla::ipc::IPCResult TestEndpointBridgeMainSubParent::RecvHello() {
+ if (!SendHi()) {
+ return IPC_FAIL_NO_REASON(this);
+ }
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult TestEndpointBridgeMainSubParent::RecvHelloSync() {
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult TestEndpointBridgeMainSubParent::AnswerHelloRpc() {
+ if (!CallHiRpc()) {
+ return IPC_FAIL_NO_REASON(this);
+ }
+ return IPC_OK();
+}
+
+void TestEndpointBridgeMainSubParent::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(
+ do_AddRef(new DeleteTask<TestEndpointBridgeMainSubParent>(this)));
+}
+
+//-----------------------------------------------------------------------------
+// sub process --- child of main
+TestEndpointBridgeMainChild* gEndpointBridgeMainChild;
+
+TestEndpointBridgeMainChild::TestEndpointBridgeMainChild()
+ : mSubprocess(nullptr) {
+ gEndpointBridgeMainChild = this;
+}
+
+mozilla::ipc::IPCResult TestEndpointBridgeMainChild::RecvStart() {
+ vector<string> subsubArgs;
+ subsubArgs.push_back("TestEndpointBridgeSub");
+
+ mSubprocess = new IPDLUnitTestSubprocess();
+ if (!mSubprocess->SyncLaunch(subsubArgs)) {
+ fail("problem launching subprocess");
+ }
+
+ IPC::Channel* transport = mSubprocess->GetChannel();
+ if (!transport) {
+ fail("no transport");
+ }
+
+ TestEndpointBridgeSubParent* bsp = new TestEndpointBridgeSubParent();
+ bsp->Open(transport, base::GetProcId(mSubprocess->GetChildProcessHandle()));
+
+ bsp->Main();
+ return IPC_OK();
+}
+
+void TestEndpointBridgeMainChild::ActorDestroy(ActorDestroyReason why) {
+ if (NormalShutdown != why) {
+ fail("unexpected destruction!");
+ }
+ // NB: this is kosher because QuitChild() joins with the IO thread
+ mSubprocess->Destroy();
+ mSubprocess = nullptr;
+ QuitChild();
+}
+
+void TestEndpointBridgeSubParent::Main() {
+ if (!SendPing()) {
+ fail("sending Ping");
+ }
+}
+
+mozilla::ipc::IPCResult TestEndpointBridgeSubParent::RecvBridgeEm() {
+ Endpoint<PTestEndpointBridgeMainSubParent> parent;
+ Endpoint<PTestEndpointBridgeMainSubChild> child;
+ nsresult rv;
+ rv = PTestEndpointBridgeMainSub::CreateEndpoints(
+ gEndpointBridgeMainChild->OtherPid(), OtherPid(), &parent, &child);
+ if (NS_FAILED(rv)) {
+ fail("opening PTestEndpointOpensOpened");
+ }
+
+ if (!gEndpointBridgeMainChild->SendBridged(std::move(parent))) {
+ fail("SendBridge failed for parent");
+ }
+ if (!SendBridged(std::move(child))) {
+ fail("SendBridge failed for child");
+ }
+
+ return IPC_OK();
+}
+
+void TestEndpointBridgeSubParent::ActorDestroy(ActorDestroyReason why) {
+ if (NormalShutdown != why) {
+ fail("unexpected destruction!");
+ }
+ gEndpointBridgeMainChild->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(
+ do_AddRef(new DeleteTask<TestEndpointBridgeSubParent>(this)));
+}
+
+//-----------------------------------------------------------------------------
+// subsub process --- child of sub
+
+static TestEndpointBridgeSubChild* gBridgeSubChild;
+
+TestEndpointBridgeSubChild::TestEndpointBridgeSubChild() {
+ gBridgeSubChild = this;
+}
+
+mozilla::ipc::IPCResult TestEndpointBridgeSubChild::RecvPing() {
+ if (!SendBridgeEm()) {
+ fail("sending BridgeEm");
+ }
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult TestEndpointBridgeSubChild::RecvBridged(
+ Endpoint<PTestEndpointBridgeMainSubChild>&& endpoint) {
+ TestEndpointBridgeMainSubChild* a = new TestEndpointBridgeMainSubChild();
+
+ if (!endpoint.Bind(a)) {
+ fail("failed to Bind");
+ }
+
+ if (!a->SendHello()) {
+ fail("sending Hello");
+ }
+
+ return IPC_OK();
+}
+
+void TestEndpointBridgeSubChild::ActorDestroy(ActorDestroyReason why) {
+ if (NormalShutdown != why) {
+ fail("unexpected destruction!");
+ }
+ QuitChild();
+}
+
+mozilla::ipc::IPCResult TestEndpointBridgeMainSubChild::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(
+ NewNonOwningRunnableMethod("ipc::IToplevelProtocol::Close", this,
+ &TestEndpointBridgeMainSubChild::Close));
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult TestEndpointBridgeMainSubChild::AnswerHiRpc() {
+ mGotHi = true; // d00d
+ return IPC_OK();
+}
+
+void TestEndpointBridgeMainSubChild::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(
+ do_AddRef(new DeleteTask<TestEndpointBridgeMainSubChild>(this)));
+}
+
+} // namespace _ipdltest
+} // namespace mozilla