gecko-dev/ipc/glue/IPCStreamParent.cpp
Jan Varga 1cb8d244c7 Bug 1351488 - Simplify IPCStreamSource::DoRead() and remove reallocation of the buffer (r=asuth)
MozReview-Commit-ID: 90mZpD1YqpV

--HG--
extra : rebase_source : 4a46872e1a89cabd43576b9437a93912185af4f5
2017-08-29 10:42:33 -05:00

227 lines
4.8 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "IPCStreamDestination.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/ipc/PBackgroundParent.h"
#include "mozilla/ipc/PChildToParentStreamParent.h"
#include "mozilla/ipc/PParentToChildStreamParent.h"
#include "mozilla/Unused.h"
namespace mozilla {
namespace ipc {
// Child to Parent implementation
// ----------------------------------------------------------------------------
namespace {
class IPCStreamSourceParent final : public PParentToChildStreamParent
, public IPCStreamSource
{
public:
static IPCStreamSourceParent*
Create(nsIAsyncInputStream* aInputStream)
{
MOZ_ASSERT(aInputStream);
IPCStreamSourceParent* source = new IPCStreamSourceParent(aInputStream);
if (!source->Initialize()) {
delete source;
return nullptr;
}
return source;
}
// PParentToChildStreamParent methods
void
ActorDestroy(ActorDestroyReason aReason) override
{
ActorDestroyed();
}
IPCResult
RecvStartReading() override
{
Start();
return IPC_OK();
}
IPCResult
RecvRequestClose(const nsresult& aRv) override
{
OnEnd(aRv);
return IPC_OK();
}
void
Close(nsresult aRv) override
{
MOZ_ASSERT(IPCStreamSource::mState == IPCStreamSource::eClosed);
Unused << SendClose(aRv);
}
void
SendData(const wr::ByteBuffer& aBuffer) override
{
Unused << SendBuffer(aBuffer);
}
private:
explicit IPCStreamSourceParent(nsIAsyncInputStream* aInputStream)
:IPCStreamSource(aInputStream)
{}
};
} // anonymous namespace
/* static */ PParentToChildStreamParent*
IPCStreamSource::Create(nsIAsyncInputStream* aInputStream,
dom::nsIContentParent* aManager)
{
MOZ_ASSERT(aInputStream);
MOZ_ASSERT(aManager);
// PContent can only be used on the main thread
MOZ_ASSERT(NS_IsMainThread());
IPCStreamSourceParent* source = IPCStreamSourceParent::Create(aInputStream);
if (!source) {
return nullptr;
}
if (!aManager->SendPParentToChildStreamConstructor(source)) {
// no delete here, the manager will delete the actor for us.
return nullptr;
}
source->ActorConstructed();
return source;
}
/* static */ PParentToChildStreamParent*
IPCStreamSource::Create(nsIAsyncInputStream* aInputStream,
PBackgroundParent* aManager)
{
MOZ_ASSERT(aInputStream);
MOZ_ASSERT(aManager);
IPCStreamSourceParent* source = IPCStreamSourceParent::Create(aInputStream);
if (!source) {
return nullptr;
}
if (!aManager->SendPParentToChildStreamConstructor(source)) {
// no delete here, the manager will delete the actor for us.
return nullptr;
}
source->ActorConstructed();
return source;
}
/* static */ IPCStreamSource*
IPCStreamSource::Cast(PParentToChildStreamParent* aActor)
{
MOZ_ASSERT(aActor);
return static_cast<IPCStreamSourceParent*>(aActor);
}
// Child to Parent implementation
// ----------------------------------------------------------------------------
namespace {
class IPCStreamDestinationParent final : public PChildToParentStreamParent
, public IPCStreamDestination
{
public:
nsresult Initialize()
{
return IPCStreamDestination::Initialize();
}
~IPCStreamDestinationParent()
{}
private:
// PChildToParentStreamParent methods
void
ActorDestroy(ActorDestroyReason aReason) override
{
ActorDestroyed();
}
IPCResult
RecvBuffer(const wr::ByteBuffer& aBuffer) override
{
BufferReceived(aBuffer);
return IPC_OK();
}
IPCResult
RecvClose(const nsresult& aRv) override
{
CloseReceived(aRv);
return IPC_OK();
}
// IPCStreamDestination methods
void
StartReading() override
{
MOZ_ASSERT(HasDelayedStart());
Unused << SendStartReading();
}
void
RequestClose(nsresult aRv) override
{
Unused << SendRequestClose(aRv);
}
void
TerminateDestination() override
{
Unused << Send__delete__(this);
}
};
} // anonymous namespace
PChildToParentStreamParent*
AllocPChildToParentStreamParent()
{
IPCStreamDestinationParent* actor = new IPCStreamDestinationParent();
if (NS_WARN_IF(NS_FAILED(actor->Initialize()))) {
delete actor;
actor = nullptr;
}
return actor;
}
void
DeallocPChildToParentStreamParent(PChildToParentStreamParent* aActor)
{
delete aActor;
}
/* static */ IPCStreamDestination*
IPCStreamDestination::Cast(PChildToParentStreamParent* aActor)
{
MOZ_ASSERT(aActor);
return static_cast<IPCStreamDestinationParent*>(aActor);
}
} // namespace ipc
} // namespace mozilla