Ver Fonte

LibCore+LibWebView: Move process statistics to LibCore

This will be needed to collect statistics from processes that do not
have anything to do with LibWebView. The ProcessInfo structure must be
virtual to allow callers to add application-specific information.
Timothy Flynn há 1 ano atrás
pai
commit
5dd3b91f0e

+ 3 - 3
Ladybird/MachPortServer.cpp

@@ -6,7 +6,7 @@
 
 
 #include "MachPortServer.h"
 #include "MachPortServer.h"
 #include <AK/Debug.h>
 #include <AK/Debug.h>
-#include <LibWebView/Platform/ProcessStatisticsMach.h>
+#include <LibCore/Platform/ProcessStatisticsMach.h>
 
 
 namespace Ladybird {
 namespace Ladybird {
 
 
@@ -56,7 +56,7 @@ void MachPortServer::thread_loop()
 {
 {
     while (!m_should_stop.load(MemoryOrder::memory_order_acquire)) {
     while (!m_should_stop.load(MemoryOrder::memory_order_acquire)) {
 
 
-        WebView::ParentPortMessage message {};
+        Core::Platform::ParentPortMessage message {};
 
 
         // Get the pid of the child from the audit trailer so we can associate the port w/it
         // Get the pid of the child from the audit trailer so we can associate the port w/it
         mach_msg_options_t const options = MACH_RCV_MSG | MACH_RCV_TRAILER_TYPE(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT);
         mach_msg_options_t const options = MACH_RCV_MSG | MACH_RCV_TRAILER_TYPE(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT);
@@ -68,7 +68,7 @@ void MachPortServer::thread_loop()
             break;
             break;
         }
         }
 
 
-        if (message.header.msgh_id != WebView::SELF_TASK_PORT_MESSAGE_ID) {
+        if (message.header.msgh_id != Core::Platform::SELF_TASK_PORT_MESSAGE_ID) {
             dbgln("Received message with id {}, ignoring", message.header.msgh_id);
             dbgln("Received message with id {}, ignoring", message.header.msgh_id);
             continue;
             continue;
         }
         }

+ 2 - 2
Ladybird/WebContent/main.cpp

@@ -46,7 +46,7 @@
 #endif
 #endif
 
 
 #if defined(AK_OS_MACOS)
 #if defined(AK_OS_MACOS)
-#    include <LibWebView/Platform/ProcessStatisticsMach.h>
+#    include <LibCore/Platform/ProcessStatisticsMach.h>
 #endif
 #endif
 
 
 static ErrorOr<void> load_content_filters();
 static ErrorOr<void> load_content_filters();
@@ -132,7 +132,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
 
 
 #if defined(AK_OS_MACOS)
 #if defined(AK_OS_MACOS)
     if (!mach_server_name.is_empty()) {
     if (!mach_server_name.is_empty()) {
-        WebView::register_with_mach_server(mach_server_name);
+        Core::Platform::register_with_mach_server(mach_server_name);
     }
     }
 #endif
 #endif
 
 

+ 15 - 0
Meta/gn/secondary/Userland/Libraries/LibCore/BUILD.gn

@@ -72,6 +72,8 @@ source_set("sources") {
     "NetworkResponse.h",
     "NetworkResponse.h",
     "Notifier.cpp",
     "Notifier.cpp",
     "Notifier.h",
     "Notifier.h",
+    "Platform/ProcessInfo.h",
+    "Platform/ProcessStatistics.h",
     "Process.cpp",
     "Process.cpp",
     "Process.h",
     "Process.h",
     "ProcessStatisticsReader.cpp",
     "ProcessStatisticsReader.cpp",
@@ -119,6 +121,19 @@ source_set("sources") {
   if (current_os == "mac") {
   if (current_os == "mac") {
     sources += [ "MachPort.cpp" ]
     sources += [ "MachPort.cpp" ]
   }
   }
+
+  if (current_os == "serenity") {
+    sources += [ "Platform/ProcessStatisticsSerenity.cpp" ]
+  } else if (current_os == "linux") {
+    sources += [ "Platform/ProcessStatisticsLinux.cpp" ]
+  } else if (current_os == "mac") {
+    sources += [
+      "Platform/ProcessStatisticsMach.cpp",
+      "Platform/ProcessStatisticsMach.h",
+    ]
+  } else {
+    sources += [ "Platform/ProcessStatisticsUnimplemented.cpp" ]
+  }
 }
 }
 
 
 source_set("filewatcher") {
 source_set("filewatcher") {

+ 1 - 10
Meta/gn/secondary/Userland/Libraries/LibWebView/BUILD.gn

@@ -146,15 +146,6 @@ shared_library("LibWebView") {
   }
   }
 
 
   if (current_os == "serenity") {
   if (current_os == "serenity") {
-    sources += [
-      "OutOfProcessWebView.cpp",
-      "Platform/ProcessStatisticsSerenity.cpp",
-    ]
-  } else if (current_os == "linux") {
-    sources += [ "Platform/ProcessStatisticsLinux.cpp" ]
-  } else if (current_os == "mac") {
-    sources += [ "Platform/ProcessStatisticsMach.cpp" ]
-  } else {
-    sources += [ "Platform/ProcessStatisticsNoop.cpp" ]
+    sources += [ "OutOfProcessWebView.cpp" ]
   }
   }
 }
 }

+ 16 - 4
Userland/Libraries/LibCore/CMakeLists.txt

@@ -60,13 +60,25 @@ endif()
 
 
 # FIXME: Implement Core::FileWatcher for *BSD and Windows.
 # FIXME: Implement Core::FileWatcher for *BSD and Windows.
 if (SERENITYOS)
 if (SERENITYOS)
-    list(APPEND SOURCES FileWatcherSerenity.cpp)
+    list(APPEND SOURCES
+        FileWatcherSerenity.cpp
+        Platform/ProcessStatisticsSerenity.cpp
+    )
 elseif (LINUX AND NOT EMSCRIPTEN)
 elseif (LINUX AND NOT EMSCRIPTEN)
-    list(APPEND SOURCES FileWatcherLinux.cpp)
+    list(APPEND SOURCES
+        FileWatcherLinux.cpp
+        Platform/ProcessStatisticsLinux.cpp
+    )
 elseif (APPLE AND NOT IOS)
 elseif (APPLE AND NOT IOS)
-    list(APPEND SOURCES FileWatcherMacOS.mm)
+    list(APPEND SOURCES
+        FileWatcherMacOS.mm
+        Platform/ProcessStatisticsMach.cpp
+    )
 else()
 else()
-    list(APPEND SOURCES FileWatcherUnimplemented.cpp)
+    list(APPEND SOURCES
+        FileWatcherUnimplemented.cpp
+        Platform/ProcessStatisticsUnimplemented.cpp
+    )
 endif()
 endif()
 
 
 if (APPLE OR CMAKE_SYSTEM_NAME STREQUAL "GNU")
 if (APPLE OR CMAKE_SYSTEM_NAME STREQUAL "GNU")

+ 12 - 20
Userland/Libraries/LibWebView/Platform/ProcessInfo.h → Userland/Libraries/LibCore/Platform/ProcessInfo.h

@@ -12,39 +12,31 @@
 #    include <LibCore/MachPort.h>
 #    include <LibCore/MachPort.h>
 #endif
 #endif
 
 
-namespace WebView {
-
-enum class ProcessType {
-    Chrome,
-    WebContent,
-    WebWorker,
-    SQLServer,
-    RequestServer,
-    ImageDecoder,
-};
+namespace Core::Platform {
 
 
 struct ProcessInfo {
 struct ProcessInfo {
-    ProcessInfo(ProcessType type, pid_t pid)
-        : type(type)
-        , pid(pid)
+    explicit ProcessInfo(pid_t pid)
+        : pid(pid)
     {
     {
     }
     }
 
 
-    ProcessType type = ProcessType::WebContent;
-    pid_t pid;
-    u64 memory_usage_bytes = 0;
-    float cpu_percent = 0.0f;
+    virtual ~ProcessInfo() = default;
 
 
-    u64 time_spent_in_process = 0;
+    pid_t pid { 0 };
 
 
-#if defined(AK_OS_MACH)
-    Core::MachPort child_task_port;
+    u64 memory_usage_bytes { 0 };
+    float cpu_percent { 0.0f };
 
 
+    u64 time_spent_in_process { 0 };
+
+#if defined(AK_OS_MACH)
     ProcessInfo(pid_t pid, Core::MachPort&& port)
     ProcessInfo(pid_t pid, Core::MachPort&& port)
         : pid(pid)
         : pid(pid)
         , child_task_port(move(port))
         , child_task_port(move(port))
     {
     {
     }
     }
+
+    Core::MachPort child_task_port;
 #endif
 #endif
 };
 };
 
 

+ 31 - 0
Userland/Libraries/LibCore/Platform/ProcessStatistics.h

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Error.h>
+#include <AK/NonnullOwnPtr.h>
+#include <AK/TypeCasts.h>
+#include <AK/Vector.h>
+#include <LibCore/Platform/ProcessInfo.h>
+
+namespace Core::Platform {
+
+struct ProcessStatistics {
+    template<typename ProcessInfoType, typename Callback>
+    void for_each_process(Callback&& callback)
+    {
+        for (auto& process : processes)
+            callback(verify_cast<ProcessInfoType>(*process));
+    }
+
+    u64 total_time_scheduled { 0 };
+    Vector<NonnullOwnPtr<ProcessInfo>> processes;
+};
+
+ErrorOr<void> update_process_statistics(ProcessStatistics&);
+
+}

+ 8 - 8
Userland/Libraries/LibWebView/Platform/ProcessStatisticsLinux.cpp → Userland/Libraries/LibCore/Platform/ProcessStatisticsLinux.cpp

@@ -6,10 +6,10 @@
 
 
 #include <AK/String.h>
 #include <AK/String.h>
 #include <LibCore/File.h>
 #include <LibCore/File.h>
-#include <LibWebView/Platform/ProcessStatistics.h>
+#include <LibCore/Platform/ProcessStatistics.h>
 #include <unistd.h>
 #include <unistd.h>
 
 
-namespace WebView {
+namespace Core::Platform {
 
 
 static auto user_hz = sysconf(_SC_CLK_TCK);
 static auto user_hz = sysconf(_SC_CLK_TCK);
 static auto page_size = sysconf(_SC_PAGESIZE);
 static auto page_size = sysconf(_SC_PAGESIZE);
@@ -43,7 +43,7 @@ ErrorOr<void> update_process_statistics(ProcessStatistics& statistics)
     statistics.total_time_scheduled = total_time_scheduled;
     statistics.total_time_scheduled = total_time_scheduled;
 
 
     for (auto& process : statistics.processes) {
     for (auto& process : statistics.processes) {
-        auto proc_pid_stat_or_error = Core::File::open(MUST(String::formatted("/proc/{}/stat", process.pid)), Core::File::OpenMode::Read);
+        auto proc_pid_stat_or_error = Core::File::open(MUST(String::formatted("/proc/{}/stat", process->pid)), Core::File::OpenMode::Read);
         if (proc_pid_stat_or_error.is_error()) {
         if (proc_pid_stat_or_error.is_error()) {
             // FIXME: Remove stale process from process list?
             // FIXME: Remove stale process from process list?
             continue;
             continue;
@@ -60,15 +60,15 @@ ErrorOr<void> update_process_statistics(ProcessStatistics& statistics)
         if (res != 3)
         if (res != 3)
             return Error::from_string_literal("Failed to parse /proc/pid/stat");
             return Error::from_string_literal("Failed to parse /proc/pid/stat");
 
 
-        process.memory_usage_bytes = rss * page_size;
+        process->memory_usage_bytes = rss * page_size;
 
 
         u64 const time_process = utime + stime;
         u64 const time_process = utime + stime;
-        float const time_scheduled_diff = time_process - process.time_spent_in_process;
-        process.time_spent_in_process = time_process;
+        float const time_scheduled_diff = time_process - process->time_spent_in_process;
+        process->time_spent_in_process = time_process;
 
 
-        process.cpu_percent = 0.0;
+        process->cpu_percent = 0.0;
         if (total_time_scheduled_diff > 0) {
         if (total_time_scheduled_diff > 0) {
-            process.cpu_percent = time_scheduled_diff / (total_time_scheduled_diff / ncpu_online) * 100.0f;
+            process->cpu_percent = time_scheduled_diff / (total_time_scheduled_diff / ncpu_online) * 100.0f;
         }
         }
     }
     }
 
 

+ 11 - 11
Userland/Libraries/LibWebView/Platform/ProcessStatisticsMach.cpp → Userland/Libraries/LibCore/Platform/ProcessStatisticsMach.cpp

@@ -13,9 +13,9 @@
 #include <AK/ByteString.h>
 #include <AK/ByteString.h>
 #include <AK/Time.h>
 #include <AK/Time.h>
 #include <LibCore/MachPort.h>
 #include <LibCore/MachPort.h>
-#include <LibWebView/Platform/ProcessStatisticsMach.h>
+#include <LibCore/Platform/ProcessStatisticsMach.h>
 
 
-namespace WebView {
+namespace Core::Platform {
 
 
 static auto user_hz = sysconf(_SC_CLK_TCK);
 static auto user_hz = sysconf(_SC_CLK_TCK);
 
 
@@ -43,19 +43,19 @@ ErrorOr<void> update_process_statistics(ProcessStatistics& statistics)
     for (auto& process : statistics.processes) {
     for (auto& process : statistics.processes) {
         mach_task_basic_info_data_t basic_info {};
         mach_task_basic_info_data_t basic_info {};
         count = MACH_TASK_BASIC_INFO_COUNT;
         count = MACH_TASK_BASIC_INFO_COUNT;
-        res = task_info(process.child_task_port.port(), MACH_TASK_BASIC_INFO, reinterpret_cast<task_info_t>(&basic_info), &count);
+        res = task_info(process->child_task_port.port(), MACH_TASK_BASIC_INFO, reinterpret_cast<task_info_t>(&basic_info), &count);
         if (res != KERN_SUCCESS) {
         if (res != KERN_SUCCESS) {
-            dbgln("Failed to get task info for pid {}: {}", process.pid, mach_error_string(res));
+            dbgln("Failed to get task info for pid {}: {}", process->pid, mach_error_string(res));
             return Core::mach_error_to_error(res);
             return Core::mach_error_to_error(res);
         }
         }
 
 
-        process.memory_usage_bytes = basic_info.resident_size;
+        process->memory_usage_bytes = basic_info.resident_size;
 
 
         task_thread_times_info_data_t time_info {};
         task_thread_times_info_data_t time_info {};
         count = TASK_THREAD_TIMES_INFO_COUNT;
         count = TASK_THREAD_TIMES_INFO_COUNT;
-        res = task_info(process.child_task_port.port(), TASK_THREAD_TIMES_INFO, reinterpret_cast<task_info_t>(&time_info), &count);
+        res = task_info(process->child_task_port.port(), TASK_THREAD_TIMES_INFO, reinterpret_cast<task_info_t>(&time_info), &count);
         if (res != KERN_SUCCESS) {
         if (res != KERN_SUCCESS) {
-            dbgln("Failed to get thread times info for pid {}: {}", process.pid, mach_error_string(res));
+            dbgln("Failed to get thread times info for pid {}: {}", process->pid, mach_error_string(res));
             return Core::mach_error_to_error(res);
             return Core::mach_error_to_error(res);
         }
         }
 
 
@@ -64,12 +64,12 @@ ErrorOr<void> update_process_statistics(ProcessStatistics& statistics)
         scratch_timeval = { static_cast<time_t>(time_info.system_time.seconds), static_cast<suseconds_t>(time_info.system_time.microseconds) };
         scratch_timeval = { static_cast<time_t>(time_info.system_time.seconds), static_cast<suseconds_t>(time_info.system_time.microseconds) };
         time_in_process += Duration::from_timeval(scratch_timeval);
         time_in_process += Duration::from_timeval(scratch_timeval);
 
 
-        auto time_diff_process = time_in_process - Duration::from_microseconds(process.time_spent_in_process);
-        process.time_spent_in_process = time_in_process.to_microseconds();
+        auto time_diff_process = time_in_process - Duration::from_microseconds(process->time_spent_in_process);
+        process->time_spent_in_process = time_in_process.to_microseconds();
 
 
-        process.cpu_percent = 0.0f;
+        process->cpu_percent = 0.0f;
         if (time_diff_process > Duration::zero())
         if (time_diff_process > Duration::zero())
-            process.cpu_percent = 100.0f * static_cast<float>(time_diff_process.to_microseconds()) / total_cpu_micro_diff;
+            process->cpu_percent = 100.0f * static_cast<float>(time_diff_process.to_microseconds()) / total_cpu_micro_diff;
     }
     }
 
 
     return {};
     return {};

+ 2 - 2
Userland/Libraries/LibWebView/Platform/ProcessStatisticsMach.h → Userland/Libraries/LibCore/Platform/ProcessStatisticsMach.h

@@ -12,10 +12,10 @@
 #    error "This file is only available on Mach platforms"
 #    error "This file is only available on Mach platforms"
 #endif
 #endif
 
 
-#include <LibWebView/Platform/ProcessStatistics.h>
+#include <LibCore/Platform/ProcessStatistics.h>
 #include <mach/mach.h>
 #include <mach/mach.h>
 
 
-namespace WebView {
+namespace Core::Platform {
 
 
 struct ChildPortMessage {
 struct ChildPortMessage {
     mach_msg_header_t header;
     mach_msg_header_t header;

+ 11 - 12
Userland/Libraries/LibWebView/Platform/ProcessStatisticsSerenity.cpp → Userland/Libraries/LibCore/Platform/ProcessStatisticsSerenity.cpp

@@ -11,11 +11,10 @@
 #endif
 #endif
 
 
 #include <LibCore/File.h>
 #include <LibCore/File.h>
+#include <LibCore/Platform/ProcessStatistics.h>
 #include <LibCore/ProcessStatisticsReader.h>
 #include <LibCore/ProcessStatisticsReader.h>
-#include <LibWebView/Platform/ProcessInfo.h>
-#include <LibWebView/Platform/ProcessStatistics.h>
 
 
-namespace WebView {
+namespace Core::Platform {
 
 
 ErrorOr<void> update_process_statistics(ProcessStatistics& statistics)
 ErrorOr<void> update_process_statistics(ProcessStatistics& statistics)
 {
 {
@@ -28,25 +27,25 @@ ErrorOr<void> update_process_statistics(ProcessStatistics& statistics)
     statistics.total_time_scheduled = total_time_scheduled;
     statistics.total_time_scheduled = total_time_scheduled;
 
 
     for (auto& process : statistics.processes) {
     for (auto& process : statistics.processes) {
-        auto it = all_processes.processes.find_if([&](auto& entry) { return entry.pid == process.pid; });
+        auto it = all_processes.processes.find_if([&](auto& entry) { return entry.pid == process->pid; });
         if (!it.is_end()) {
         if (!it.is_end()) {
-            process.memory_usage_bytes = it->amount_resident;
+            process->memory_usage_bytes = it->amount_resident;
 
 
             u64 time_process = 0;
             u64 time_process = 0;
             for (auto& thread : it->threads) {
             for (auto& thread : it->threads) {
                 time_process += thread.time_user + thread.time_kernel;
                 time_process += thread.time_user + thread.time_kernel;
             }
             }
-            u64 time_scheduled_diff = time_process - process.time_spent_in_process;
+            u64 time_scheduled_diff = time_process - process->time_spent_in_process;
 
 
-            process.time_spent_in_process = time_process;
-            process.cpu_percent = 0.0;
+            process->time_spent_in_process = time_process;
+            process->cpu_percent = 0.0;
             if (total_time_scheduled_diff > 0) {
             if (total_time_scheduled_diff > 0) {
-                process.cpu_percent = static_cast<float>((time_scheduled_diff * 1000) / total_time_scheduled_diff) / 10.0f;
+                process->cpu_percent = static_cast<float>((time_scheduled_diff * 1000) / total_time_scheduled_diff) / 10.0f;
             }
             }
         } else {
         } else {
-            process.memory_usage_bytes = 0;
-            process.cpu_percent = 0.0;
-            process.time_spent_in_process = 0;
+            process->memory_usage_bytes = 0;
+            process->cpu_percent = 0.0;
+            process->time_spent_in_process = 0;
         }
         }
     }
     }
 
 

+ 2 - 2
Userland/Libraries/LibWebView/Platform/ProcessStatisticsNoop.cpp → Userland/Libraries/LibCore/Platform/ProcessStatisticsUnimplemented.cpp

@@ -4,9 +4,9 @@
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
 
 
-#include <LibWebView/Platform/ProcessStatistics.h>
+#include <LibCore/Platform/ProcessStatistics.h>
 
 
-namespace WebView {
+namespace Core::Platform {
 
 
 ErrorOr<void> update_process_statistics(ProcessStatistics&)
 ErrorOr<void> update_process_statistics(ProcessStatistics&)
 {
 {

+ 1 - 16
Userland/Libraries/LibWebView/CMakeLists.txt

@@ -21,22 +21,7 @@ set(SOURCES
 set(GENERATED_SOURCES ${CURRENT_LIB_GENERATED})
 set(GENERATED_SOURCES ${CURRENT_LIB_GENERATED})
 
 
 if (SERENITYOS)
 if (SERENITYOS)
-    list(APPEND SOURCES
-        OutOfProcessWebView.cpp
-        Platform/ProcessStatisticsSerenity.cpp
-    )
-elseif(LINUX AND NOT ANDROID)
-    list(APPEND SOURCES
-        Platform/ProcessStatisticsLinux.cpp
-    )
-elseif(APPLE)
-    list(APPEND SOURCES
-        Platform/ProcessStatisticsMach.cpp
-    )
-else()
-    list(APPEND SOURCES
-        Platform/ProcessStatisticsNoop.cpp
-    )
+    list(APPEND SOURCES OutOfProcessWebView.cpp)
 endif()
 endif()
 
 
 embed_as_string_view(
 embed_as_string_view(

+ 0 - 22
Userland/Libraries/LibWebView/Platform/ProcessStatistics.h

@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include <AK/Error.h>
-#include <AK/Vector.h>
-#include <LibWebView/Platform/ProcessInfo.h>
-
-namespace WebView {
-
-struct ProcessStatistics {
-    u64 total_time_scheduled = 0;
-    Vector<ProcessInfo> processes;
-};
-
-ErrorOr<void> update_process_statistics(ProcessStatistics&);
-
-}

+ 39 - 0
Userland/Libraries/LibWebView/ProcessInfo.h

@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Types.h>
+#include <LibCore/Platform/ProcessInfo.h>
+
+#if defined(AK_OS_MACH)
+#    include <LibCore/MachPort.h>
+#endif
+
+namespace WebView {
+
+enum class ProcessType {
+    Chrome,
+    WebContent,
+    WebWorker,
+    SQLServer,
+    RequestServer,
+    ImageDecoder,
+};
+
+struct ProcessInfo : public Core::Platform::ProcessInfo {
+    using Core::Platform::ProcessInfo::ProcessInfo;
+
+    ProcessInfo(ProcessType type, pid_t pid)
+        : Core::Platform::ProcessInfo(pid)
+        , type(type)
+    {
+    }
+
+    ProcessType type { ProcessType::WebContent };
+};
+
+}

+ 18 - 10
Userland/Libraries/LibWebView/ProcessManager.cpp

@@ -88,15 +88,23 @@ void ProcessManager::initialize()
 #endif
 #endif
 }
 }
 
 
+ProcessInfo* ProcessManager::find_process(pid_t pid)
+{
+    if (auto existing_process = m_statistics.processes.find_if([&](auto& info) { return info->pid == pid; }); !existing_process.is_end())
+        return verify_cast<ProcessInfo>(existing_process->ptr());
+
+    return nullptr;
+}
+
 void ProcessManager::add_process(ProcessType type, pid_t pid)
 void ProcessManager::add_process(ProcessType type, pid_t pid)
 {
 {
     Threading::MutexLocker locker { m_lock };
     Threading::MutexLocker locker { m_lock };
     dbgln("ProcessManager::add_process({}, {})", process_name_from_type(type), pid);
     dbgln("ProcessManager::add_process({}, {})", process_name_from_type(type), pid);
-    if (auto existing_process = m_statistics.processes.find_if([&](auto& info) { return info.pid == pid; }); !existing_process.is_end()) {
+    if (auto* existing_process = find_process(pid)) {
         existing_process->type = type;
         existing_process->type = type;
         return;
         return;
     }
     }
-    m_statistics.processes.append({ type, pid });
+    m_statistics.processes.append(make<ProcessInfo>(type, pid));
 }
 }
 
 
 #if defined(AK_OS_MACH)
 #if defined(AK_OS_MACH)
@@ -104,20 +112,21 @@ void ProcessManager::add_process(pid_t pid, Core::MachPort&& port)
 {
 {
     Threading::MutexLocker locker { m_lock };
     Threading::MutexLocker locker { m_lock };
     dbgln("ProcessManager::add_process({}, {:p})", pid, port.port());
     dbgln("ProcessManager::add_process({}, {:p})", pid, port.port());
-    if (auto existing_process = m_statistics.processes.find_if([&](auto& info) { return info.pid == pid; }); !existing_process.is_end()) {
+    if (auto* existing_process = find_process(pid)) {
         existing_process->child_task_port = move(port);
         existing_process->child_task_port = move(port);
         return;
         return;
     }
     }
-    m_statistics.processes.append({ pid, move(port) });
+    m_statistics.processes.append(make<ProcessInfo>(pid, move(port)));
 }
 }
 #endif
 #endif
 
 
 void ProcessManager::remove_process(pid_t pid)
 void ProcessManager::remove_process(pid_t pid)
 {
 {
     Threading::MutexLocker locker { m_lock };
     Threading::MutexLocker locker { m_lock };
-    m_statistics.processes.remove_first_matching([&](auto& info) {
-        if (info.pid == pid) {
-            dbgln("ProcessManager: Remove process {} ({})", process_name_from_type(info.type), pid);
+    m_statistics.processes.remove_first_matching([&](auto const& info) {
+        if (info->pid == pid) {
+            auto type = verify_cast<ProcessInfo>(*info).type;
+            dbgln("ProcessManager: Remove process {} ({})", process_name_from_type(type), pid);
             return true;
             return true;
         }
         }
         return false;
         return false;
@@ -146,7 +155,6 @@ String ProcessManager::generate_html()
 {
 {
     Threading::MutexLocker locker { m_lock };
     Threading::MutexLocker locker { m_lock };
     StringBuilder builder;
     StringBuilder builder;
-    auto const& processes = m_statistics.processes;
 
 
     builder.append(R"(
     builder.append(R"(
         <html>
         <html>
@@ -197,7 +205,7 @@ String ProcessManager::generate_html()
                 <tbody>
                 <tbody>
     )"sv);
     )"sv);
 
 
-    for (auto const& process : processes) {
+    m_statistics.for_each_process<ProcessInfo>([&](auto const& process) {
         builder.append("<tr>"sv);
         builder.append("<tr>"sv);
         builder.append("<td>"sv);
         builder.append("<td>"sv);
         builder.append(WebView::process_name_from_type(process.type));
         builder.append(WebView::process_name_from_type(process.type));
@@ -212,7 +220,7 @@ String ProcessManager::generate_html()
         builder.append(MUST(String::formatted("{:.1f}", process.cpu_percent)));
         builder.append(MUST(String::formatted("{:.1f}", process.cpu_percent)));
         builder.append("</td>"sv);
         builder.append("</td>"sv);
         builder.append("</tr>"sv);
         builder.append("</tr>"sv);
-    }
+    });
 
 
     builder.append(R"(
     builder.append(R"(
                 </tbody>
                 </tbody>

+ 4 - 4
Userland/Libraries/LibWebView/ProcessManager.h

@@ -9,9 +9,10 @@
 #include <AK/Types.h>
 #include <AK/Types.h>
 #include <AK/Vector.h>
 #include <AK/Vector.h>
 #include <LibCore/EventReceiver.h>
 #include <LibCore/EventReceiver.h>
+#include <LibCore/Platform/ProcessStatistics.h>
 #include <LibThreading/Mutex.h>
 #include <LibThreading/Mutex.h>
 #include <LibWebView/Forward.h>
 #include <LibWebView/Forward.h>
-#include <LibWebView/Platform/ProcessStatistics.h>
+#include <LibWebView/ProcessInfo.h>
 
 
 namespace WebView {
 namespace WebView {
 
 
@@ -25,21 +26,20 @@ public:
 
 
     void add_process(WebView::ProcessType, pid_t);
     void add_process(WebView::ProcessType, pid_t);
     void remove_process(pid_t);
     void remove_process(pid_t);
+    ProcessInfo* find_process(pid_t);
 
 
 #if defined(AK_OS_MACH)
 #if defined(AK_OS_MACH)
     void add_process(pid_t, Core::MachPort&&);
     void add_process(pid_t, Core::MachPort&&);
 #endif
 #endif
 
 
     void update_all_processes();
     void update_all_processes();
-    Vector<ProcessInfo> const& processes() const { return m_statistics.processes; }
-
     String generate_html();
     String generate_html();
 
 
 private:
 private:
     ProcessManager();
     ProcessManager();
     ~ProcessManager();
     ~ProcessManager();
 
 
-    ProcessStatistics m_statistics;
+    Core::Platform::ProcessStatistics m_statistics;
     Threading::Mutex m_lock;
     Threading::Mutex m_lock;
 };
 };