From 4c1f414713819a1fa711207478e5c2b4d83bee3f Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Fri, 9 Dec 2022 17:10:09 -0500 Subject: [PATCH] Ladybird: Migrate SQLServer to be launched as a singleton process Rather than manually launching the SQLServer process, use SQLClient's new functionality to launch the server just once for all Ladybird instances. Quit the SQLServer process when it no longer has any connected clients. --- Ladybird/SQLServer/main.cpp | 29 +++++++++++--------- Ladybird/main.cpp | 53 +++---------------------------------- 2 files changed, 20 insertions(+), 62 deletions(-) diff --git a/Ladybird/SQLServer/main.cpp b/Ladybird/SQLServer/main.cpp index d41cd6fedc..70789c2f84 100644 --- a/Ladybird/SQLServer/main.cpp +++ b/Ladybird/SQLServer/main.cpp @@ -11,33 +11,38 @@ #include #include #include -#include -#include +#include #include -#include #include ErrorOr serenity_main(Main::Arguments arguments) { - int sql_server_fd_passing_socket { -1 }; + DeprecatedString pid_file; Core::ArgsParser args_parser; - args_parser.add_option(sql_server_fd_passing_socket, "File descriptor of the passing socket for the SQLServer connection", "sql-server-fd-passing-socket", 's', "sql_server_fd_passing_socket"); + args_parser.add_option(pid_file, "Path to the PID file for the SQLServer singleton process", "pid-file", 'p', "pid_file"); args_parser.parse(arguments); - VERIFY(sql_server_fd_passing_socket >= 0); + VERIFY(!pid_file.is_empty()); auto database_path = DeprecatedString::formatted("{}/Ladybird", Core::StandardPaths::data_directory()); TRY(Core::Directory::create(database_path, Core::Directory::CreateDirectories::Yes)); Core::EventLoop loop; - auto socket = TRY(Core::take_over_socket_from_system_server("SQLServer"sv)); - auto client = TRY(SQLServer::ConnectionFromClient::try_create(move(socket), 1)); - client->set_fd_passing_socket(TRY(Core::Stream::LocalSocket::adopt_fd(sql_server_fd_passing_socket))); - client->set_database_path(move(database_path)); - client->on_disconnect = [&]() { - loop.quit(0); + auto server = TRY(IPC::MultiServer::try_create()); + u64 connection_count { 0 }; + + server->on_new_client = [&](auto& client) { + client.set_database_path(database_path); + ++connection_count; + + client.on_disconnect = [&]() { + if (--connection_count == 0) { + MUST(Core::System::unlink(pid_file)); + loop.quit(0); + } + }; }; return loop.exec(); diff --git a/Ladybird/main.cpp b/Ladybird/main.cpp index f33f465518..b9d4a09744 100644 --- a/Ladybird/main.cpp +++ b/Ladybird/main.cpp @@ -47,55 +47,6 @@ static ErrorOr handle_attached_debugger() return {}; } -ErrorOr> create_database() -{ - int socket_fds[2] {}; - TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds)); - auto [browser_fd, sql_server_fd] = socket_fds; - - int fd_passing_socket_fds[2] {}; - TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, fd_passing_socket_fds)); - auto [browser_fd_passing_fd, sql_server_fd_passing_fd] = fd_passing_socket_fds; - - auto sql_server_pid = TRY(Core::System::fork()); - - if (sql_server_pid == 0) { - TRY(Core::System::close(browser_fd_passing_fd)); - TRY(Core::System::close(browser_fd)); - - DeprecatedString takeover_string; - if (auto* socket_takeover = getenv("SOCKET_TAKEOVER")) - takeover_string = DeprecatedString::formatted("{} SQLServer:{}", socket_takeover, sql_server_fd); - else - takeover_string = DeprecatedString::formatted("SQLServer:{}", sql_server_fd); - TRY(Core::System::setenv("SOCKET_TAKEOVER"sv, takeover_string, true)); - - auto sql_server_fd_passing_fd_string = DeprecatedString::number(sql_server_fd_passing_fd); - - char const* argv[] = { - "SQLServer", - "--sql-server-fd-passing-socket", - sql_server_fd_passing_fd_string.characters(), - nullptr, - }; - - if (execvp("./SQLServer/SQLServer", const_cast(argv)) < 0) - perror("execvp"); - VERIFY_NOT_REACHED(); - } - - TRY(Core::System::close(sql_server_fd_passing_fd)); - TRY(Core::System::close(sql_server_fd)); - - auto socket = TRY(Core::Stream::LocalSocket::adopt_fd(browser_fd)); - TRY(socket->set_blocking(true)); - - auto sql_client = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SQL::SQLClient(std::move(socket)))); - sql_client->set_fd_passing_socket(TRY(Core::Stream::LocalSocket::adopt_fd(browser_fd_passing_fd))); - - return Browser::Database::create(move(sql_client)); -} - ErrorOr serenity_main(Main::Arguments arguments) { // NOTE: This is only used for the Core::Socket inside the IPC connections. @@ -104,6 +55,9 @@ ErrorOr serenity_main(Main::Arguments arguments) TRY(handle_attached_debugger()); + auto sql_client = TRY(SQL::SQLClient::launch_server_and_create_client("./SQLServer/SQLServer"sv)); + auto database = TRY(Browser::Database::create(move(sql_client))); + QApplication app(arguments.argc, arguments.argv); platform_init(); @@ -121,7 +75,6 @@ ErrorOr serenity_main(Main::Arguments arguments) args_parser.add_option(webdriver_fd_passing_socket, "File descriptor of the passing socket for the WebDriver connection", "webdriver-fd-passing-socket", 'd', "webdriver_fd_passing_socket"); args_parser.parse(arguments); - auto database = TRY(create_database()); auto cookie_jar = TRY(Browser::CookieJar::create(*database)); BrowserWindow window(cookie_jar, webdriver_fd_passing_socket);