1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsCodeCoverage.h"
7 #include "mozilla/CodeCoverageHandler.h"
8 #include "mozilla/Unused.h"
9 #include "mozilla/dom/ContentParent.h"
10 #include "mozilla/dom/Promise.h"
12 using mozilla::dom::ContentParent
;
13 using mozilla::dom::Promise
;
15 NS_IMPL_ISUPPORTS(nsCodeCoverage
, nsICodeCoverage
)
17 nsCodeCoverage::nsCodeCoverage() {}
19 nsCodeCoverage::~nsCodeCoverage() {}
21 enum RequestType
{ Flush
};
23 class ProcessCount final
{
24 NS_INLINE_DECL_REFCOUNTING(ProcessCount
);
27 explicit ProcessCount(uint32_t c
) : mCount(c
) {}
28 operator uint32_t() const { return mCount
; }
29 ProcessCount
& operator--() {
41 nsresult
Request(JSContext
* cx
, Promise
** aPromise
, RequestType requestType
) {
42 MOZ_ASSERT(XRE_IsParentProcess());
43 MOZ_ASSERT(NS_IsMainThread());
45 nsIGlobalObject
* global
= xpc::CurrentNativeGlobal(cx
);
46 if (NS_WARN_IF(!global
)) {
47 return NS_ERROR_FAILURE
;
50 mozilla::ErrorResult result
;
51 RefPtr
<Promise
> promise
= Promise::Create(global
, result
);
52 if (NS_WARN_IF(result
.Failed())) {
53 return result
.StealNSResult();
56 uint32_t processCount
= 0;
57 for (auto* cp
: ContentParent::AllProcesses(ContentParent::eLive
)) {
58 mozilla::Unused
<< cp
;
62 if (requestType
== RequestType::Flush
) {
63 mozilla::CodeCoverageHandler::FlushCounters();
66 if (processCount
== 0) {
67 promise
->MaybeResolveWithUndefined();
69 RefPtr
<ProcessCount
> processCountHolder(new ProcessCount(processCount
));
71 auto resolve
= [processCountHolder
, promise
](bool unused
) {
72 if (--(*processCountHolder
) == 0) {
73 promise
->MaybeResolveWithUndefined();
77 auto reject
= [promise
](mozilla::ipc::ResponseRejectReason
&& aReason
) {
78 promise
->MaybeReject(NS_ERROR_FAILURE
);
81 for (auto* cp
: ContentParent::AllProcesses(ContentParent::eLive
)) {
82 if (requestType
== RequestType::Flush
) {
83 cp
->SendFlushCodeCoverageCounters(resolve
, reject
);
88 promise
.forget(aPromise
);
92 } // anonymous namespace
94 NS_IMETHODIMP
nsCodeCoverage::FlushCounters(JSContext
* cx
, Promise
** aPromise
) {
95 return Request(cx
, aPromise
, RequestType::Flush
);