Подробности

[В начало]

Проблема в реализации № 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

[В начало]