Does g_source_remove() also destroy the source?

I am creating (with g_source_new()), and attaching a GSource to the main context (gtk4 program).

If I use g_source_remove() it seems that I cannot subsequently use g_source attach to reattach it (using the same GSource *).

It’s as if g_source_remove() is also invoking g_source_delete(), although I don’t find this in my reading of the documentation.

Do I have to (as it seems I do) use g_source_new() each time I attach a source after removal?

Michael

The terminology is really confusing. g_source_destroy() removes the source from the main context. That name was a mistake. It won’t actually destroy the source on its own. But removing it from the main context may have the side effect of destroying it: semantically, you can think of it as the main context dropping its ref on the source, so if there are no other references remaining then it will be destroyed. But when you call this function yourself, you would usually have your own ref, so that ordinarily would not happen. A typical pattern would be: you call g_source_destroy(), then you possibly call g_source_unref() if you are done with it.

g_source_remove() just removes the GSource from the default main context using g_source_destroy(). But in this case, you probably don’t have your own ref, because it accepts an integer ID rather than a GSource object, so this would indeed usually destroy the source. But you can prevent that by keeping a ref.

The scenario you’re describing is probably a mistake. You don’t generally want to pair g_source_new() with g_source_remove(). You technically can, by using g_source_get_id() and passing it to g_source_remove(), but that’s really confusing. If you created the GSource using g_source_new(), then you would normally call g_source_destroy() and g_source_unref() instead of using g_source_remove().

g_source_remove() is normally paired with g_idle_add() or g_timeout_add() because those functions return a source ID, and g_source_remove() also takes a source ID. Those work well for simple cases, allowing you to create and destroy the source without ever using a GSource object. Whereas if you have a GSource, it’s normally better to use it and ignore the simple APIs that only take the source ID. I recommend you pick one set of APIs or the other. The APIs that operate on GSource objects give you more control and are necessary when you need anything other than the default main context. But the APIs that operate on integers are simpler and should be preferred when you can use them. See the main context tutorial to learn more.

The documentation says …

“This does not unref the GSource: if you still hold a reference, use g_source_unref() to drop it.”

This implies, as you say, that the object is not unallocated.

Even if I use g_source_ref( ptrSource ) (to ensure the count doesn’t go to 0), and then g_source_delete( ptrSource ), I still get an error when I try to reattach with g_source_attach( ptrSource, NULL )

g_source_attach: assertion 'source->context == NULL' failed

The documentation for g_source_destroy() states this: “The source cannot be subsequently added to another context.”

It’s the same (main) context.

If it means “any context”, then it is only possible to attach a “new” source.

g_source_delete() does not exist.

Hm, then I suppose you cannot reattach after all.

yeah g_source_destroy() :weary_cat: