Fix deadlock when event_callback within an API scope 72/244272/2
authorNishant Chaprana <n.chaprana@samsung.com>
Wed, 16 Sep 2020 12:34:38 +0000 (18:04 +0530)
committerNishant Chaprana <n.chaprana@samsung.com>
Thu, 17 Sep 2020 06:20:16 +0000 (11:50 +0530)
The deadlock occurs when connection_close_profile() is called
when profile is in connecting state at libnet-client.

Code flow is as below:-
connection_close_profile
 -> _connection_libnet_close_profile
     -> net_close_connection
now  if (is_connecting == TRUE), then event callback is triggered
within connection_close_profile() scope via __net_abort_open_connection()

Change-Id: I92781b907625d541914b602b6449135d74d490db
Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
packaging/capi-network-connection.spec
src/libnetwork.c

index 3578120..dcdb33e 100755 (executable)
@@ -1,6 +1,6 @@
 Name:          capi-network-connection
 Summary:       Network Connection library in TIZEN C API
-Version:       1.0.119
+Version:       1.0.120
 Release:       1
 Group:         System/Network
 License:       Apache-2.0
index a3d9ed8..89d3cdb 100755 (executable)
@@ -27,6 +27,7 @@
 static GSList *prof_handle_list = NULL;
 static GHashTable *profile_cb_table = NULL;
 static pthread_mutex_t g_conn_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
+static __thread int g_conn_thread_mutex_ref = 0;
 
 struct _profile_cb_s {
        connection_profile_state_changed_cb callback;
@@ -1542,10 +1543,24 @@ int _connection_libnet_get_tcpdump_state(connection_handle_s *conn_handle,
 
 void _connection_lock(void)
 {
-       pthread_mutex_lock(&g_conn_thread_mutex);
+       if (g_conn_thread_mutex_ref == 0)
+               pthread_mutex_lock(&g_conn_thread_mutex);
+
+       g_conn_thread_mutex_ref++;
 }
 
 void _connection_unlock(void)
 {
-       pthread_mutex_unlock(&g_conn_thread_mutex);
+       if (g_conn_thread_mutex_ref == 1)
+               pthread_mutex_unlock(&g_conn_thread_mutex);
+
+       g_conn_thread_mutex_ref--;
+
+//LCOV_EXCL_START
+       if (g_conn_thread_mutex_ref < 0) {
+               CONNECTION_LOG(CONNECTION_ERROR,
+                               "Error scenario, thread specific mutex ref is negative !!!");
+               g_conn_thread_mutex_ref = 0;
+       }
+//LCOV_EXCL_STOP
 }