mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:27:43 +00:00
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.
This commit is contained in:
parent
1dd14e1324
commit
4c1f414713
2 changed files with 20 additions and 62 deletions
|
@ -11,33 +11,38 @@
|
||||||
#include <LibCore/Directory.h>
|
#include <LibCore/Directory.h>
|
||||||
#include <LibCore/EventLoop.h>
|
#include <LibCore/EventLoop.h>
|
||||||
#include <LibCore/StandardPaths.h>
|
#include <LibCore/StandardPaths.h>
|
||||||
#include <LibCore/Stream.h>
|
#include <LibIPC/MultiServer.h>
|
||||||
#include <LibCore/SystemServerTakeover.h>
|
|
||||||
#include <LibMain/Main.h>
|
#include <LibMain/Main.h>
|
||||||
#include <QSocketNotifier>
|
|
||||||
#include <SQLServer/ConnectionFromClient.h>
|
#include <SQLServer/ConnectionFromClient.h>
|
||||||
|
|
||||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
{
|
{
|
||||||
int sql_server_fd_passing_socket { -1 };
|
DeprecatedString pid_file;
|
||||||
|
|
||||||
Core::ArgsParser args_parser;
|
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);
|
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());
|
auto database_path = DeprecatedString::formatted("{}/Ladybird", Core::StandardPaths::data_directory());
|
||||||
TRY(Core::Directory::create(database_path, Core::Directory::CreateDirectories::Yes));
|
TRY(Core::Directory::create(database_path, Core::Directory::CreateDirectories::Yes));
|
||||||
|
|
||||||
Core::EventLoop loop;
|
Core::EventLoop loop;
|
||||||
|
|
||||||
auto socket = TRY(Core::take_over_socket_from_system_server("SQLServer"sv));
|
auto server = TRY(IPC::MultiServer<SQLServer::ConnectionFromClient>::try_create());
|
||||||
auto client = TRY(SQLServer::ConnectionFromClient::try_create(move(socket), 1));
|
u64 connection_count { 0 };
|
||||||
client->set_fd_passing_socket(TRY(Core::Stream::LocalSocket::adopt_fd(sql_server_fd_passing_socket)));
|
|
||||||
client->set_database_path(move(database_path));
|
server->on_new_client = [&](auto& client) {
|
||||||
client->on_disconnect = [&]() {
|
client.set_database_path(database_path);
|
||||||
loop.quit(0);
|
++connection_count;
|
||||||
|
|
||||||
|
client.on_disconnect = [&]() {
|
||||||
|
if (--connection_count == 0) {
|
||||||
|
MUST(Core::System::unlink(pid_file));
|
||||||
|
loop.quit(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
return loop.exec();
|
return loop.exec();
|
||||||
|
|
|
@ -47,55 +47,6 @@ static ErrorOr<void> handle_attached_debugger()
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<NonnullRefPtr<Browser::Database>> 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<char**>(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<int> serenity_main(Main::Arguments arguments)
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
{
|
{
|
||||||
// NOTE: This is only used for the Core::Socket inside the IPC connections.
|
// NOTE: This is only used for the Core::Socket inside the IPC connections.
|
||||||
|
@ -104,6 +55,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
|
|
||||||
TRY(handle_attached_debugger());
|
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);
|
QApplication app(arguments.argc, arguments.argv);
|
||||||
|
|
||||||
platform_init();
|
platform_init();
|
||||||
|
@ -121,7 +75,6 @@ ErrorOr<int> 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.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);
|
args_parser.parse(arguments);
|
||||||
|
|
||||||
auto database = TRY(create_database());
|
|
||||||
auto cookie_jar = TRY(Browser::CookieJar::create(*database));
|
auto cookie_jar = TRY(Browser::CookieJar::create(*database));
|
||||||
|
|
||||||
BrowserWindow window(cookie_jar, webdriver_fd_passing_socket);
|
BrowserWindow window(cookie_jar, webdriver_fd_passing_socket);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue