mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-14 05:16:18 +01:00
gdbusproxy: Add G_DBUS_PROXY_FLAGS_NO_MATCH_RULE flag
D-Bus has an upper limit on number of Match rules and it's rather easy to hit with a big number of proxies with signal subscriptions. This happens with NetworkManager with hundreds of devices or connection settings. By passing G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE to g_dbus_connection_signal_subscribe(), the user can call AddMatch with a less granular match instead of a match per every proxy. Tests subsequently added by Philip Withnall. Fixes: #1109
This commit is contained in:
parent
caf777984b
commit
a107a328e4
@ -1694,6 +1694,10 @@ static void
|
|||||||
async_initable_init_first (GAsyncInitable *initable)
|
async_initable_init_first (GAsyncInitable *initable)
|
||||||
{
|
{
|
||||||
GDBusProxy *proxy = G_DBUS_PROXY (initable);
|
GDBusProxy *proxy = G_DBUS_PROXY (initable);
|
||||||
|
GDBusSignalFlags signal_flags = G_DBUS_SIGNAL_FLAGS_NONE;
|
||||||
|
|
||||||
|
if (proxy->priv->flags & G_DBUS_PROXY_FLAGS_NO_MATCH_RULE)
|
||||||
|
signal_flags |= G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE;
|
||||||
|
|
||||||
if (!(proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES))
|
if (!(proxy->priv->flags & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES))
|
||||||
{
|
{
|
||||||
@ -1705,7 +1709,7 @@ async_initable_init_first (GAsyncInitable *initable)
|
|||||||
"PropertiesChanged",
|
"PropertiesChanged",
|
||||||
proxy->priv->object_path,
|
proxy->priv->object_path,
|
||||||
proxy->priv->interface_name,
|
proxy->priv->interface_name,
|
||||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
signal_flags,
|
||||||
on_properties_changed,
|
on_properties_changed,
|
||||||
weak_ref_new (G_OBJECT (proxy)),
|
weak_ref_new (G_OBJECT (proxy)),
|
||||||
(GDestroyNotify) weak_ref_free);
|
(GDestroyNotify) weak_ref_free);
|
||||||
@ -1721,7 +1725,7 @@ async_initable_init_first (GAsyncInitable *initable)
|
|||||||
NULL, /* member */
|
NULL, /* member */
|
||||||
proxy->priv->object_path,
|
proxy->priv->object_path,
|
||||||
NULL, /* arg0 */
|
NULL, /* arg0 */
|
||||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
signal_flags,
|
||||||
on_signal_received,
|
on_signal_received,
|
||||||
weak_ref_new (G_OBJECT (proxy)),
|
weak_ref_new (G_OBJECT (proxy)),
|
||||||
(GDestroyNotify) weak_ref_free);
|
(GDestroyNotify) weak_ref_free);
|
||||||
@ -1737,7 +1741,7 @@ async_initable_init_first (GAsyncInitable *initable)
|
|||||||
"NameOwnerChanged", /* signal name */
|
"NameOwnerChanged", /* signal name */
|
||||||
"/org/freedesktop/DBus", /* path */
|
"/org/freedesktop/DBus", /* path */
|
||||||
proxy->priv->name, /* arg0 */
|
proxy->priv->name, /* arg0 */
|
||||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
signal_flags,
|
||||||
on_name_owner_changed,
|
on_name_owner_changed,
|
||||||
weak_ref_new (G_OBJECT (proxy)),
|
weak_ref_new (G_OBJECT (proxy)),
|
||||||
(GDestroyNotify) weak_ref_free);
|
(GDestroyNotify) weak_ref_free);
|
||||||
|
@ -1021,6 +1021,9 @@ typedef enum
|
|||||||
* do not ask the bus to launch an owner during proxy initialization, but allow it to be
|
* do not ask the bus to launch an owner during proxy initialization, but allow it to be
|
||||||
* autostarted by a method call. This flag is only meaningful in proxies for well-known names,
|
* autostarted by a method call. This flag is only meaningful in proxies for well-known names,
|
||||||
* and only if %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START is not also specified.
|
* and only if %G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START is not also specified.
|
||||||
|
* @G_DBUS_PROXY_FLAGS_NO_MATCH_RULE: Don't actually send the AddMatch D-Bus
|
||||||
|
* call for this signal subscription. This gives you more control
|
||||||
|
* over which match rules you add (but you must add them manually). (Since: 2.72)
|
||||||
*
|
*
|
||||||
* Flags used when constructing an instance of a #GDBusProxy derived class.
|
* Flags used when constructing an instance of a #GDBusProxy derived class.
|
||||||
*
|
*
|
||||||
@ -1033,7 +1036,8 @@ typedef enum
|
|||||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS = (1<<1),
|
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS = (1<<1),
|
||||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START = (1<<2),
|
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START = (1<<2),
|
||||||
G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES = (1<<3),
|
G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES = (1<<3),
|
||||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION = (1<<4)
|
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION = (1<<4),
|
||||||
|
G_DBUS_PROXY_FLAGS_NO_MATCH_RULE GLIB_AVAILABLE_ENUMERATOR_IN_2_72 = (1<<5)
|
||||||
} GDBusProxyFlags;
|
} GDBusProxyFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -701,7 +701,6 @@ test_basic (GDBusProxy *proxy)
|
|||||||
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
||||||
|
|
||||||
g_assert_true (g_dbus_proxy_get_connection (proxy) == connection);
|
g_assert_true (g_dbus_proxy_get_connection (proxy) == connection);
|
||||||
g_assert_cmpint (g_dbus_proxy_get_flags (proxy), ==, G_DBUS_PROXY_FLAGS_NONE);
|
|
||||||
g_assert_null (g_dbus_proxy_get_interface_info (proxy));
|
g_assert_null (g_dbus_proxy_get_interface_info (proxy));
|
||||||
g_assert_cmpstr (g_dbus_proxy_get_name (proxy), ==, "com.example.TestService");
|
g_assert_cmpstr (g_dbus_proxy_get_name (proxy), ==, "com.example.TestService");
|
||||||
g_assert_cmpstr (g_dbus_proxy_get_object_path (proxy), ==, "/com/example/TestObject");
|
g_assert_cmpstr (g_dbus_proxy_get_object_path (proxy), ==, "/com/example/TestObject");
|
||||||
@ -720,7 +719,7 @@ test_basic (GDBusProxy *proxy)
|
|||||||
|
|
||||||
g_assert_true (conn == connection);
|
g_assert_true (conn == connection);
|
||||||
g_assert_null (info);
|
g_assert_null (info);
|
||||||
g_assert_cmpint (flags, ==, G_DBUS_PROXY_FLAGS_NONE);
|
g_assert_cmpint (flags, ==, g_dbus_proxy_get_flags (proxy));
|
||||||
g_assert_cmpstr (name, ==, "com.example.TestService");
|
g_assert_cmpstr (name, ==, "com.example.TestService");
|
||||||
g_assert_cmpstr (path, ==, "/com/example/TestObject");
|
g_assert_cmpstr (path, ==, "/com/example/TestObject");
|
||||||
g_assert_cmpstr (interface, ==, "com.example.Frob");
|
g_assert_cmpstr (interface, ==, "com.example.Frob");
|
||||||
@ -763,7 +762,7 @@ kill_test_service (GDBusConnection *connection)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_proxy (void)
|
test_proxy_with_flags (GDBusProxyFlags flags)
|
||||||
{
|
{
|
||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
GDBusConnection *connection;
|
GDBusConnection *connection;
|
||||||
@ -777,7 +776,7 @@ test_proxy (void)
|
|||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
error = NULL;
|
error = NULL;
|
||||||
proxy = g_dbus_proxy_new_sync (connection,
|
proxy = g_dbus_proxy_new_sync (connection,
|
||||||
G_DBUS_PROXY_FLAGS_NONE,
|
flags,
|
||||||
NULL, /* GDBusInterfaceInfo */
|
NULL, /* GDBusInterfaceInfo */
|
||||||
"com.example.TestService", /* name */
|
"com.example.TestService", /* name */
|
||||||
"/com/example/TestObject", /* object path */
|
"/com/example/TestObject", /* object path */
|
||||||
@ -809,6 +808,12 @@ test_proxy (void)
|
|||||||
g_object_unref (connection);
|
g_object_unref (connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_proxy (void)
|
||||||
|
{
|
||||||
|
test_proxy_with_flags (G_DBUS_PROXY_FLAGS_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -930,6 +935,58 @@ test_wellknown_noauto (void)
|
|||||||
g_source_remove (id);
|
g_source_remove (id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ADD_MATCH,
|
||||||
|
REMOVE_MATCH,
|
||||||
|
} AddOrRemove;
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_or_remove_match_rule (GDBusConnection *connection,
|
||||||
|
AddOrRemove add_or_remove,
|
||||||
|
GVariant *match_rule)
|
||||||
|
{
|
||||||
|
GDBusMessage *message = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
message = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */
|
||||||
|
"/org/freedesktop/DBus", /* path */
|
||||||
|
"org.freedesktop.DBus", /* interface */
|
||||||
|
(add_or_remove == ADD_MATCH) ? "AddMatch" : "RemoveMatch");
|
||||||
|
g_dbus_message_set_body (message, match_rule);
|
||||||
|
g_dbus_connection_send_message (connection,
|
||||||
|
message,
|
||||||
|
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_clear_object (&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_proxy_no_match_rule (void)
|
||||||
|
{
|
||||||
|
GDBusConnection *connection = NULL;
|
||||||
|
GVariant *match_rule = NULL;
|
||||||
|
|
||||||
|
g_test_summary ("Test that G_DBUS_PROXY_FLAGS_NO_MATCH_RULE works");
|
||||||
|
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/1109");
|
||||||
|
|
||||||
|
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
||||||
|
|
||||||
|
/* Add a custom match rule which matches everything. */
|
||||||
|
match_rule = g_variant_ref_sink (g_variant_new ("(s)", "type='signal'"));
|
||||||
|
add_or_remove_match_rule (connection, ADD_MATCH, match_rule);
|
||||||
|
|
||||||
|
/* Run the tests. */
|
||||||
|
test_proxy_with_flags (G_DBUS_PROXY_FLAGS_NO_MATCH_RULE);
|
||||||
|
|
||||||
|
/* Remove the match rule again. */
|
||||||
|
add_or_remove_match_rule (connection, REMOVE_MATCH, match_rule);
|
||||||
|
|
||||||
|
g_clear_pointer (&match_rule, g_variant_unref);
|
||||||
|
g_clear_object (&connection);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
@ -950,6 +1007,7 @@ main (int argc,
|
|||||||
g_test_add_func ("/gdbus/proxy/no-properties", test_no_properties);
|
g_test_add_func ("/gdbus/proxy/no-properties", test_no_properties);
|
||||||
g_test_add_func ("/gdbus/proxy/wellknown-noauto", test_wellknown_noauto);
|
g_test_add_func ("/gdbus/proxy/wellknown-noauto", test_wellknown_noauto);
|
||||||
g_test_add_func ("/gdbus/proxy/async", test_async);
|
g_test_add_func ("/gdbus/proxy/async", test_async);
|
||||||
|
g_test_add_func ("/gdbus/proxy/no-match-rule", test_proxy_no_match_rule);
|
||||||
|
|
||||||
ret = session_bus_run();
|
ret = session_bus_run();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user