mot-agent: fixed crash issue due to emitting signal during worker thread
authorsaerome.kim <saerome.kim@samsung.com>
Wed, 25 Apr 2018 07:51:56 +0000 (16:51 +0900)
committersaerome.kim <saerome.kim@samsung.com>
Mon, 2 Jul 2018 10:38:50 +0000 (19:38 +0900)
operation.

Signed-off-by: saerome.kim <saerome.kim@samsung.com>
src/mot-agent/ma-subowner.c

index 8c2731d..381454f 100644 (file)
@@ -60,6 +60,7 @@ static const OicSecPrm_t  SUPPORTED_PRMS[2] = { PRM_PRE_CONFIGURED, PRM_RANDOM_P
 OCStackResult GetDoxmDevOwnerId(OicUuid_t *devownerid);
 
 typedef struct {
+       int ret; /** Result of command */
        ma_cmd_id_e cid; /**< Command ID */
        int tid; /**< Timer ID */
        int timeout; /**< Timeout value */
@@ -373,17 +374,17 @@ static void _request_cleanup(gpointer data)
        }
 }
 
-static void __notify_found_devs(void  *data)
+static gpointer ___notify_found_devs(gpointer data)
 {
        GVariantBuilder builder;
        GVariant* devices;
        OCProvisionDev_t *iter = NULL;
 
        ma_req_cb_s *con = (ma_req_cb_s *)data;
-       ma_check_null_ret("con", con);
+       ma_check_null_ret_error("con", con, NULL);
        ma_service *service = (ma_service *)con->userdata;
-       ma_check_null_ret("service", service);
-       ma_check_null_ret("g_client", g_client);
+       ma_check_null_ret_error("service", service, NULL);
+       ma_check_null_ret_error("g_client", g_client, NULL);
 
        /* g_mowned_list would be filled above request */
        g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
@@ -447,6 +448,24 @@ static void __notify_found_devs(void  *data)
 
        g_variant_builder_unref(&builder);
        g_variant_unref(devices);
+
+       _request_cleanup(con);
+       g_thread_exit(GINT_TO_POINTER(1));
+
+       return NULL;
+}
+
+static int __notify_found_devs(ma_req_cb_s *con)
+{
+       con->thread = g_thread_try_new("notify_devs", ___notify_found_devs, con, NULL);
+       if (!con->thread) {
+               MA_LOGE("Failed to create thread");
+               _request_cleanup(con);
+               return MA_ERROR_OUT_OF_MEMORY;
+       }
+       g_thread_unref(con->thread);
+
+       return MA_ERROR_NONE;
 }
 
 static void _disc_mot_env_devs_func(ma_req_cb_s *con)
@@ -462,15 +481,17 @@ static void _disc_mot_env_devs_func(ma_req_cb_s *con)
        _remove_mot_client();
 
        g_mutex_lock(&g_client->iotivity_mutex);
-       OCDiscoverMultipleOwnerEnabledDevices(con->timeout,
-                                                                                 &g_client->g_motdev_list);
+       OCDiscoverMultipleOwnerEnabledDevices(con->timeout, &g_client->g_motdev_list);
        g_mutex_unlock(&g_client->iotivity_mutex);
        if (OC_STACK_OK != ret) {
                MA_LOGE("OCDiscoverMultipleOwnerEnalbedDevices API error");
                goto DISC_MOT_ENB_DEVS_END;
        }
+
        __notify_found_devs(con);
 
+       return;
+
 DISC_MOT_ENB_DEVS_END:
        _request_cleanup(con);
 }
@@ -519,8 +540,11 @@ static void _disc_owned_devs_func(ma_req_cb_s *con)
                MA_LOGE("OCDiscoverMultipleOwnerEnabledDevices API error");
                goto DISC_OWNED_DEVS_END;
        }
+
        __notify_found_devs(con);
 
+       return;
+
 DISC_OWNED_DEVS_END:
        _request_cleanup(con);
 }
@@ -549,6 +573,68 @@ static int _disc_owned_devs(ma_service *service, int timeout)
        return MA_ERROR_NONE;
 }
 
+static gpointer ___notify_result(gpointer data)
+{
+       ma_req_cb_s *con = (ma_req_cb_s *)data;
+       ma_check_null_ret_error("con", con, NULL);
+       ma_service *service = (ma_service *)con->userdata;
+       ma_check_null_ret_error("service", service, NULL);
+       ma_check_null_ret_error("g_client", g_client, NULL);
+
+       switch (con->cid) {
+               case MA_DO_MOT:
+                       /* Notify ACL result  */
+                       net_ma_emit_acl_done(ma_dbus_get_object(), con->ret);
+                       break;
+               case MA_DO_ACL_PROVISIONING:
+                       net_ma_emit_acl_done(ma_dbus_get_object(), con->ret);
+                       break;
+               case MA_DO_CRED_PROVISIONING:
+                       net_ma_emit_cred_done(ma_dbus_get_object(), con->ret);
+                       break;
+               case MA_DO_RESOURCES_PAIRWISE:
+                       net_ma_emit_pairwise_done(ma_dbus_get_object(), con->ret);
+                       break;
+               case MA_REMOVE_MULTIPLE_OWNED_DEVICE:
+                       net_ma_emit_remove_mo_done(ma_dbus_get_object(), con->ret);
+                       break;
+               case MA_REMOVE_DEVICE_WITH_UUID_IN_SVR:
+                       net_ma_emit_remove_cred_local_done(ma_dbus_get_object(), con->ret);
+                       break;
+               case MA_UNLINK_RESOURCES:
+                       net_ma_emit_unpair_done(ma_dbus_get_object(), con->ret);
+                       break;
+               case MA_MAKE_PAIR:
+                       net_ma_emit_pair_done(ma_dbus_get_object(), con->ret);
+                       break;
+               case MA_MAKE_UNPAIR:
+                       net_ma_emit_unpair_done(ma_dbus_get_object(), con->ret);
+                       break;
+               default:
+                       break;
+       }
+
+       _request_cleanup(con);
+
+       g_thread_exit(GINT_TO_POINTER(1));
+
+       return NULL;
+}
+
+
+static int __notify_result(ma_req_cb_s *con)
+{
+       con->thread = g_thread_try_new("notify_result", ___notify_result, con, NULL);
+       if (!con->thread) {
+               MA_LOGE("Failed to create thread");
+               _request_cleanup(con);
+               return MA_ERROR_OUT_OF_MEMORY;
+       }
+       g_thread_unref(con->thread);
+
+       return MA_ERROR_NONE;
+}
+
 static void _mot_cb(void* ctx, int num, OCProvisionResult_t* arr, bool has_error)
 {
        ma_subowner_s *client = (ma_subowner_s *)ctx;
@@ -653,12 +739,12 @@ MOT_ENDED:
        src_dev->next = next_dev;
 #endif
 
-       net_ma_emit_mot_done(ma_dbus_get_object(), (int)ret);
+       /* Notify of MOT result */
+       con->ret = ret;
+       __notify_result(con);
 
        if (uuid_target)
                g_free(uuid_target);
-
-       _request_cleanup(con);
 }
 
 static int _mot(ma_service *service, gchar *uuid_str, gchar *pin)
@@ -864,8 +950,9 @@ static void _acl_provisioning_func(ma_req_cb_s *con)
        MA_LOGI(" Provisioned Selected ACL Successfully");
 
 PV_ACL_END:
-       /* Notify ACL result  */
-       net_ma_emit_acl_done(ma_dbus_get_object(), (int)ret);
+       /* Notify ACL result */
+       con->ret = ret;
+       __notify_result(con);
 
        if (acl)
                OCDeleteACLList(acl);
@@ -873,8 +960,6 @@ PV_ACL_END:
                g_free(uuid1);
        if (uuid2)
                g_free(uuid2);
-
-       _request_cleanup(con);
 }
 
 static int _acl_provisioning(ma_service *service, gchar *target, gchar *subject,
@@ -992,15 +1077,14 @@ PV_CRED_END:
        dev1->next = dev1_next;
        dev2->next = dev2_next;
 
-       /* Notify ACL result  */
-       net_ma_emit_cred_done(ma_dbus_get_object(), (int)ret);
+       /* Notify CRED provisiong result  */
+       con->ret = ret;
+       __notify_result(con);
 
        if (uuid1)
                g_free(uuid1);
        if (uuid2)
                g_free(uuid2);
-
-       _request_cleanup(con);
 }
 
 static int _cred_provisioning(ma_service *service,
@@ -1141,8 +1225,10 @@ static void _resources_pairwise_func(ma_req_cb_s *con)
        MA_LOGI(" Provision pairwise Done");
 
 PVPAIRWIE_ERROR:
-       /* Notify ACL result  */
-       net_ma_emit_pairwise_done(ma_dbus_get_object(), (int)ret);
+
+       /* Notify resource pairwise result  */
+       con->ret = ret;
+       __notify_result(con);
 
        if (uuid_1)
                g_free(uuid_1);
@@ -1156,8 +1242,6 @@ PVPAIRWIE_ERROR:
                OCDeleteACLList(acl_1);
        if (acl_2)
                OCDeleteACLList(acl_2);
-
-       _request_cleanup(con);
 }
 
 static int _resources_pairwise(ma_service *service, gchar *target_1,
@@ -1273,15 +1357,14 @@ static void _unlink_resources_func(ma_req_cb_s *con)
        MA_LOGI("Unlink Devices");
 
 PVUNLINKPAIRWISE_ERROR:
-       /* Notify ACL result  */
-       net_ma_emit_unpair_done(ma_dbus_get_object(), (int)ret);
+       /* Notify resource unpair result */
+       con->ret = ret;
+       __notify_result(con);
 
        if (uuid1)
                g_free(uuid1);
        if (uuid2)
                g_free(uuid2);
-
-       _request_cleanup(con);
 }
 
 static int _unlink_resources(ma_service *service,
@@ -1384,10 +1467,12 @@ static void _remove_subowner_func(ma_req_cb_s *con)
        MA_LOGI("Remove Multiple Ownership Done");
 
 REMOVE_SUBOWNER_ENDED:
-       net_ma_emit_remove_mo_done(ma_dbus_get_object(), (int)ret);
+       /* Notify remove multiple owner at the remote device */
+       con->ret = ret;
+       __notify_result(con);
+
        if (uuid_target)
                g_free(uuid_target);
-       _request_cleanup(con);
 }
 
 static int _ma_remove_subowner(ma_service *service, gchar *uuid_str)
@@ -1468,11 +1553,12 @@ static void _remove_device_func(ma_req_cb_s *con)
        MA_LOGI(" Removing CRED info. at local SVR DB - Done");
 
 REMOVE_DEVICE_END:
-       /* Notify ACL result  */
-       net_ma_emit_remove_cred_local_done(ma_dbus_get_object(), (int)ret);
+       /* Notify of result of removing CRED infor at local SVR DB  */
+       con->ret = ret;
+       __notify_result(con);
+
        if (uuid)
                g_free(uuid);
-       _request_cleanup(con);
 }
 
 static int _remove_device(ma_service *service, gchar *uuid_str)
@@ -1643,8 +1729,10 @@ PV_PAIR_END:
        /* Restore MOT enabled devices */
        if (src_dev)
                src_dev->next = next_dev ;
+
        /* Notify pair result  */
-       net_ma_emit_pair_done(ma_dbus_get_object(), (int)ret);
+       con->ret = ret;
+       __notify_result(con);
 
        if (uuid_1)
                g_free(uuid_1);
@@ -1658,8 +1746,6 @@ PV_PAIR_END:
                OCDeleteACLList(acl_1);
        if (acl_2)
                OCDeleteACLList(acl_2);
-
-       _request_cleanup(con);
 }
 
 static int _make_devices_pair(ma_service *service, gchar *pin, gchar *target_1,
@@ -1817,12 +1903,13 @@ static void _make_devices_unpair_func(ma_req_cb_s *con)
 
 PV_UNPAIR_END:
        /* Notify unpair result  */
-       net_ma_emit_unpair_done(ma_dbus_get_object(), (int)ret);
+       con->ret = ret;
+       __notify_result(con);
+
        if (owner_uuid)
                g_free(owner_uuid);
        if (owned_uuid)
                g_free(owned_uuid);
-       _request_cleanup(con);
 }
 
 static int _make_devices_unpair(ma_service *service, gchar *uuid_dev1, gchar *uuid_dev2)