From: Tom Hacohen Date: Mon, 28 Sep 2015 23:45:34 +0000 (+0100) Subject: Eo legacy events: Fix broken callback comparison X-Git-Tag: v1.16.0-alpha1~76 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d889da6b12e6123073edb54d766c9af1fc6db822;p=platform%2Fupstream%2Fefl.git Eo legacy events: Fix broken callback comparison Commit 37f84b7e966372384e2dfe5d191a6f907a17962e introduced a few changes to the callback matching mechanism that made it so sometimes callbacks would be triggered for the wrong events. The problem was there because of the support for legacy events that forces to do string comparison instead of the usual pointer comparison. We should only do string comparison when we are certain one of the callbacks is a legacy generated one. Regression tests will follow tomorrow. Way too late here for that. Thanks to cedric for reporting. --- diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 3f551f4..66be6ff 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -919,6 +919,8 @@ typedef void (*eo_key_data_free_func)(void *); /** * Don't use. + * The values of the returned event structure are also internal, don't assume + * anything about them. * @internal */ EAPI const Eo_Event_Description *eo_base_legacy_only_event_description_get(const char *_event_name); diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c index f85aa4e..f0a4030 100644 --- a/src/lib/eo/eo_base_class.c +++ b/src/lib/eo/eo_base_class.c @@ -401,11 +401,16 @@ _wref_destruct(Eo_Base_Data *pd) /* XXX: Legacy support, remove when legacy is dead. */ static Eina_Hash *_legacy_events_hash = NULL; +#define _LEGACY_EVENT_FIRST_CHAR 1 EAPI const Eo_Event_Description * eo_base_legacy_only_event_description_get(const char *_event_name) { - Eina_Stringshare *event_name = eina_stringshare_add(_event_name); + char buf[1024]; + buf[0] = _LEGACY_EVENT_FIRST_CHAR; /* Encode it's a legacy event */ + strncpy(buf + 1, _event_name, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + Eina_Stringshare *event_name = eina_stringshare_add(buf); Eo_Event_Description *event_desc = eina_hash_find(_legacy_events_hash, event_name); if (!event_desc) { @@ -421,6 +426,26 @@ eo_base_legacy_only_event_description_get(const char *_event_name) return event_desc; } +static Eina_Bool +_legacy_event_desc_is(const Eo_Event_Description *desc) +{ + return (desc->name[0] == _LEGACY_EVENT_FIRST_CHAR); +} + +/* Also supports non legacy. */ +static const char * +_legacy_event_desc_name_get(const Eo_Event_Description *desc) +{ + if (_legacy_event_desc_is(desc)) + { + return desc->name + 1; + } + else + { + return desc->name; + } +} + static void _legacy_events_hash_free_cb(void *_desc) { @@ -641,13 +666,19 @@ _cb_desc_match(const Eo_Event_Description *a, const Eo_Event_Description *b) if (!a) return EINA_FALSE; - if (a == b) + if (_legacy_event_desc_is(a) && _legacy_event_desc_is(b)) + { + return (a->name == b->name); + } + else if (_legacy_event_desc_is(a) || _legacy_event_desc_is(b)) { - return EINA_TRUE; + const char *aname = _legacy_event_desc_name_get(a); + const char *bname = _legacy_event_desc_name_get(b); + return !strcmp(aname, bname); } else { - return !strcmp(a->name, b->name); + return (a == b); } } diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c index ccd6af2..b483a80 100644 --- a/src/tests/eo/suite/eo_test_general.c +++ b/src/tests/eo/suite/eo_test_general.c @@ -125,12 +125,12 @@ START_TEST(eo_signals) { const Eo_Event_Description *a_desc = eo_base_legacy_only_event_description_get("a,changed"); fail_if(!a_desc); - ck_assert_str_eq(a_desc->name, "a,changed"); + ck_assert_str_eq(a_desc->name, "\x01" "a,changed"); fail_if(a_desc == EV_A_CHANGED); const Eo_Event_Description *bad_desc = eo_base_legacy_only_event_description_get("bad"); fail_if(!bad_desc); - ck_assert_str_eq(bad_desc->name, "bad"); + ck_assert_str_eq(bad_desc->name, "\x01" "bad"); /* Call Eo event with legacy and non-legacy callbacks. */ _eo_signals_cb_current = 0;