Release GBinding transform functions also when implicitly unbinding because source/target are finalized

This was inconsistently handled before and only explicit unbinding or
finalizing the binding would've previously released the transform
function. If the source/target were finalized while more strong
references to the binding still existed then the transform function
would stay alive and only the binding itself would be deactivated.
This commit is contained in:
Sebastian Dröge 2020-11-26 12:35:28 +02:00
parent cc15c933b3
commit 7367c5d367

View File

@ -183,11 +183,7 @@ binding_context_unref (BindingContext *context)
*
* The transform functions are released when unbinding but unbinding can happen
* while the transform functions are currently in use inside the notify callbacks.
*
* Note that the transform functions are only released from explicit unbinding
* or when the binding itself is finalized. Finalizing the source and target
* while the binding is still alive does not release the transform functions
* yet. */
*/
typedef struct {
GBindingTransformFunc transform_s2t;
GBindingTransformFunc transform_t2s;
@ -374,6 +370,7 @@ weak_unbind (gpointer user_data,
GBinding *binding;
GObject *source, *target;
gboolean binding_was_removed = FALSE;
TransformFunc *transform_func;
binding = g_weak_ref_get (&context->binding);
if (!binding)
@ -385,6 +382,8 @@ weak_unbind (gpointer user_data,
g_mutex_lock (&binding->unbind_lock);
transform_func = g_steal_pointer (&binding->transform_func);
source = g_weak_ref_get (&context->source);
target = g_weak_ref_get (&context->target);
@ -399,11 +398,13 @@ weak_unbind (gpointer user_data,
g_mutex_unlock (&binding->unbind_lock);
/* Unref source and target after the mutex is unlocked as it might
* release the last reference, which then accesses the mutex again */
/* Unref source, target and transform_func after the mutex is unlocked as it
* might release the last reference, which then accesses the mutex again */
g_clear_object (&target);
g_clear_object (&source);
g_clear_pointer (&transform_func, transform_func_unref);
/* This releases the strong reference we got from the weak ref above */
g_object_unref (binding);