Подробности
[В начало]
Проблема в реализации № S0567
Краткое описание
Функция atk_object_connect_property_change_handler: guint вместо gulong
Подробное описание
atk_object_connect_property_change_handler возвращает идентификатор в виде guint. Но в своей реализации она использует g_signal_connect_closure_by_id, которая возвращает идентификатор в виде gulong.
Соответственно, если этот идентификатор будет превышать максимальное значение guint, то идентификатор, возвращаемый atk_object_connect_property_change_handler будет непригоден для использования в atk_object_remove_property_change_handler, которая вызывает g_signal_closure_disconnect для удаления handler'a по id(типа gulong).
На архитектурах, где sizeof(int) < sizeof(long), следующий код(см. пример) покажет, что соответствие функций atk_object_connect_property_change_handler и atk_object_remove_property_change_handler стандарту нарушается.
Аналогичная проблема у функций atk_component_add_focus_handler и atk_component_remove_focus_handler.
Раздел стандарта
ATK 1.9.0 Reference Manual, AtkObject.
Пример
#include <stdio.h> #include <atk/atk.h> #include <limits.h> gboolean handler_was_called; void handler(AtkObject* object, AtkPropertyValues* prop_values) { handler_was_called = TRUE; } void handler_test(AtkObject* object, AtkPropertyValues* prop_values){} int main() { g_type_init(); AtkObject* obj = g_object_new(ATK_TYPE_OBJECT, NULL); guint handler_id = atk_object_connect_property_change_handler( obj,(AtkPropertyChangeHandler*)handler_test); gulong number_of_cycles = (sizeof(guint) != sizeof(gulong)) ? (G_MAXUINT - 1): 10000000; //Cycle of connecting and removing handlers, for increasing id. printf("Number of iterations is %ld ...\n", number_of_cycles); gulong i; for(i = number_of_cycles; i > 0 ;i --) { guint handler_id_tmp = atk_object_connect_property_change_handler( obj, (AtkPropertyChangeHandler*)handler_test); atk_object_remove_property_change_handler( obj, handler_id); handler_id = handler_id_tmp; } printf("...Cycle finished.\n"); atk_object_remove_property_change_handler(obj, handler_id); // handler_id = atk_object_connect_property_change_handler( obj,(AtkPropertyChangeHandler*)handler); printf("Now id of connected handler is %d.\n", handler_id); printf("And after call of \ atk_object_remove_property_change_handler(%d)\n", handler_id); atk_object_remove_property_change_handler( obj, handler_id); handler_was_called = FALSE; g_object_set(obj, "accessible-name", "some name", NULL); if(handler_was_called) { printf("the handler is still called "); } else { printf("the handler is not called any more "); } printf("when the property changes value.\n"); return 0; }
Компонент
gtk-atk 1.9.0 or later
Окружение
Архитектуры
x86_64, ia64, ppc64, s390X
Принято
Gnome Bugzilla 477705
[В начало]