Подробности
[В начало]
Проблема в реализации № S0838
Краткое описание
Функция 'destroy_data', зарегистрированная в g_cclosure_new, не вызывается в результате g_closure_invalidate
Подробное описание
Описание функции g_cclosure_new:
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
Из описания функции g_closure_invalidate:
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.
Из последнего описания следует, что после вызова g_closure_invalidate user_data становится ненужным для closure, а значит, исходя из описания параметра destroy_data функции g_cclosure_new, функция 'destroy_data' должна быть вызвана.
Однако в реализации функция 'destroy_data' вызывается только при уничтожении самого closure, причем между вызовом(явным) g_closure_invalidate, и уничтожением closure в результате вызова g_closure_unref может пройти сколько угодно времени. Следовательно, реализация противоречит описанию в документации.
Раздел стандарта
Linux Standard Base Desktop Specification 4.0, Section 16.5. Interfaces for libgobject-2.0, который ссылается на 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); g_closure_invalidate(closure); if(!destroy_data_was_called) { printf("destroy_data wasn't called after invalidate.\n"); g_closure_unref(closure); return 1; } g_closure_unref(closure); return 0; }
Компонент
gtk-gobject-2.14
Принято
Gnome Bugzilla 614345
Статус
Reported
[В начало]