Bug 1595578 - Don't release the AutoIPCStream immediately when called from IPDLParamTraits, since we need it to outlive the message currently being serialized. r=baku,kmag

Differential Revision: https://phabricator.services.mozilla.com/D54867

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matt Woodrow 2019-11-28 19:50:43 +00:00
Родитель c413bb265b
Коммит 1f6d417fda
2 изменённых файлов: 22 добавлений и 7 удалений

Просмотреть файл

@ -441,7 +441,8 @@ Maybe<IPCStream>& AutoIPCStream::TakeOptionalValue() {
void IPDLParamTraits<nsIInputStream*>::Write(IPC::Message* aMsg,
IProtocol* aActor,
nsIInputStream* aParam) {
mozilla::ipc::AutoIPCStream autoStream;
auto autoStream = MakeRefPtr<HoldIPCStream>();
bool ok = false;
bool found = false;
@ -453,22 +454,22 @@ void IPDLParamTraits<nsIInputStream*>::Write(IPC::Message* aMsg,
switch (actor->GetProtocolId()) {
case PContentMsgStart:
if (actor->GetSide() == mozilla::ipc::ParentSide) {
ok = autoStream.Serialize(
ok = autoStream->Serialize(
aParam, static_cast<mozilla::dom::ContentParent*>(actor));
} else {
MOZ_RELEASE_ASSERT(actor->GetSide() == mozilla::ipc::ChildSide);
ok = autoStream.Serialize(
ok = autoStream->Serialize(
aParam, static_cast<mozilla::dom::ContentChild*>(actor));
}
found = true;
break;
case PBackgroundMsgStart:
if (actor->GetSide() == mozilla::ipc::ParentSide) {
ok = autoStream.Serialize(
ok = autoStream->Serialize(
aParam, static_cast<mozilla::ipc::PBackgroundParent*>(actor));
} else {
MOZ_RELEASE_ASSERT(actor->GetSide() == mozilla::ipc::ChildSide);
ok = autoStream.Serialize(
ok = autoStream->Serialize(
aParam, static_cast<mozilla::ipc::PBackgroundChild*>(actor));
}
found = true;
@ -487,7 +488,13 @@ void IPDLParamTraits<nsIInputStream*>::Write(IPC::Message* aMsg,
}
MOZ_RELEASE_ASSERT(ok, "Failed to serialize nsIInputStream");
WriteIPDLParam(aMsg, aActor, autoStream.TakeOptionalValue());
WriteIPDLParam(aMsg, aActor, autoStream->TakeOptionalValue());
// Dispatch the autoStream to an async runnable, so that we guarantee it
// outlives this callstack, and doesn't shut down any actors we created
// until after we've finished sending the current message.
NS_ProxyRelease("IPDLParamTraits<nsIInputStream*>::Write::autoStream",
NS_GetCurrentThread(), autoStream.forget(), true);
}
bool IPDLParamTraits<nsIInputStream*>::Read(const IPC::Message* aMsg,

Просмотреть файл

@ -120,7 +120,7 @@ already_AddRefed<nsIInputStream> DeserializeIPCStream(
// with complex ipdl structures. For example, you may want to create an
// array of RAII AutoIPCStream objects or build your own wrapping
// RAII object to handle other actors that need to be cleaned up.
class AutoIPCStream final {
class AutoIPCStream {
public:
// Implicitly create an Maybe<IPCStream> value. Either
// TakeValue() or TakeOptionalValue() can be used.
@ -182,6 +182,14 @@ class AutoIPCStream final {
const bool mDelayedStart;
};
class HoldIPCStream final : public AutoIPCStream {
public:
NS_INLINE_DECL_REFCOUNTING(HoldIPCStream)
private:
~HoldIPCStream() = default;
};
template <>
struct IPDLParamTraits<nsIInputStream*> {
static void Write(IPC::Message* aMsg, IProtocol* aActor,