+ _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);