Bug 1517276 - thread callbacks through MemoryReportRequestClient; r=mccr8

The guts of MemoryReportRequestClient's supporting runnables contain
switches on the particular type of process we're running.  If you're
bringing up a new process type, having to add extra cases for your
process type here is a bit onerous.  These runnables really shouldn't
know anything about the process types that they're running on, either.

The easiest thing to do is modify MemoryReportRequestClient::Start to
take callbacks for what to do when a report is created and when
reporting is finished.  Then all process-specific knowledge can be
pushed out to the clients themselves, leaving MemoryReportRequestClient
and friends process-type agnostic.  We could even, at some later date,
move this code into xpcom/base/ to sit near nsMemoryReporterManager,
where it belongs.
This commit is contained in:
Nathan Froyd 2019-01-02 16:18:13 -05:00
parent 4e37f82d83
commit 9acf5a0c63
5 changed files with 64 additions and 50 deletions

View File

@ -1237,7 +1237,13 @@ mozilla::ipc::IPCResult ContentChild::RecvRequestMemoryReport(
AppendProcessId(process);
MemoryReportRequestClient::Start(aGeneration, aAnonymize,
aMinimizeMemoryUsage, aDMDFile, process);
aMinimizeMemoryUsage, aDMDFile, process,
[&](const MemoryReport& aReport) {
Unused << GetSingleton()->SendAddMemoryReport(aReport);
},
[&](const uint32_t& aGeneration) {
return GetSingleton()->SendFinishMemoryReport(aGeneration);
});
return IPC_OK();
}

View File

@ -5,10 +5,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MemoryReportRequest.h"
#include "mozilla/RDDParent.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/gfx/GPUParent.h"
namespace mozilla {
namespace dom {
@ -54,9 +50,12 @@ NS_IMPL_ISUPPORTS(MemoryReportRequestClient, nsIRunnable)
/* static */ void MemoryReportRequestClient::Start(
uint32_t aGeneration, bool aAnonymize, bool aMinimizeMemoryUsage,
const MaybeFileDesc& aDMDFile, const nsACString& aProcessString) {
const MaybeFileDesc& aDMDFile, const nsACString& aProcessString,
const ReportCallback& aReportCallback,
const FinishCallback& aFinishCallback) {
RefPtr<MemoryReportRequestClient> request = new MemoryReportRequestClient(
aGeneration, aAnonymize, aDMDFile, aProcessString);
aGeneration, aAnonymize, aDMDFile, aProcessString,
aReportCallback, aFinishCallback);
DebugOnly<nsresult> rv;
if (aMinimizeMemoryUsage) {
@ -73,10 +72,13 @@ NS_IMPL_ISUPPORTS(MemoryReportRequestClient, nsIRunnable)
MemoryReportRequestClient::MemoryReportRequestClient(
uint32_t aGeneration, bool aAnonymize, const MaybeFileDesc& aDMDFile,
const nsACString& aProcessString)
const nsACString& aProcessString, const ReportCallback& aReportCallback,
const FinishCallback& aFinishCallback)
: mGeneration(aGeneration),
mAnonymize(aAnonymize),
mProcessString(aProcessString) {
mProcessString(aProcessString),
mReportCallback(aReportCallback),
mFinishCallback(aFinishCallback) {
if (aDMDFile.type() == MaybeFileDesc::TFileDescriptor) {
mDMDFile = aDMDFile.get_FileDescriptor();
}
@ -86,11 +88,16 @@ MemoryReportRequestClient::~MemoryReportRequestClient() {}
class HandleReportCallback final : public nsIHandleReportCallback {
public:
using ReportCallback = typename MemoryReportRequestClient::ReportCallback;
NS_DECL_ISUPPORTS
explicit HandleReportCallback(uint32_t aGeneration,
const nsACString& aProcess)
: mGeneration(aGeneration), mProcess(aProcess) {}
const nsACString& aProcess,
const ReportCallback& aReportCallback)
: mGeneration(aGeneration),
mProcess(aProcess),
mReportCallback(aReportCallback) {}
NS_IMETHOD Callback(const nsACString& aProcess, const nsACString& aPath,
int32_t aKind, int32_t aUnits, int64_t aAmount,
@ -98,20 +105,7 @@ class HandleReportCallback final : public nsIHandleReportCallback {
nsISupports* aUnused) override {
MemoryReport memreport(mProcess, nsCString(aPath), aKind, aUnits, aAmount,
mGeneration, nsCString(aDescription));
switch (XRE_GetProcessType()) {
case GeckoProcessType_Content:
ContentChild::GetSingleton()->SendAddMemoryReport(memreport);
break;
case GeckoProcessType_GPU:
Unused << gfx::GPUParent::GetSingleton()->SendAddMemoryReport(
memreport);
break;
case GeckoProcessType_RDD:
Unused << RDDParent::GetSingleton()->SendAddMemoryReport(memreport);
break;
default:
MOZ_ASSERT_UNREACHABLE("Unhandled process type");
}
mReportCallback(memreport);
return NS_OK;
}
@ -120,41 +114,31 @@ class HandleReportCallback final : public nsIHandleReportCallback {
uint32_t mGeneration;
const nsCString mProcess;
ReportCallback mReportCallback;
};
NS_IMPL_ISUPPORTS(HandleReportCallback, nsIHandleReportCallback)
class FinishReportingCallback final : public nsIFinishReportingCallback {
public:
using FinishCallback = typename MemoryReportRequestClient::FinishCallback;
NS_DECL_ISUPPORTS
explicit FinishReportingCallback(uint32_t aGeneration)
: mGeneration(aGeneration) {}
explicit FinishReportingCallback(uint32_t aGeneration,
const FinishCallback& aFinishCallback)
: mGeneration(aGeneration),
mFinishCallback(aFinishCallback) {}
NS_IMETHOD Callback(nsISupports* aUnused) override {
bool sent = false;
switch (XRE_GetProcessType()) {
case GeckoProcessType_Content:
sent =
ContentChild::GetSingleton()->SendFinishMemoryReport(mGeneration);
break;
case GeckoProcessType_GPU:
sent =
gfx::GPUParent::GetSingleton()->SendFinishMemoryReport(mGeneration);
break;
case GeckoProcessType_RDD:
sent = RDDParent::GetSingleton()->SendFinishMemoryReport(mGeneration);
break;
default:
MOZ_ASSERT_UNREACHABLE("Unhandled process type");
}
return sent ? NS_OK : NS_ERROR_FAILURE;
return mFinishCallback(mGeneration) ? NS_OK : NS_ERROR_FAILURE;
}
private:
~FinishReportingCallback() = default;
uint32_t mGeneration;
FinishCallback mFinishCallback;
};
NS_IMPL_ISUPPORTS(FinishReportingCallback, nsIFinishReportingCallback)
@ -166,9 +150,9 @@ NS_IMETHODIMP MemoryReportRequestClient::Run() {
// Run the reporters. The callback will turn each measurement into a
// MemoryReport.
RefPtr<HandleReportCallback> handleReport =
new HandleReportCallback(mGeneration, mProcessString);
new HandleReportCallback(mGeneration, mProcessString, mReportCallback);
RefPtr<FinishReportingCallback> finishReporting =
new FinishReportingCallback(mGeneration);
new FinishReportingCallback(mGeneration, mFinishCallback);
nsresult rv = mgr->GetReportsForThisProcessExtended(
handleReport, nullptr, mAnonymize, FileDescriptorToFILE(mDMDFile, "wb"),

View File

@ -11,12 +11,15 @@
#include "mozilla/ipc/FileDescriptor.h"
#include "nsISupports.h"
#include <functional>
class nsMemoryReporterManager;
namespace mozilla {
namespace dom {
class MaybeFileDesc;
class MemoryReport;
class MemoryReportRequestHost final {
public:
@ -35,18 +38,25 @@ class MemoryReportRequestHost final {
class MemoryReportRequestClient final : public nsIRunnable {
public:
using ReportCallback = std::function<void(const MemoryReport&)>;
using FinishCallback = std::function<bool(const uint32_t&)>;
NS_DECL_ISUPPORTS
static void Start(uint32_t aGeneration, bool aAnonymize,
bool aMinimizeMemoryUsage, const MaybeFileDesc& aDMDFile,
const nsACString& aProcessString);
const nsACString& aProcessString,
const ReportCallback& aReportCallback,
const FinishCallback& aFinishCallback);
NS_IMETHOD Run() override;
private:
MemoryReportRequestClient(uint32_t aGeneration, bool aAnonymize,
const MaybeFileDesc& aDMDFile,
const nsACString& aProcessString);
const nsACString& aProcessString,
const ReportCallback& aReportCallback,
const FinishCallback& aFinishCallback);
private:
~MemoryReportRequestClient();
@ -55,6 +65,8 @@ class MemoryReportRequestClient final : public nsIRunnable {
bool mAnonymize;
mozilla::ipc::FileDescriptor mDMDFile;
nsCString mProcessString;
ReportCallback mReportCallback;
FinishCallback mFinishCallback;
};
} // namespace dom

View File

@ -155,7 +155,13 @@ mozilla::ipc::IPCResult RDDParent::RecvRequestMemoryReport(
nsPrintfCString processName("RDD (pid %u)", (unsigned)getpid());
mozilla::dom::MemoryReportRequestClient::Start(
aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName);
aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName,
[&](const MemoryReport& aReport) {
Unused << GetSingleton()->SendAddMemoryReport(aReport);
},
[&](const uint32_t& aGeneration) {
return GetSingleton()->SendFinishMemoryReport(aGeneration);
});
return IPC_OK();
}

View File

@ -447,7 +447,13 @@ mozilla::ipc::IPCResult GPUParent::RecvRequestMemoryReport(
GetGPUProcessName(processName);
mozilla::dom::MemoryReportRequestClient::Start(
aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName);
aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, processName,
[&](const MemoryReport& aReport) {
Unused << GetSingleton()->SendAddMemoryReport(aReport);
},
[&](const uint32_t& aGeneration) {
return GetSingleton()->SendFinishMemoryReport(aGeneration);
});
return IPC_OK();
}