From 79150acb1e20f0d13d7fbb16e8f6e8b04d1c4ea8 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 17 Oct 2018 13:20:36 +0900 Subject: [PATCH] Fixed a bug about finding callback function Change-Id: If81fb645267dd181e56bf2cf3a4d40f0bfcf4cf3 Signed-off-by: Hwankyu Jhun --- src/eventsystem.c | 288 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 151 insertions(+), 137 deletions(-) diff --git a/src/eventsystem.c b/src/eventsystem.c index 90e7e91..aea30f5 100755 --- a/src/eventsystem.c +++ b/src/eventsystem.c @@ -83,6 +83,7 @@ typedef struct eventmap { eventsystem_cb es_cb; eventsystem_handler ep_cb; }; + void *user_data; } eventmap_s; typedef struct eventinfo { @@ -108,14 +109,10 @@ static int __eventsystem_check_user_send_validation(const char *event_name); static int __eventsystem_requet_destination_list(const char *event_name, GList **dest_list); static int __eventsystem_check_sender_validation(int sender_pid, const char *event_name, char **sender); - -static int __event_compare_name_cb(gconstpointer a, gconstpointer b) -{ - eventmap_s *key1 = (eventmap_s *)a; - eventmap_s *key2 = (eventmap_s *)b; - return strcmp(key1->interface_name, key2->interface_name) | - strcmp(key1->member_name, key2->member_name); -} +static eventmap_s *__create_eventmap(const char *interface_name, + const char *member_name, const char *event_name, + int event_type, eventsystem_cb callback, void *user_data); +static void __destroy_eventmap(gpointer data); static int __event_compare_reg_id_cb(gconstpointer a, gconstpointer b) { @@ -468,19 +465,20 @@ static void __eventsystem_event_handler(GDBusConnection *connection, GVariant *parameters, gpointer user_data) { int len; - eventmap_s em; + eventmap_s *em = (eventmap_s *)user_data; GList *cb_list = NULL; bundle *buf = NULL; bundle_raw *raw = NULL; - em.interface_name = (char *)interface_name; - em.member_name = (char *)signal_name; + if (!em) { + _E("Critical error!"); + return; + } _D("sender_name(%s), interface_name(%s), signal_name(%s)", sender_name, interface_name, signal_name); - cb_list = g_list_find_custom(system_event_list, &em, - (GCompareFunc)__event_compare_name_cb); + cb_list = g_list_find(system_event_list, em); if (cb_list == NULL) return; @@ -488,10 +486,8 @@ static void __eventsystem_event_handler(GDBusConnection *connection, buf = bundle_decode((bundle_raw *)raw, len); - em.event_name = ((eventmap_s *)cb_list->data)->event_name; - em.ep_cb = ((eventmap_s *)cb_list->data)->ep_cb; - if (em.ep_cb) - em.ep_cb(em.event_name, buf, user_data); + if (em->ep_cb) + em->ep_cb(em->event_name, buf, em->user_data); bundle_free_encoded_rawdata(&raw); bundle_free(buf); @@ -501,36 +497,33 @@ static void __eventsystem_application_event_handler(int sender_pid, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { - GList *cb_list = NULL; - eventmap_s em; + GList *cb_list; + eventmap_s *em = (eventmap_s *)user_data; bundle_raw *raw = NULL; int len; - em.interface_name = (char *)interface_name; - em.member_name = (char *)signal_name; - - cb_list = g_list_find_custom(system_event_list, &em, - (GCompareFunc)__event_compare_name_cb); + if (!em) { + _E("Critical error!"); + return; + } + cb_list = g_list_find(system_event_list, em); if (cb_list == NULL) { _E("not interested event"); return; } - em.event_name = ((eventmap_s *)cb_list->data)->event_name; - if (sender_pid > 0 && __check_interface_validation_user((char *)interface_name)) { if (__check_validation_usrevent_sender(sender_pid, - (const char *)interface_name, em.event_name) < 0) { + (const char *)interface_name, em->event_name) < 0) { _E("invalid sender"); return; } } g_variant_get(parameters, "(us)", &len, &raw); - em.es_cb = ((eventmap_s *)cb_list->data)->es_cb; - if (em.es_cb) - em.es_cb(em.event_name, raw, len, user_data); + if (em->es_cb) + em->es_cb(em->event_name, raw, len, em->user_data); bundle_free_encoded_rawdata(&raw); } @@ -612,10 +605,10 @@ static void __eventsystem_filter_sysevent_for_internal(GDBusConnection *connecti static int __eventsystem_register_event_internal(const char *event_name, eventmap_s **em_s, void *user_data) { - eventmap_s *em = NULL; - char *interface_name = NULL; - char *object_path = NULL; - char *member_name = NULL; + eventmap_s *em; + char *interface_name; + char *object_path; + char *member_name; char *sender_name = NULL; GDBusSignalCallback filter; GBusType bus_type; @@ -691,6 +684,13 @@ static int __eventsystem_register_event_internal(const char *event_name, goto out_4; } + em = __create_eventmap(interface_name, member_name, event_name, + evt_type, NULL, user_data); + if (!em) { + ret = ES_R_ENOMEM; + goto out_4; + } + subscription_id = g_dbus_connection_signal_subscribe(conn, sender_name, /* sender */ interface_name, @@ -699,7 +699,7 @@ static int __eventsystem_register_event_internal(const char *event_name, NULL, /* arg0 */ G_DBUS_SIGNAL_FLAGS_NONE, filter, - user_data, + em, NULL); /* user_data_free_func */ _D("event_name(%s), interface_name(%s)", event_name, interface_name); @@ -707,33 +707,14 @@ static int __eventsystem_register_event_internal(const char *event_name, member_name, subscription_id, bus_type); if (subscription_id != 0) { - em = calloc(1, sizeof(eventmap_s)); - if (!em) { - _E("memory alloc failed"); - ret = ES_R_ENOMEM; - } else { - em->interface_name = strdup(interface_name); - em->member_name = strdup(member_name); - em->event_name = strdup(event_name); - em->bus_type = bus_type; - em->reg_id = subscription_id; - em->event_type = evt_type; - - if (!em->interface_name || !em->member_name || !em->event_name) { - _E("out_of_memory"); - FREE_AND_NULL(em->interface_name); - FREE_AND_NULL(em->member_name); - FREE_AND_NULL(em->event_name); - FREE_AND_NULL(em); - ret = ES_R_ENOMEM; - goto out_4; - } + em->bus_type = bus_type; + em->reg_id = subscription_id; - *em_s = em; - ret = ES_R_OK; - } + *em_s = em; + ret = ES_R_OK; } else { _D("dbus subscribe: error(%d), event(%s)", subscription_id, event_name); + __destroy_eventmap(em); ret = ES_R_ERROR; } @@ -816,10 +797,7 @@ int eventsystem_unregister_event(unsigned int reg_id) system_event_list = g_list_remove(system_event_list, cb_list->data); - FREE_AND_NULL(em_data->interface_name); - FREE_AND_NULL(em_data->member_name); - FREE_AND_NULL(em_data->event_name); - FREE_AND_NULL(em_data); + __destroy_eventmap(em_data); g_object_unref(conn); } @@ -1725,17 +1703,73 @@ int eventsystem_keep_last_event_data(const char *event_name) return ret; } +static void __destroy_eventmap(gpointer data) +{ + eventmap_s *em = (eventmap_s *)data; + + if (!em) + return; + + if (em->interface_name) + free(em->interface_name); + if (em->member_name) + free(em->member_name); + if (em->event_name) + free(em->event_name); + free(em); +} + +static eventmap_s *__create_eventmap(const char *interface_name, + const char *member_name, const char *event_name, + int event_type, eventsystem_cb callback, void *user_data) +{ + eventmap_s *em; + + em = calloc(1, sizeof(eventmap_s)); + if (!em) { + _E("Out of memory"); + return NULL; + } + + em->interface_name = strdup(interface_name); + if (!em->interface_name) { + _E("Failed to duplicate interface name"); + __destroy_eventmap(em); + return NULL; + } + + em->member_name = strdup(member_name); + if (!em->member_name) { + _E("Failed to duplicate member name"); + __destroy_eventmap(em); + return NULL; + } + + em->event_name = strdup(event_name); + if (!em->event_name) { + _E("Failed to duplicate event name"); + __destroy_eventmap(em); + return NULL; + } + + em->event_type = event_type; + em->es_cb = callback; + em->user_data = user_data; + + return em; +} + int eventsystem_register_application_event(const char *event_name, unsigned int *reg_id, int *event_type, eventsystem_cb callback, void *user_data) { eventmap_s *em; - char *interface_name = NULL; - char *object_path = NULL; - char *member_name = NULL; + char *interface_name; + char *object_path; + char *member_name; char *sender_name = NULL; GDBusSignalCallback filter; GBusType bus_type; - guint subscription_id = 0; + guint subscription_id = 0; int ret = 0; GDBusConnection *conn = NULL; @@ -1805,9 +1839,8 @@ int eventsystem_register_application_event(const char *event_name, unsigned int object_path = __get_object_path(interface_name); if (!object_path) { _E("failed get object_path"); - FREE_AND_NULL(interface_name); - FREE_AND_NULL(member_name); - return ES_R_ERROR; + ret = ES_R_ERROR; + goto end; } sender_name = NULL; @@ -1817,16 +1850,21 @@ int eventsystem_register_application_event(const char *event_name, unsigned int if (__get_gdbus_shared_connection(&conn, bus_type, *event_type) < 0) { _E("getting gdbus-connetion error"); - FREE_AND_NULL(interface_name); - FREE_AND_NULL(object_path); - FREE_AND_NULL(member_name); - return ES_R_ERROR; + ret = ES_R_ERROR; + goto end; } #ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE __eventsystem_request_earlier_data(event_name, callback, user_data); #endif + em = __create_eventmap(interface_name, member_name, event_name, + *event_type, callback, user_data); + if (!em) { + ret = ES_R_ENOMEM; + goto end; + } + subscription_id = g_dbus_connection_signal_subscribe(conn, sender_name, /* sender */ interface_name, @@ -1835,77 +1873,56 @@ int eventsystem_register_application_event(const char *event_name, unsigned int NULL, /* arg0 */ G_DBUS_SIGNAL_FLAGS_NONE, filter, - user_data, + em, NULL); /* user_data_free_func */ _D("event_name(%s), subscription_id(%d)", event_name, subscription_id); if (subscription_id != 0) { - em = calloc(1, sizeof(eventmap_s)); - if (!em) { - _E("memory alloc failed"); - ret = ES_R_ENOMEM; - } else { - em->interface_name = strdup(interface_name); - em->member_name = strdup(member_name); - em->event_name = strdup(event_name); - em->es_cb = callback; - em->bus_type = bus_type; - em->reg_id = subscription_id; - em->event_type = *event_type; - - if (!em->interface_name || !em->member_name || - !em->event_name) { - _E("out_of_memory"); - FREE_AND_NULL(em->interface_name); - FREE_AND_NULL(em->member_name); - FREE_AND_NULL(em->event_name); - FREE_AND_NULL(em); - ret = ES_R_ENOMEM; + em->bus_type = bus_type; + em->reg_id = subscription_id; + + system_event_list = g_list_append(system_event_list, em); + *reg_id = subscription_id; + + ret = ES_R_OK; + + if (em->bus_type == G_BUS_TYPE_SESSION && + em->event_type == ES_TYPE_USER) { + if (s_info.own_name_session_bus == NULL) { + _E("session bus is not ready"); + ret = ES_R_ERROR; } else { - system_event_list = - g_list_append(system_event_list, em); - *reg_id = subscription_id; - - ret = ES_R_OK; - - if (em->bus_type == G_BUS_TYPE_SESSION && - em->event_type == ES_TYPE_USER) { - if (s_info.own_name_session_bus == NULL) { - _E("session bus is not ready"); - ret = ES_R_ERROR; - } else { - if (__eventsystem_setup_trusted_peer(event_name, + if (__eventsystem_setup_trusted_peer(event_name, s_info.own_name_session_bus) < 0) { - _E("failed to setup trusted peer"); - ret = ES_R_ERROR; - } - } + _E("failed to setup trusted peer"); + ret = ES_R_ERROR; } } } } else { _E("dbus subscribe: error(%d)", subscription_id); + __destroy_eventmap(em); ret = ES_R_ERROR; } + __request_esd_for_last_data(event_name, true); +end: FREE_AND_NULL(interface_name); FREE_AND_NULL(object_path); FREE_AND_NULL(member_name); if (conn) g_object_unref(conn); - __request_esd_for_last_data(event_name, true); - return ret; } int eventsystem_unregister_application_event(unsigned int reg_id) { eventmap_s em; - eventmap_s *em_data = NULL; + eventmap_s *em_data; GBusType bus_type; - GList *cb_list = NULL; + GList *cb_list; GDBusConnection *conn = NULL; eventsystem_event_type evt_type; @@ -1916,32 +1933,29 @@ int eventsystem_unregister_application_event(unsigned int reg_id) em.reg_id = reg_id; cb_list = g_list_find_custom(system_event_list, &em, - (GCompareFunc)__event_compare_reg_id_cb); - if (cb_list) { - em_data = (eventmap_s *)cb_list->data; + (GCompareFunc)__event_compare_reg_id_cb); + if (!cb_list) { + _E("not found matched item"); + return ES_R_ERROR; + } - bus_type = em_data->bus_type; - evt_type = em_data->event_type; + em_data = (eventmap_s *)cb_list->data; - _D("unsubscribe: reg_id(%d), bus_type(%d)", reg_id, bus_type); + bus_type = em_data->bus_type; + evt_type = em_data->event_type; - if (__get_gdbus_shared_connection(&conn, bus_type, evt_type) < 0) { - _E("getting gdbus-connetion error"); - return ES_R_ERROR; - } - g_dbus_connection_signal_unsubscribe(conn, reg_id); + _D("unsubscribe: reg_id(%d), bus_type(%d)", reg_id, bus_type); - system_event_list = g_list_remove(system_event_list, cb_list->data); - - FREE_AND_NULL(em_data->interface_name); - FREE_AND_NULL(em_data->member_name); - FREE_AND_NULL(em_data->event_name); - FREE_AND_NULL(em_data); - g_object_unref(conn); - } else { - _E("not found matched item"); + if (__get_gdbus_shared_connection(&conn, bus_type, evt_type) < 0) { + _E("getting gdbus-connetion error"); return ES_R_ERROR; } + g_dbus_connection_signal_unsubscribe(conn, reg_id); + + system_event_list = g_list_remove(system_event_list, cb_list->data); + + __destroy_eventmap(em_data); + g_object_unref(conn); return ES_R_OK; } -- 2.7.4