From ea62e55f1a697a9a9286119de0fc638572ac9d2b Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Tue, 11 Apr 2017 11:17:40 +0200 Subject: [PATCH] Add support for auto shutdown dbus-daemon after last client disconnects on Windows. By default dbus-daemon on Windows is auto started on request by any dbus client application and now also shutdown itself after the last client has been disconnected to free unused system resources and simplifies portable installations. The auto shutting down behavior could be disabled by specifing --disable-auto-shutdown on dbus-daemon command line. https://bugs.freedesktop.org/show_bug.cgi?id=99751 --- bus/bus.c | 13 +++++++++++++ bus/bus.h | 4 +++- bus/connection.c | 23 ++++++++++++++++++++++- bus/main.c | 19 +++++++++++++++++++ dbus/dbus-sysdeps-unix.c | 6 ++++++ dbus/dbus-sysdeps-win.c | 28 +++++++++++++++++++++++++--- dbus/dbus-sysdeps.h | 2 ++ doc/dbus-daemon.1.xml.in | 10 ++++++++++ 8 files changed, 100 insertions(+), 5 deletions(-) diff --git a/bus/bus.c b/bus/bus.c index a6f8db47..2ecb8e28 100644 --- a/bus/bus.c +++ b/bus/bus.c @@ -80,6 +80,7 @@ struct BusContext unsigned int quiet_log : 1; #endif dbus_bool_t watches_enabled; + dbus_bool_t auto_shutdown_enabled; }; static dbus_int32_t server_data_slot = -1; @@ -1913,3 +1914,15 @@ bus_context_get_quiet_log (BusContext *context) return context->quiet_log; } #endif + +dbus_bool_t +bus_context_get_auto_shutdown_enabled (BusContext *context) +{ + return context->auto_shutdown_enabled; +} + +void +bus_context_set_auto_shutdown_enabled (BusContext *context, dbus_bool_t state) +{ + context->auto_shutdown_enabled = state; +} diff --git a/bus/bus.h b/bus/bus.h index 8f96222f..b876e42e 100644 --- a/bus/bus.h +++ b/bus/bus.h @@ -160,7 +160,9 @@ dbus_bool_t bus_context_setup_server (BusContext DBusError *error); dbus_bool_t bus_context_add_incoming_connection (BusContext *context, DBusConnection *new_connection); - +dbus_bool_t bus_context_get_auto_shutdown_enabled (BusContext *context); +void bus_context_set_auto_shutdown_enabled (BusContext *context, + dbus_bool_t state); #ifdef DBUS_ENABLE_EMBEDDED_TESTS void bus_context_quiet_log_begin (BusContext *context); void bus_context_quiet_log_end (BusContext *context); diff --git a/bus/connection.c b/bus/connection.c index 91b1966e..a0fd28fe 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -345,6 +345,27 @@ bus_connection_disconnected (DBusConnection *connection) bus_connection_drop_pending_replies (d->connections, connection); + if (bus_connections_get_n_active (d->connections) + + bus_connections_get_n_incomplete (d->connections) == 0) + { + if (bus_context_get_auto_shutdown_enabled (d->connections->context)) + { + if (_dbus_daemon_lock_autolaunch_address ()) + { + DBusLoop *loop = bus_context_get_loop (d->connections->context); + _dbus_loop_quit (loop); + _dbus_verbose ("Got auto shutdown request - quit event loop\n"); + } + else + { + // We are not able to lock autolaunch address mutex because a + // dbus client tries to fetch autolaunch address as part of the + // autolaunch connection attempt + _dbus_verbose ("Could not lock autolaunch address - skipping shutdown"); + } + } + } + /* frees "d" as side effect */ dbus_connection_set_data (connection, connection_data_slot, @@ -1606,7 +1627,7 @@ bus_connection_complete (DBusConnection *connection, d->name = NULL; return FALSE; } - + if (dbus_connection_get_unix_user (connection, &uid)) { if (!adjust_connections_for_uid (d->connections, diff --git a/bus/main.c b/bus/main.c index b3fcddd0..e5075231 100644 --- a/bus/main.c +++ b/bus/main.c @@ -163,6 +163,9 @@ usage (void) " [--syslog]" " [--syslog-only]" " [--nofork]" +#ifdef DBUS_WIN + " [--disable-auto-shutdown]" +#endif #ifdef DBUS_UNIX " [--fork]" " [--systemd-activation]" @@ -401,6 +404,9 @@ main (int argc, char **argv) int i; dbus_bool_t print_address; dbus_bool_t print_pid; +#ifdef DBUS_WIN + dbus_bool_t auto_shutdown; +#endif BusContextFlags flags; #ifdef DBUS_UNIX const char *error_str; @@ -438,6 +444,9 @@ main (int argc, char **argv) print_address = FALSE; print_pid = FALSE; +#ifdef DBUS_WIN + auto_shutdown = TRUE; +#endif flags = BUS_CONTEXT_FLAG_WRITE_PID_FILE; @@ -614,6 +623,12 @@ main (int argc, char **argv) { print_pid = TRUE; /* and we'll get the next arg if appropriate */ } +#ifdef DBUS_WIW + else if (strcmp (arg, "--disable-auto-shutdown") == 0) + { + auto_shutdown = FALSE; + } +#endif else { usage (); @@ -700,6 +715,10 @@ main (int argc, char **argv) exit (1); } +#ifdef DBUS_WIN + if (auto_shutdown) + bus_context_set_auto_shutdown_enabled (context, TRUE); +#endif /* bus_context_new() closes the print_addr_pipe and * print_pid_pipe */ diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 9f859845..ff814256 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -4296,6 +4296,12 @@ _dbus_daemon_publish_session_bus_address (const char* addr, return TRUE; } +dbus_bool_t +_dbus_daemon_lock_autolaunch_address () +{ + return FALSE; +} + //PENDING(kdab) docs void _dbus_daemon_unpublish_session_bus_address (void) diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 4e71d1cf..29eb50e1 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -2867,6 +2867,25 @@ _dbus_daemon_is_session_bus_address_published (const char *scope) return FALSE; } +/** + * Lock access to autolaunched address + * + * This function is called to prevent client from accessing + * autolaunch address in shared memory segment as preparation + * to shutdown server + * @return TRUE lock has been gotten + * @return FALSE lock has not been gotten + */ +dbus_bool_t +_dbus_daemon_lock_autolaunch_address () +{ + HANDLE lock; + + // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address, + // _dbus_daemon_already_runs and _dbus_daemon_lock_autolaunch_address + return _dbus_global_lock (cUniqueDBusInitMutex) != FALSE; +} + dbus_bool_t _dbus_daemon_publish_session_bus_address (const char* address, const char *scope) { @@ -2884,7 +2903,8 @@ _dbus_daemon_publish_session_bus_address (const char* address, const char *scope return FALSE; } - // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs + // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address, + // _dbus_daemon_already_runs and _dbus_daemon_lock_autolaunch_address lock = _dbus_global_lock( cUniqueDBusInitMutex ); if (!hDBusDaemonMutex) @@ -2937,7 +2957,8 @@ _dbus_daemon_unpublish_session_bus_address (void) { HANDLE lock; - // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs + // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address, + // _dbus_daemon_already_runs and _dbus_daemon_lock_autolaunch_address lock = _dbus_global_lock( cUniqueDBusInitMutex ); CloseHandle( hDBusSharedMem ); @@ -3004,7 +3025,8 @@ _dbus_daemon_already_runs (DBusString *address, DBusString *shm_name, const char return FALSE; } - // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address and _dbus_daemon_already_runs + // sync _dbus_daemon_publish_session_bus_address, _dbus_daemon_unpublish_session_bus_address, + // _dbus_daemon_already_runs and _dbus_daemon_lock_autolaunch_address lock = _dbus_global_lock( cUniqueDBusInitMutex ); // do checks diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index b9b0c440..e4bb7139 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -613,6 +613,8 @@ void _dbus_logv (DBusSystemLogSeverity severity, _DBUS_BYTE_OF_PRIMITIVE (a, 6) == _DBUS_BYTE_OF_PRIMITIVE (b, 6) && \ _DBUS_BYTE_OF_PRIMITIVE (a, 7) == _DBUS_BYTE_OF_PRIMITIVE (b, 7)) +DBUS_PRIVATE_EXPORT +dbus_bool_t _dbus_daemon_lock_autolaunch_address(); dbus_bool_t _dbus_get_autolaunch_address (const char *scope, DBusString *address, DBusError *error); diff --git a/doc/dbus-daemon.1.xml.in b/doc/dbus-daemon.1.xml.in index 6368464f..404d037c 100644 --- a/doc/dbus-daemon.1.xml.in +++ b/doc/dbus-daemon.1.xml.in @@ -32,6 +32,7 @@ --nosyslog --syslog --syslog-only + --disable-auto-shutdown @@ -197,6 +198,15 @@ files. + + + + On Windows dbus daemon is autolaunched by dbus client library if an + autolaunch bus address is specified. After last client disconnects it + shuts down by default if not disabled with this switch. + + + -- 2.12.3