gmain: optimize "context->sources" hash table to use as set

Instead of tracking a "(guint,GSource*)" tuple in the "context->sources"
dictionary, only track pointers to the "source_id".

With this we use the GHashTable as Set (g_hash_table_add()), which is
optimized and avoids storing a separate value array.

It's simple enough to do, because there are literally 5 references to
"context->sources". It's easy to review those usages and reason that the
handling is correct.

While at it, in g_main_context_find_source_by_id() move the check for
SOURCE_DESTROYED() inside the lock. It's not obvious that doing this
without a lock was correct in every case. But doing the check with
a lock should be fast enough to not worry about whether it's absolutely
necessary.
This commit is contained in:
Thomas Haller 2023-10-24 14:14:14 +02:00
parent 501bdb51e4
commit b067c43b00

View File

@ -637,7 +637,7 @@ g_main_context_new_with_flags (GMainContextFlags flags)
g_mutex_init (&context->mutex);
g_cond_init (&context->cond);
context->sources = g_hash_table_new (NULL, NULL);
context->sources = g_hash_table_new (g_uint_hash, g_uint_equal);
context->owner = NULL;
context->flags = flags;
context->waiters = NULL;
@ -1166,13 +1166,13 @@ g_source_attach_unlocked (GSource *source,
*/
do
id = context->next_id++;
while (id == 0 || g_hash_table_contains (context->sources, GUINT_TO_POINTER (id)));
while (id == 0 || g_hash_table_contains (context->sources, &id));
source->context = context;
source->source_id = id;
g_source_ref (source);
g_hash_table_insert (context->sources, GUINT_TO_POINTER (id), source);
g_hash_table_add (context->sources, &source->source_id);
source_add_to_context (source, context);
@ -2239,7 +2239,7 @@ g_source_unref_internal (GSource *source,
g_warning (G_STRLOC ": ref_count == 0, but source was still attached to a context!");
source_remove_from_context (source, context);
g_hash_table_remove (context->sources, GUINT_TO_POINTER (source->source_id));
g_hash_table_remove (context->sources, &source->source_id);
}
if (source->source_funcs->finalize)
@ -2348,7 +2348,8 @@ GSource *
g_main_context_find_source_by_id (GMainContext *context,
guint source_id)
{
GSource *source;
GSource *source = NULL;
gconstpointer ptr;
g_return_val_if_fail (source_id > 0, NULL);
@ -2356,11 +2357,14 @@ g_main_context_find_source_by_id (GMainContext *context,
context = g_main_context_default ();
LOCK_CONTEXT (context);
source = g_hash_table_lookup (context->sources, GUINT_TO_POINTER (source_id));
UNLOCK_CONTEXT (context);
if (source && SOURCE_DESTROYED (source))
ptr = g_hash_table_lookup (context->sources, &source_id);
if (ptr)
{
source = G_CONTAINER_OF (ptr, GSource, source_id);
if (SOURCE_DESTROYED (source))
source = NULL;
}
UNLOCK_CONTEXT (context);
return source;
}