diff options
Diffstat (limited to 'recipes/dbus/dbus-1.3.0/will-6.patch')
-rw-r--r-- | recipes/dbus/dbus-1.3.0/will-6.patch | 456 |
1 files changed, 0 insertions, 456 deletions
diff --git a/recipes/dbus/dbus-1.3.0/will-6.patch b/recipes/dbus/dbus-1.3.0/will-6.patch deleted file mode 100644 index 05d9c49e30..0000000000 --- a/recipes/dbus/dbus-1.3.0/will-6.patch +++ /dev/null @@ -1,456 +0,0 @@ -From 023bb6fdc82304866353a28cd503863e80c3ea0d Mon Sep 17 00:00:00 2001 -From: Will Thompson <will.thompson@collabora.co.uk> -Date: Thu, 30 Jul 2009 10:49:33 +0100 -Subject: [PATCH 6/6] Group match rules by their interface. - -In my informal studies of "normal" sets of match rules, only checking -match rules with the appropriate interface for the message reduces the -number that need to be checked by almost 100x on average (ranging from -halving for messages from the bus daemon, to a >200x reduction in many -cases). This reduces the overhead added to dispatching each message by -having lots of irrelevant match rules. ---- - bus/signals.c | 292 ++++++++++++++++++++++++++++++++++++++++++++++----------- - 1 files changed, 239 insertions(+), 53 deletions(-) - -diff --git a/bus/signals.c b/bus/signals.c -index c6f122b..23bf98a 100644 ---- a/bus/signals.c -+++ b/bus/signals.c -@@ -1018,15 +1018,25 @@ bus_match_rule_parse (DBusConnection *matches_go_to, - return rule; - } - -+typedef struct RulePool RulePool; -+struct RulePool -+{ -+ /* Maps non-NULL interface names to non-NULL (DBusList **)s */ -+ DBusHashTable *rules_by_iface; -+ -+ /* List of BusMatchRules which don't specify an interface */ -+ DBusList *rules_without_iface; -+}; -+ - struct BusMatchmaker - { - int refcount; - -- /* lists of rules, grouped by the type of message they match. 0 -+ /* Pools of rules, grouped by the type of message they match. 0 - * (DBUS_MESSAGE_TYPE_INVALID) represents rules that do not specify a message - * type. - */ -- DBusList *rules_by_type[DBUS_NUM_MESSAGE_TYPES]; -+ RulePool rules_by_type[DBUS_NUM_MESSAGE_TYPES]; - }; - - static void -@@ -1042,28 +1052,139 @@ rule_list_free (DBusList **rules) - } - } - -+static void -+rule_list_ptr_free (DBusList **list) -+{ -+ /* We have to cope with NULL because the hash table frees the "existing" -+ * value (which is NULL) when creating a new table entry... -+ */ -+ if (list != NULL) -+ { -+ rule_list_free (list); -+ dbus_free (list); -+ } -+} -+ - BusMatchmaker* - bus_matchmaker_new (void) - { - BusMatchmaker *matchmaker; -+ int i; - - matchmaker = dbus_new0 (BusMatchmaker, 1); - if (matchmaker == NULL) - return NULL; - - matchmaker->refcount = 1; -- -+ -+ for (i = DBUS_MESSAGE_TYPE_INVALID; i < DBUS_NUM_MESSAGE_TYPES; i++) -+ { -+ RulePool *p = matchmaker->rules_by_type + i; -+ -+ p->rules_by_iface = _dbus_hash_table_new (DBUS_HASH_STRING, -+ dbus_free, (DBusFreeFunction) rule_list_ptr_free); -+ -+ if (p->rules_by_iface == NULL) -+ goto nomem; -+ } -+ - return matchmaker; -+ -+ nomem: -+ for (i = DBUS_MESSAGE_TYPE_INVALID; i < DBUS_NUM_MESSAGE_TYPES; i++) -+ { -+ RulePool *p = matchmaker->rules_by_type + i; -+ -+ if (p->rules_by_iface == NULL) -+ break; -+ else -+ _dbus_hash_table_unref (p->rules_by_iface); -+ } -+ -+ return NULL; - } - - static DBusList ** - bus_matchmaker_get_rules (BusMatchmaker *matchmaker, -- int message_type) -+ int message_type, -+ const char *interface, -+ dbus_bool_t create) - { -+ RulePool *p; -+ - _dbus_assert (message_type >= 0); - _dbus_assert (message_type < DBUS_NUM_MESSAGE_TYPES); - -- return matchmaker->rules_by_type + message_type; -+ _dbus_verbose ("Looking up rules for message_type %d, interface %s\n", -+ message_type, -+ interface != NULL ? interface : "<null>"); -+ -+ p = matchmaker->rules_by_type + message_type; -+ -+ if (interface == NULL) -+ { -+ return &p->rules_without_iface; -+ } -+ else -+ { -+ DBusList **list; -+ -+ list = _dbus_hash_table_lookup_string (p->rules_by_iface, interface); -+ -+ if (list == NULL && create) -+ { -+ char *dupped_interface; -+ -+ list = dbus_new0 (DBusList *, 1); -+ if (list == NULL) -+ return NULL; -+ -+ dupped_interface = _dbus_strdup (interface); -+ if (dupped_interface == NULL) -+ { -+ dbus_free (list); -+ return NULL; -+ } -+ -+ _dbus_verbose ("Adding list for type %d, iface %s\n", message_type, -+ interface); -+ -+ if (!_dbus_hash_table_insert_string (p->rules_by_iface, -+ dupped_interface, list)) -+ { -+ dbus_free (list); -+ dbus_free (dupped_interface); -+ return NULL; -+ } -+ } -+ -+ return list; -+ } -+} -+ -+static void -+bus_matchmaker_gc_rules (BusMatchmaker *matchmaker, -+ int message_type, -+ const char *interface, -+ DBusList **rules) -+{ -+ RulePool *p; -+ -+ if (interface == NULL) -+ return; -+ -+ if (*rules != NULL) -+ return; -+ -+ _dbus_verbose ("GCing HT entry for message_type %u, interface %s\n", -+ message_type, interface); -+ -+ p = matchmaker->rules_by_type + message_type; -+ -+ _dbus_assert (_dbus_hash_table_lookup_string (p->rules_by_iface, interface) -+ == rules); -+ -+ _dbus_hash_table_remove_string (p->rules_by_iface, interface); - } - - BusMatchmaker * -@@ -1087,7 +1208,12 @@ bus_matchmaker_unref (BusMatchmaker *matchmaker) - int i; - - for (i = DBUS_MESSAGE_TYPE_INVALID; i < DBUS_NUM_MESSAGE_TYPES; i++) -- rule_list_free (bus_matchmaker_get_rules (matchmaker, i)); -+ { -+ RulePool *p = matchmaker->rules_by_type + i; -+ -+ _dbus_hash_table_unref (p->rules_by_iface); -+ rule_list_free (&p->rules_without_iface); -+ } - - dbus_free (matchmaker); - } -@@ -1102,7 +1228,15 @@ bus_matchmaker_add_rule (BusMatchmaker *matchmaker, - - _dbus_assert (bus_connection_is_active (rule->matches_go_to)); - -- rules = bus_matchmaker_get_rules (matchmaker, rule->message_type); -+ _dbus_verbose ("Adding rule with message_type %d, interface %s\n", -+ rule->message_type, -+ rule->interface != NULL ? rule->interface : "<null>"); -+ -+ rules = bus_matchmaker_get_rules (matchmaker, rule->message_type, -+ rule->interface, TRUE); -+ -+ if (rules == NULL) -+ return FALSE; - - if (!_dbus_list_append (rules, rule)) - return FALSE; -@@ -1110,9 +1244,11 @@ bus_matchmaker_add_rule (BusMatchmaker *matchmaker, - if (!bus_connection_add_match_rule (rule->matches_go_to, rule)) - { - _dbus_list_remove_last (rules, rule); -+ bus_matchmaker_gc_rules (matchmaker, rule->message_type, -+ rule->interface, rules); - return FALSE; - } -- -+ - bus_match_rule_ref (rule); - - #ifdef DBUS_ENABLE_VERBOSE_MODE -@@ -1224,10 +1360,23 @@ bus_matchmaker_remove_rule (BusMatchmaker *matchmaker, - { - DBusList **rules; - -+ _dbus_verbose ("Removing rule with message_type %d, interface %s\n", -+ rule->message_type, -+ rule->interface != NULL ? rule->interface : "<null>"); -+ - bus_connection_remove_match_rule (rule->matches_go_to, rule); - -- rules = bus_matchmaker_get_rules (matchmaker, rule->message_type); -+ rules = bus_matchmaker_get_rules (matchmaker, rule->message_type, -+ rule->interface, FALSE); -+ -+ /* We should only be asked to remove a rule by identity right after it was -+ * added, so there should be a list for it. -+ */ -+ _dbus_assert (rules != NULL); -+ - _dbus_list_remove (rules, rule); -+ bus_matchmaker_gc_rules (matchmaker, rule->message_type, rule->interface, -+ rules); - - #ifdef DBUS_ENABLE_VERBOSE_MODE - { -@@ -1248,31 +1397,38 @@ bus_matchmaker_remove_rule_by_value (BusMatchmaker *matchmaker, - BusMatchRule *value, - DBusError *error) - { -- /* FIXME this is an unoptimized linear scan */ - DBusList **rules; -- DBusList *link; -+ DBusList *link = NULL; - -- rules = bus_matchmaker_get_rules (matchmaker, value->message_type); -+ _dbus_verbose ("Removing rule by value with message_type %d, interface %s\n", -+ value->message_type, -+ value->interface != NULL ? value->interface : "<null>"); - -- /* we traverse backward because bus_connection_remove_match_rule() -- * removes the most-recently-added rule -- */ -- link = _dbus_list_get_last_link (rules); -- while (link != NULL) -+ rules = bus_matchmaker_get_rules (matchmaker, value->message_type, -+ value->interface, FALSE); -+ -+ if (rules != NULL) - { -- BusMatchRule *rule; -- DBusList *prev; -+ /* we traverse backward because bus_connection_remove_match_rule() -+ * removes the most-recently-added rule -+ */ -+ link = _dbus_list_get_last_link (rules); -+ while (link != NULL) -+ { -+ BusMatchRule *rule; -+ DBusList *prev; - -- rule = link->data; -- prev = _dbus_list_get_prev_link (rules, link); -+ rule = link->data; -+ prev = _dbus_list_get_prev_link (rules, link); - -- if (match_rule_equal (rule, value)) -- { -- bus_matchmaker_remove_rule_link (rules, link); -- break; -- } -+ if (match_rule_equal (rule, value)) -+ { -+ bus_matchmaker_remove_rule_link (rules, link); -+ break; -+ } - -- link = prev; -+ link = prev; -+ } - } - - if (link == NULL) -@@ -1282,6 +1438,9 @@ bus_matchmaker_remove_rule_by_value (BusMatchmaker *matchmaker, - return FALSE; - } - -+ bus_matchmaker_gc_rules (matchmaker, value->message_type, value->interface, -+ rules); -+ - return TRUE; - } - -@@ -1341,16 +1500,29 @@ bus_matchmaker_disconnected (BusMatchmaker *matchmaker, - * for the rules belonging to the connection, since we keep - * a list of those; but for the rules that just refer to - * the connection we'd need to do something more elaborate. -- * - */ -- -+ - _dbus_assert (bus_connection_is_active (disconnected)); - -+ _dbus_verbose ("Removing all rules for connection %p\n", disconnected); -+ - for (i = DBUS_MESSAGE_TYPE_INVALID; i < DBUS_NUM_MESSAGE_TYPES; i++) - { -- DBusList **rules = bus_matchmaker_get_rules (matchmaker, i); -+ RulePool *p = matchmaker->rules_by_type + i; -+ DBusHashIter iter; -+ -+ rule_list_remove_by_connection (&p->rules_without_iface, disconnected); -+ -+ _dbus_hash_iter_init (p->rules_by_iface, &iter); -+ while (_dbus_hash_iter_next (&iter)) -+ { -+ DBusList **items = _dbus_hash_iter_get_value (&iter); - -- rule_list_remove_by_connection (rules, disconnected); -+ rule_list_remove_by_connection (items, disconnected); -+ -+ if (*items == NULL) -+ _dbus_hash_iter_remove_entry (&iter); -+ } - } - } - -@@ -1565,6 +1737,9 @@ get_recipients_from_list (DBusList **rules, - { - DBusList *link; - -+ if (rules == NULL) -+ return TRUE; -+ - link = _dbus_list_get_first_link (rules); - while (link != NULL) - { -@@ -1581,10 +1756,10 @@ get_recipients_from_list (DBusList **rules, - dbus_free (s); - } - #endif -- -+ - if (match_rule_matches (rule, - sender, addressed_recipient, message, -- BUS_MATCH_MESSAGE_TYPE)) -+ BUS_MATCH_MESSAGE_TYPE | BUS_MATCH_INTERFACE)) - { - _dbus_verbose ("Rule matched\n"); - -@@ -1616,12 +1791,9 @@ bus_matchmaker_get_recipients (BusMatchmaker *matchmaker, - DBusMessage *message, - DBusList **recipients_p) - { -- /* FIXME for now this is a wholly unoptimized linear search */ -- /* Guessing the important optimization is to skip the signal-related -- * match lists when processing method call and exception messages. -- * So separate match rule lists for signals? -- */ - int type; -+ const char *interface; -+ DBusList **neither, **just_type, **just_iface, **both; - - _dbus_assert (*recipients_p == NULL); - -@@ -1638,25 +1810,39 @@ bus_matchmaker_get_recipients (BusMatchmaker *matchmaker, - if (addressed_recipient != NULL) - bus_connection_mark_stamp (addressed_recipient); - -- /* We always need to try the rules that don't specify a message type */ -- if (!get_recipients_from_list ( -- bus_matchmaker_get_rules (matchmaker, DBUS_MESSAGE_TYPE_INVALID), -- sender, addressed_recipient, message, recipients_p)) -- goto nomem; -- -- /* Also try rules that match the type of this message */ - type = dbus_message_get_type (message); -+ interface = dbus_message_get_interface (message); -+ -+ neither = bus_matchmaker_get_rules (matchmaker, DBUS_MESSAGE_TYPE_INVALID, -+ NULL, FALSE); -+ just_type = just_iface = both = NULL; -+ -+ if (interface != NULL) -+ just_iface = bus_matchmaker_get_rules (matchmaker, -+ DBUS_MESSAGE_TYPE_INVALID, interface, FALSE); -+ - if (type > DBUS_MESSAGE_TYPE_INVALID && type < DBUS_NUM_MESSAGE_TYPES) -- if (!get_recipients_from_list ( -- bus_matchmaker_get_rules (matchmaker, type), -- sender, addressed_recipient, message, recipients_p)) -- goto nomem; -+ { -+ just_type = bus_matchmaker_get_rules (matchmaker, type, NULL, FALSE); - -- return TRUE; -+ if (interface != NULL) -+ both = bus_matchmaker_get_rules (matchmaker, type, interface, FALSE); -+ } - -- nomem: -- _dbus_list_clear (recipients_p); -- return FALSE; -+ if (!(get_recipients_from_list (neither, sender, addressed_recipient, -+ message, recipients_p) && -+ get_recipients_from_list (just_iface, sender, addressed_recipient, -+ message, recipients_p) && -+ get_recipients_from_list (just_type, sender, addressed_recipient, -+ message, recipients_p) && -+ get_recipients_from_list (both, sender, addressed_recipient, -+ message, recipients_p))) -+ { -+ _dbus_list_clear (recipients_p); -+ return FALSE; -+ } -+ -+ return TRUE; - } - - #ifdef DBUS_BUILD_TESTS --- -1.6.3.3 - |