+ * g_dbus_interface_info_cache_build:
+ * @info: A #GDBusInterfaceInfo.
+ *
+ * Builds a lookup-cache to speed up
+ * g_dbus_interface_info_lookup_method(),
+ * g_dbus_interface_info_lookup_signal() and
+ * g_dbus_interface_info_lookup_property().
+ *
+ * If this has already been called with @info, the existing cache is
+ * used and its use count is increased.
+ *
+ * Note that @info cannot be modified until
+ * g_dbus_interface_info_cache_release() is called.
+ *
+ * Since: 2.30
+ */
+void
+g_dbus_interface_info_cache_build (GDBusInterfaceInfo *info)
+{
+ InfoCacheEntry *cache;
+ guint n;
+
+ G_LOCK (info_cache_lock);
+ if (info_cache == NULL)
+ info_cache = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) info_cache_free);
+ cache = g_hash_table_lookup (info_cache, info);
+ if (cache != NULL)
+ {
+ cache->use_count += 1;
+ goto out;
+ }
+ cache = g_slice_new0 (InfoCacheEntry);
+ cache->use_count = 1;
+ cache->method_name_to_data = g_hash_table_new (g_str_hash, g_str_equal);
+ cache->signal_name_to_data = g_hash_table_new (g_str_hash, g_str_equal);
+ cache->property_name_to_data = g_hash_table_new (g_str_hash, g_str_equal);
+ for (n = 0; info->methods != NULL && info->methods[n] != NULL; n++)
+ g_hash_table_insert (cache->method_name_to_data, info->methods[n]->name, info->methods[n]);
+ for (n = 0; info->signals != NULL && info->signals[n] != NULL; n++)
+ g_hash_table_insert (cache->signal_name_to_data, info->signals[n]->name, info->signals[n]);
+ for (n = 0; info->properties != NULL && info->properties[n] != NULL; n++)
+ g_hash_table_insert (cache->property_name_to_data, info->properties[n]->name, info->properties[n]);
+ g_hash_table_insert (info_cache, info, cache);
+ out:
+ G_UNLOCK (info_cache_lock);
+}
+
+/**
+ * g_dbus_interface_info_cache_release:
+ * @info: A GDBusInterfaceInfo
+ *
+ * Decrements the usage count for the cache for @info built by
+ * g_dbus_interface_info_cache_build() (if any) and frees the
+ * resources used by the cache if the usage count drops to zero.
+ *
+ * Since: 2.30
+ */
+void
+g_dbus_interface_info_cache_release (GDBusInterfaceInfo *info)
+{
+ InfoCacheEntry *cache;
+
+ G_LOCK (info_cache_lock);
+ if (G_UNLIKELY (info_cache == NULL))
+ {
+ g_warning ("%s called for interface %s but there is no cache", info->name, G_STRFUNC);
+ goto out;
+ }
+
+ cache = g_hash_table_lookup (info_cache, info);
+ if (G_UNLIKELY (cache == NULL))
+ {
+ g_warning ("%s called for interface %s but there is no cache entry", info->name, G_STRFUNC);
+ goto out;
+ }
+ cache->use_count -= 1;
+ if (cache->use_count == 0)
+ {
+ g_hash_table_remove (info_cache, info);
+ /* could nuke info_cache itself if empty */
+ }
+ out:
+ G_UNLOCK (info_cache_lock);
+}
+
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**