Issue of the Implementation # S0838


'destroy_data' function registered by g_cclosure_new is not called as a result of g_closure_invalidate

Detailed Description

Description of g_cclosure_new function states:

Creates a new closure which invokes callback_func with user_data as the last parameter.

callback_func : the function to invoke
user_data : user data to pass to callback_func
destroy_data : destroy notify to be called when user_data is no longer used
Returns : a new GCClosure

From the description of g_closure_invalidate function:

Sets a flag on the closure to indicate that its calling environment has become invalid, and thus causes any future invocations of g_closure_invoke() on this closure to be ignored.

The last description implies that after the call of g_closure_invalidate, 'user_data' can no longer be used by the closure. So, based on the description of destroy_data parameter of g_cclosure_new, 'destroy_data' function should be called at this point.

However the implementation calls 'destroy_data' only while destroying closure itself. But after the closure is invalidated (via explicit call of g_closure_invalidate), it may be a while before closure is destroyed via g_closure_unref. Therefore, the actual behaviour contradicts to what is stated in the documentation.

Problem location(s) in the standard

Linux Standard Base Desktop Specification 4.0, Section 16.5. Interfaces for libgobject-2.0 that refers Gobject 2.8.6 Reference Manual, Section "Closures"


#include <glib-object.h>
#include <stdio.h>

gboolean destroy_data_was_called = FALSE;
void destroy_data(gpointer data, GClosure* closure)
    destroy_data_was_called = TRUE;
void callback(){}

int main()
    gpointer data = (gpointer)0x123;
    GClosure* closure = g_cclosure_new(callback, data, destroy_data);
        printf("destroy_data wasn't called after invalidate.\n");
        return 1;
    return 0;




Gnome Bugzilla 614345