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 namespace mozilla
;
13 using namespace mozilla::dom
;
14 using namespace mozilla::ipc
;
16 NS_IMPL_ISUPPORTS(nsCodeCoverage
, nsICodeCoverage
)
18 nsCodeCoverage::nsCodeCoverage() {}
20 nsCodeCoverage::~nsCodeCoverage() {}
22 enum RequestType
{ Flush
};
24 class ProcessCount final
{
25 NS_INLINE_DECL_REFCOUNTING(ProcessCount
);
28 explicit ProcessCount(uint32_t c
) : mCount(c
) {}
29 operator uint32_t() const { return mCount
; }
30 ProcessCount
& operator--() {
40 nsresult
Request(JSContext
* cx
, Promise
** aPromise
, RequestType requestType
) {
41 MOZ_ASSERT(XRE_IsParentProcess());
42 MOZ_ASSERT(NS_IsMainThread());
44 nsIGlobalObject
* global
= xpc::CurrentNativeGlobal(cx
);
45 if (NS_WARN_IF(!global
)) {
46 return NS_ERROR_FAILURE
;
50 RefPtr
<Promise
> promise
= Promise::Create(global
, result
);
51 if (NS_WARN_IF(result
.Failed())) {
52 return result
.StealNSResult();
55 uint32_t processCount
= 0;
56 for (auto* cp
: ContentParent::AllProcesses(ContentParent::eLive
)) {
61 if (requestType
== RequestType::Flush
) {
62 CodeCoverageHandler::FlushCounters();
65 if (processCount
== 0) {
66 promise
->MaybeResolveWithUndefined();
68 RefPtr
<ProcessCount
> processCountHolder(new ProcessCount(processCount
));
70 auto resolve
= [processCountHolder
, promise
](bool unused
) {
71 if (--(*processCountHolder
) == 0) {
72 promise
->MaybeResolveWithUndefined();
76 auto reject
= [promise
](ResponseRejectReason
&& aReason
) {
77 promise
->MaybeReject(NS_ERROR_FAILURE
);
80 for (auto* cp
: ContentParent::AllProcesses(ContentParent::eLive
)) {
81 if (requestType
== RequestType::Flush
) {
82 cp
->SendFlushCodeCoverageCounters(resolve
, reject
);
87 promise
.forget(aPromise
);
91 NS_IMETHODIMP
nsCodeCoverage::FlushCounters(JSContext
* cx
, Promise
** aPromise
) {
92 return Request(cx
, aPromise
, RequestType::Flush
);