summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalf Habacker <ralf.habacker@freenet.de>2017-04-11 00:28:48 +0200
committerRalf Habacker <ralf.habacker@freenet.de>2017-04-11 00:28:48 +0200
commit938f9a530f24b9b4cf164f4e3721f12570c46c7b (patch)
tree55a49ae6c20bfd8c476e5be5da1df3e8317e9a5e
parenteb56619aedc667c0d10b2e9630802c24c1a617a3 (diff)
Add support for automatically shutdown dbus-daemon after after last client disconnects on Windows.terminate-dbus-after-clients-disconnect
Shutdown the server if the bus is running with an autolaunch meta transport and the last client has disconnected.
-rw-r--r--bus/bus.c17
-rw-r--r--bus/bus.h3
-rw-r--r--bus/connection.c27
-rw-r--r--dbus/dbus-sysdeps-unix.c6
-rw-r--r--dbus/dbus-sysdeps-win.c28
-rw-r--r--dbus/dbus-sysdeps.h1
6 files changed, 78 insertions, 4 deletions
diff --git a/bus/bus.c b/bus/bus.c
index b01386643..2ad221c92 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -74,6 +74,7 @@ struct BusContext
unsigned int allow_anonymous : 1;
unsigned int systemd_activation : 1;
dbus_bool_t watches_enabled;
+ int n_connections;
};
static dbus_int32_t server_data_slot = -1;
@@ -1825,3 +1826,19 @@ bus_context_check_all_watches (BusContext *context)
_dbus_server_toggle_all_watches (server, enabled);
}
}
+
+void bus_context_increment_connections (BusContext *context)
+{
+ context->n_connections++;
+}
+
+void
+bus_context_decrement_connections (BusContext *context)
+{
+ context->n_connections--;
+}
+
+int bus_context_n_connections (BusContext *context)
+{
+ return context->n_connections;
+}
diff --git a/bus/bus.h b/bus/bus.h
index 2e0de8255..55ea7e593 100644
--- a/bus/bus.h
+++ b/bus/bus.h
@@ -145,5 +145,8 @@ dbus_bool_t bus_context_check_security_policy (BusContext
BusActivationEntry *activation_entry,
DBusError *error);
void bus_context_check_all_watches (BusContext *context);
+void bus_context_increment_connections (BusContext *context);
+void bus_context_decrement_connections (BusContext *context);
+int bus_context_n_connections (BusContext *context);
#endif /* BUS_BUS_H */
diff --git a/bus/connection.c b/bus/connection.c
index 5144218cf..16e29cc81 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -295,6 +295,29 @@ bus_connection_disconnected (DBusConnection *connection)
bus_connection_remove_transactions (connection);
+ bus_context_decrement_connections (d->connections->context);
+#ifdef DBUS_WIIN
+ if (bus_context_n_connections (d->connections->context) == 0)
+ {
+ const char *s = bus_context_get_address (d->connections->context);
+ if (strstr (s, "autolaunch"))
+ {
+ if (_dbus_daemon_lock_autolaunch_address ())
+ {
+ DBusLoop *loop = bus_context_get_loop (d->connections->context);
+ _dbus_loop_quit (loop);
+ }
+ else
+ {
+ // Ignore the case that we are not able to lock autolaunch address mutex
+ // because a client tries to fetch autolaunch address as preparation
+ // to connect to the server.
+ _dbus_verbose ("Could not lock autolaunch address - skipping shutdown");
+ }
+ }
+ }
+#endif
+
if (d->link_in_monitors != NULL)
{
BusMatchmaker *mm = d->connections->monitor_matchmaker;
@@ -1582,7 +1605,9 @@ bus_connection_complete (DBusConnection *connection,
d->name = NULL;
return FALSE;
}
-
+
+ bus_context_increment_connections(d->connections->context);
+
if (dbus_connection_get_unix_user (connection, &uid))
{
if (!adjust_connections_for_uid (d->connections,
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index 39c13360b..259e9723a 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -4271,6 +4271,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 e321168bc..3e6e0cc4f 100644
--- a/dbus/dbus-sysdeps-win.c
+++ b/dbus/dbus-sysdeps-win.c
@@ -2859,6 +2859,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)
{
@@ -2876,7 +2895,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)
@@ -2929,7 +2949,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 );
@@ -2996,7 +3017,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 5ed4c45ed..0a03253da 100644
--- a/dbus/dbus-sysdeps.h
+++ b/dbus/dbus-sysdeps.h
@@ -610,6 +610,7 @@ 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_bool_t _dbus_daemon_lock_autolaunch_address();
dbus_bool_t _dbus_get_autolaunch_address (const char *scope,
DBusString *address,
DBusError *error);