Bug 1509930 - Simplify CycleCollectWithLogsChild's lifetime, r=jld

Previously this actor would call `Send__delete__` in its destructor, meaning
that the lifetime of the actor is a bit hard to follow. This changes the actor
to instead use a separate object for XPCOM, and use refcounting universally.
This should also help with the transition to universally refcounted actors.

Differential Revision: https://phabricator.services.mozilla.com/D12955
This commit is contained in:
Nika Layzell 2018-11-23 17:07:41 -05:00
Родитель 69812b8403
Коммит 8098a0e23f
1 изменённых файлов: 100 добавлений и 93 удалений

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

@ -273,14 +273,19 @@ namespace dom {
// IPC sender for remote GC/CC logging.
class CycleCollectWithLogsChild final
: public PCycleCollectWithLogsChild
, public nsICycleCollectorLogSink
{
public:
NS_INLINE_DECL_REFCOUNTING(CycleCollectWithLogsChild)
class Sink final : public nsICycleCollectorLogSink
{
NS_DECL_ISUPPORTS
CycleCollectWithLogsChild(const FileDescriptor& aGCLog,
Sink(CycleCollectWithLogsChild* aActor,
const FileDescriptor& aGCLog,
const FileDescriptor& aCCLog)
{
mActor = aActor;
mGCLog = FileDescriptorToFILE(aGCLog, "w");
mCCLog = FileDescriptorToFILE(aCCLog, "w");
}
@ -300,7 +305,7 @@ public:
MOZ_ASSERT(mGCLog);
fclose(mGCLog);
mGCLog = nullptr;
SendCloseGCLog();
mActor->SendCloseGCLog();
return NS_OK;
}
@ -309,7 +314,7 @@ public:
MOZ_ASSERT(mCCLog);
fclose(mCCLog);
mCCLog = nullptr;
SendCloseCCLog();
mActor->SendCloseCCLog();
return NS_OK;
}
@ -344,7 +349,7 @@ public:
}
private:
~CycleCollectWithLogsChild() override
~Sink()
{
if (mGCLog) {
fclose(mGCLog);
@ -354,9 +359,8 @@ private:
fclose(mCCLog);
mCCLog = nullptr;
}
// The XPCOM refcount drives the IPC lifecycle; see also
// DeallocPCycleCollectWithLogsChild.
Unused << Send__delete__(this);
// The XPCOM refcount drives the IPC lifecycle;
Unused << mActor->Send__delete__(mActor);
}
nsresult UnimplementedProperty()
@ -366,11 +370,16 @@ private:
return NS_ERROR_UNEXPECTED;
}
RefPtr<CycleCollectWithLogsChild> mActor;
FILE* mGCLog;
FILE* mCCLog;
};
NS_IMPL_ISUPPORTS(CycleCollectWithLogsChild, nsICycleCollectorLogSink);
private:
~CycleCollectWithLogsChild() {}
};
NS_IMPL_ISUPPORTS(CycleCollectWithLogsChild::Sink, nsICycleCollectorLogSink);
class AlertObserver
{
@ -1323,9 +1332,7 @@ ContentChild::AllocPCycleCollectWithLogsChild(const bool& aDumpAllTraces,
const FileDescriptor& aGCLog,
const FileDescriptor& aCCLog)
{
auto* actor = new CycleCollectWithLogsChild(aGCLog, aCCLog);
// Return actor with refcount 0, which is safe because it has a non-XPCOM type.
return actor;
return do_AddRef(new CycleCollectWithLogsChild()).take();
}
mozilla::ipc::IPCResult
@ -1334,23 +1341,23 @@ ContentChild::RecvPCycleCollectWithLogsConstructor(PCycleCollectWithLogsChild* a
const FileDescriptor& aGCLog,
const FileDescriptor& aCCLog)
{
// Take a reference here, where the XPCOM type is regained.
RefPtr<CycleCollectWithLogsChild> sink = static_cast<CycleCollectWithLogsChild*>(aActor);
// The sink's destructor is called when the last reference goes away, which
// will cause the actor to be closed down.
auto* actor = static_cast<CycleCollectWithLogsChild*>(aActor);
RefPtr<CycleCollectWithLogsChild::Sink> sink =
new CycleCollectWithLogsChild::Sink(actor, aGCLog, aCCLog);
// Invoke the dumper, which will take a reference to the sink.
nsCOMPtr<nsIMemoryInfoDumper> dumper = do_GetService("@mozilla.org/memory-info-dumper;1");
dumper->DumpGCAndCCLogsToSink(aDumpAllTraces, sink);
// The actor's destructor is called when the last reference goes away...
return IPC_OK();
}
bool
ContentChild::DeallocPCycleCollectWithLogsChild(PCycleCollectWithLogsChild* /* aActor */)
ContentChild::DeallocPCycleCollectWithLogsChild(PCycleCollectWithLogsChild* aActor)
{
// ...so when we get here, there's nothing for us to do.
//
// Also, we're already in ~CycleCollectWithLogsChild (q.v.) at
// this point, so we shouldn't touch the actor in any case.
RefPtr<CycleCollectWithLogsChild> actor =
dont_AddRef(static_cast<CycleCollectWithLogsChild*>(aActor));
return true;
}