Fix multi-thread issue 59/256559/1
authorjusung <jusung07.son@samsung.com>
Wed, 7 Apr 2021 05:18:44 +0000 (14:18 +0900)
committerjusung <jusung07.son@samsung.com>
Wed, 7 Apr 2021 05:20:18 +0000 (14:20 +0900)
Change-Id: Ia4a5722c37ebe706e2f424aa6a551f24a3109ce3
Signed-off-by: jusung <jusung07.son@samsung.com>
src/data_control_internal.c

index 40a706c..d007146 100644 (file)
@@ -101,10 +101,18 @@ static GHashTable *__checked_consumer_hash;
 static GDBusConnection *_gdbus_conn;
 
 static pthread_mutex_t __data_control_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t __data_control_socket_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /* 100 milliseconds */
 const struct timespec TRY_SLEEP_TIME = { 0, 100 * 1000 * 1000 };
 
+void __remove_socket_pair_hash(const char *provider_id)
+{
+       pthread_mutex_lock(&__data_control_socket_mutex);
+       g_hash_table_remove(__socket_pair_hash, provider_id);
+       pthread_mutex_unlock(&__data_control_socket_mutex);
+}
+
 int __get_unique_handle_id(void)
 {
        static int id = 0;
@@ -1197,7 +1205,7 @@ error:
 
        if (((__response_cb_s *)data) != NULL) {
                _dc = (__response_cb_s *)data;
-               g_hash_table_remove(__socket_pair_hash, _dc->provider_id);
+               __remove_socket_pair_hash(_dc->provider_id);
 
                itr = g_list_first(_dc->request_info_list);
                while (itr != NULL) {
@@ -1599,6 +1607,7 @@ int _request_provider(data_control_h provider, datacontrol_request_type type,
        const struct timespec TRY_SLEEP_TIME = { 0, 1000 * 1000 * 1000 };
        bundle *send_data;
        char *socket_hash_key;
+       int socket;
 
        _LOGI("Data control request, type: %d, request id: %d", type, request_id);
 
@@ -1669,6 +1678,7 @@ int _request_provider(data_control_h provider, datacontrol_request_type type,
        _LOGI("caller_id %s, app_id %s", caller_app_id, app_id);
 
        do {
+               pthread_mutex_lock(&__data_control_socket_mutex);
                datacontrol_socket_info *socket_info =
                        g_hash_table_lookup(__socket_pair_hash, provider->provider_id);
                if (socket_info == NULL) {
@@ -1678,6 +1688,7 @@ int _request_provider(data_control_h provider, datacontrol_request_type type,
                                        &socket_info);
                        if (ret != DATA_CONTROL_ERROR_NONE) {
                                bundle_free(send_data);
+                               pthread_mutex_unlock(&__data_control_socket_mutex);
                                return ret;
                        }
 
@@ -1686,6 +1697,7 @@ int _request_provider(data_control_h provider, datacontrol_request_type type,
                                bundle_free(send_data);
                                _socket_info_free((gpointer)socket_info);
                                _LOGE("Out of memory");
+                               pthread_mutex_unlock(&__data_control_socket_mutex);
                                return DATA_CONTROL_ERROR_OUT_OF_MEMORY;
                        }
 
@@ -1694,6 +1706,7 @@ int _request_provider(data_control_h provider, datacontrol_request_type type,
                                bundle_free(send_data);
                                _socket_info_free((gpointer)socket_info);
                                free(socket_hash_key);
+                               pthread_mutex_unlock(&__data_control_socket_mutex);
                                return ret;
                        }
 
@@ -1701,13 +1714,17 @@ int _request_provider(data_control_h provider, datacontrol_request_type type,
                                        socket_hash_key, socket_info);
                }
 
+               socket = socket_info->socket_fd;
+               pthread_mutex_unlock(&__data_control_socket_mutex);
+
                _LOGI("send data from consumer");
-               ret = __datacontrol_send_async(socket_info->socket_fd, send_data,
+               ret = __datacontrol_send_async(socket, send_data,
                                extra_data, type, NULL);
                if (ret != DATA_CONTROL_ERROR_NONE)
-                       g_hash_table_remove(__socket_pair_hash, provider->provider_id);
+                       __remove_socket_pair_hash(provider->provider_id);
                else
                        break;
+
                count++;
                nanosleep(&TRY_SLEEP_TIME, 0);
        } while (ret != DATA_CONTROL_ERROR_NONE && count < TRY_COUNT);
@@ -1993,7 +2010,7 @@ int _unregister_response_cb(data_control_h provider, bool is_bind,
 
                if (has_bound_cb == NULL && _dc_temp->registered_cb == NULL) {
                        g_hash_table_remove(__response_table, provider->provider_id);
-                       g_hash_table_remove(__socket_pair_hash, provider->provider_id);
+                       __remove_socket_pair_hash(provider->provider_id);
                        _LOGI("All of registered callback was removed");
                }
        }