ProcessManager.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*
  2. * Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibCore/EventLoop.h>
  7. #include <LibCore/System.h>
  8. #include <LibWebView/ProcessManager.h>
  9. namespace WebView {
  10. static sig_atomic_t s_received_sigchld = 0;
  11. ProcessType process_type_from_name(StringView name)
  12. {
  13. if (name == "Chrome"sv)
  14. return ProcessType::Chrome;
  15. if (name == "WebContent"sv)
  16. return ProcessType::WebContent;
  17. if (name == "WebWorker"sv)
  18. return ProcessType::WebWorker;
  19. if (name == "SQLServer"sv)
  20. return ProcessType::SQLServer;
  21. if (name == "RequestServer"sv)
  22. return ProcessType::RequestServer;
  23. if (name == "ImageDecoder"sv)
  24. return ProcessType::ImageDecoder;
  25. dbgln("Unknown process type: '{}'", name);
  26. VERIFY_NOT_REACHED();
  27. }
  28. StringView process_name_from_type(ProcessType type)
  29. {
  30. switch (type) {
  31. case ProcessType::Chrome:
  32. return "Chrome"sv;
  33. case ProcessType::WebContent:
  34. return "WebContent"sv;
  35. case ProcessType::WebWorker:
  36. return "WebWorker"sv;
  37. case ProcessType::SQLServer:
  38. return "SQLServer"sv;
  39. case ProcessType::RequestServer:
  40. return "RequestServer"sv;
  41. case ProcessType::ImageDecoder:
  42. return "ImageDecoder"sv;
  43. }
  44. VERIFY_NOT_REACHED();
  45. }
  46. ProcessManager::ProcessManager()
  47. {
  48. }
  49. ProcessManager::~ProcessManager()
  50. {
  51. }
  52. ProcessManager& ProcessManager::the()
  53. {
  54. static ProcessManager s_the;
  55. return s_the;
  56. }
  57. void ProcessManager::initialize()
  58. {
  59. // FIXME: Should we change this to call EventLoop::register_signal?
  60. // Note that only EventLoopImplementationUnix has a working register_signal
  61. struct sigaction action { };
  62. action.sa_flags = SA_RESTART;
  63. action.sa_sigaction = [](int, auto*, auto) {
  64. s_received_sigchld = 1;
  65. };
  66. MUST(Core::System::sigaction(SIGCHLD, &action, nullptr));
  67. the().add_process(WebView::ProcessType::Chrome, getpid());
  68. }
  69. void ProcessManager::add_process(ProcessType type, pid_t pid)
  70. {
  71. dbgln("ProcessManager::add_process({}, {})", process_name_from_type(type), pid);
  72. m_processes.append({ type, pid, 0, 0 });
  73. }
  74. void ProcessManager::remove_process(pid_t pid)
  75. {
  76. m_processes.remove_first_matching([&](auto& info) {
  77. if (info.pid == pid) {
  78. dbgln("ProcessManager: Remove process {} ({})", process_name_from_type(info.type), pid);
  79. return true;
  80. }
  81. return false;
  82. });
  83. }
  84. void ProcessManager::update_all_processes()
  85. {
  86. if (s_received_sigchld) {
  87. s_received_sigchld = 0;
  88. auto result = Core::System::waitpid(-1, WNOHANG);
  89. while (!result.is_error() && result.value().pid > 0) {
  90. auto& [pid, status] = result.value();
  91. if (WIFEXITED(status) || WIFSIGNALED(status)) {
  92. remove_process(pid);
  93. }
  94. result = Core::System::waitpid(-1, WNOHANG);
  95. }
  96. }
  97. // FIXME: Actually gather stats in a platform-specific way
  98. }
  99. }