Bug 1673311 [wpt PR 26282] - Fieldset NG: Percentage heights for content elements...
[gecko.git] / widget / ProcInfo.h
blobfb7a77c5c8f75a2eed8e25bf1df646ada660a67b
1 /* -*- Mode: C++; tab-width: 8; 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
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef __mozilla_ProcInfo_h
7 #define __mozilla_ProcInfo_h
9 #include <base/process.h>
10 #include <stdint.h>
11 #include "mozilla/dom/ipc/IdType.h"
12 #include "mozilla/HashTable.h"
13 #include "mozilla/MozPromise.h"
15 namespace mozilla {
17 namespace ipc {
18 class GeckoChildProcessHost;
21 // Process types. When updating this enum, please make sure to update
22 // WebIDLProcType, ChromeUtils::RequestProcInfo and ProcTypeToWebIDL to
23 // mirror the changes.
24 enum class ProcType {
25 // These must match the ones in ContentParent.h, and E10SUtils.jsm
26 Web,
27 WebIsolated,
28 File,
29 Extension,
30 PrivilegedAbout,
31 PrivilegedMozilla,
32 WebLargeAllocation,
33 WebCOOPCOEP,
34 // the rest matches GeckoProcessTypes.h
35 Browser, // Default is named Browser here
36 Plugin,
37 IPDLUnitTest,
38 GMPlugin,
39 GPU,
40 VR,
41 RDD,
42 Socket,
43 RemoteSandboxBroker,
44 #ifdef MOZ_ENABLE_FORKSERVER
45 ForkServer,
46 #endif
47 Preallocated,
48 // Unknown type of process
49 Unknown,
50 Max = Unknown,
53 struct ThreadInfo {
54 // Thread Id.
55 base::ProcessId tid = 0;
56 // Thread name, if any.
57 nsString name;
58 // User time in ns.
59 uint64_t cpuUser = 0;
60 // System time in ns.
61 uint64_t cpuKernel = 0;
64 // Info on a DOM window.
65 struct WindowInfo {
66 explicit WindowInfo()
67 : outerWindowId(0),
68 documentURI(nullptr),
69 documentTitle(u""_ns),
70 isProcessRoot(false),
71 isInProcess(false) {}
72 WindowInfo(uint64_t aOuterWindowId, nsIURI* aDocumentURI,
73 nsAString&& aDocumentTitle, bool aIsProcessRoot, bool aIsInProcess)
74 : outerWindowId(aOuterWindowId),
75 documentURI(aDocumentURI),
76 documentTitle(std::move(aDocumentTitle)),
77 isProcessRoot(aIsProcessRoot),
78 isInProcess(aIsInProcess) {}
80 // Internal window id.
81 const uint64_t outerWindowId;
83 // URI of the document.
84 const nsCOMPtr<nsIURI> documentURI;
86 // Title of the document.
87 const nsString documentTitle;
89 // True if this is the toplevel window of the process.
90 // Note that this may be an iframe from another process.
91 const bool isProcessRoot;
93 const bool isInProcess;
96 struct ProcInfo {
97 // Process Id
98 base::ProcessId pid = 0;
99 // Child Id as defined by Firefox when a child process is created.
100 dom::ContentParentId childId;
101 // Process type
102 ProcType type;
103 // Origin, if any
104 nsCString origin;
105 // Process filename (without the path name).
106 nsString filename;
107 // RSS in bytes.
108 int64_t residentSetSize = 0;
109 // Unshared resident size in bytes.
110 int64_t residentUniqueSize = 0;
111 // User time in ns.
112 uint64_t cpuUser = 0;
113 // System time in ns.
114 uint64_t cpuKernel = 0;
115 // Threads owned by this process.
116 CopyableTArray<ThreadInfo> threads;
117 // DOM windows represented by this process.
118 CopyableTArray<WindowInfo> windows;
121 typedef MozPromise<mozilla::HashMap<base::ProcessId, ProcInfo>, nsresult, true>
122 ProcInfoPromise;
125 * Data we need to request process info (e.g. CPU usage, memory usage)
126 * from the operating system and populate the resulting `ProcInfo`.
128 * Note that this structure contains a mix of:
129 * - low-level handles that we need to request low-level process info
130 * (`aChildTask` on macOS, `aPid` on other platforms); and
131 * - high-level data that we already acquired while looking for
132 * `aPid`/`aChildTask` and that we will need further down the road.
134 struct ProcInfoRequest {
135 ProcInfoRequest(base::ProcessId aPid, ProcType aProcessType,
136 const nsACString& aOrigin, nsTArray<WindowInfo>&& aWindowInfo,
137 uint32_t aChildId = 0
138 #ifdef XP_MACOSX
140 mach_port_t aChildTask = 0
141 #endif // XP_MACOSX
143 : pid(aPid),
144 processType(aProcessType),
145 origin(aOrigin),
146 windowInfo(std::move(aWindowInfo)),
147 childId(aChildId)
148 #ifdef XP_MACOSX
150 childTask(aChildTask)
151 #endif // XP_MACOSX
154 const base::ProcessId pid;
155 const ProcType processType;
156 const nsCString origin;
157 const nsTArray<WindowInfo> windowInfo;
158 // If the process is a child, its child id, otherwise `0`.
159 const int32_t childId;
160 #ifdef XP_MACOSX
161 const mach_port_t childTask;
162 #endif // XP_MACOSX
166 * Batch a request for low-level information on Gecko processes.
168 * # Request
170 * Argument `aRequests` is a list of processes, along with high-level data
171 * we have already obtained on them and that we need to populate the
172 * resulting array of `ProcInfo`.
174 * # Result
176 * This call succeeds (possibly with missing data, see below) unless we
177 * cannot allocate memory.
179 * # Performance
181 * - This call is always executed on a background thread.
182 * - This call does NOT wake up children processes.
183 * - This function is sometimes observably slow to resolve, in particular
184 * under Windows.
186 * # Error-handling and race conditions
188 * Requesting low-level information on a process and its threads is inherently
189 * subject to race conditions. Typically, if a process or a thread is killed
190 * while we're preparing to fetch information, we can easily end up with
191 * system/lib calls that return failures.
193 * For this reason, this API assumes that errors when placing a system/lib call
194 * are likely and normal. When some information cannot be obtained, the API will
195 * simply skip over said information.
197 * Note that due to different choices by OSes, the exact information we skip may
198 * vary across platforms. For instance, under Unix, failing to access the
199 * threads of a process will cause us to skip all data on the process, while
200 * under Windows, process information will be returned without thread
201 * information.
203 RefPtr<ProcInfoPromise> GetProcInfo(nsTArray<ProcInfoRequest>&& aRequests);
206 * Utility function: copy data from a `ProcInfo` and into either a
207 * `ParentProcInfoDictionary` or a `ChildProcInfoDictionary`.
209 template <typename T>
210 nsresult CopySysProcInfoToDOM(const ProcInfo& source, T* dest) {
211 // Copy system info.
212 dest->mPid = source.pid;
213 dest->mFilename.Assign(source.filename);
214 dest->mResidentSetSize = source.residentSetSize;
215 dest->mResidentUniqueSize = source.residentUniqueSize;
216 dest->mCpuUser = source.cpuUser;
217 dest->mCpuKernel = source.cpuKernel;
219 // Copy thread info.
220 mozilla::dom::Sequence<mozilla::dom::ThreadInfoDictionary> threads;
221 for (const ThreadInfo& entry : source.threads) {
222 mozilla::dom::ThreadInfoDictionary* thread =
223 threads.AppendElement(fallible);
224 if (NS_WARN_IF(!thread)) {
225 return NS_ERROR_OUT_OF_MEMORY;
227 thread->mCpuUser = entry.cpuUser;
228 thread->mCpuKernel = entry.cpuKernel;
229 thread->mTid = entry.tid;
230 thread->mName.Assign(entry.name);
232 dest->mThreads = std::move(threads);
233 return NS_OK;
236 } // namespace mozilla
237 #endif // ProcInfo_h