Add a logic to check activated thread before destroying tts client 64/239364/1
authorsooyeon.kim <sooyeon.kim@samsung.com>
Fri, 24 Jul 2020 07:40:49 +0000 (16:40 +0900)
committersooyeon.kim <sooyeon.kim@samsung.com>
Fri, 24 Jul 2020 07:40:49 +0000 (16:40 +0900)
Change-Id: I326f171deee0dee502a6ff062fd459d86cde2697
Signed-off-by: sooyeon.kim <sooyeon.kim@samsung.com>
client/tts.c
client/tts_client.c
client/tts_client.h

index 3305e74..d1ad656 100644 (file)
@@ -55,6 +55,7 @@ static char* g_engine_name = NULL;
 static char g_engine_appid[256];
 static int g_engine_update_status = 0;
 static pthread_mutex_t g_pkgmgr_mutex = PTHREAD_MUTEX_INITIALIZER;
+static Ecore_Thread* g_pkgmgr_thread = NULL;
 
 
 /* Function definition */
@@ -291,6 +292,14 @@ static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
 {
        SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] create pkgmgr thread");
 
+       tts_h tts = (tts_h)data;
+       tts_client_s* client = tts_client_get(tts);
+       /* check handle */
+       if (NULL == client) {
+               SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] client is null");
+               return ;
+       }
+
        pthread_mutex_lock(&g_pkgmgr_mutex);
 
        while (!g_pkgmgr) {
@@ -318,24 +327,38 @@ static void __create_pkgmgr_thread(void* data, Ecore_Thread* thread)
                        }
                }
                usleep(10000);
+
+               /* Checking handle which can be destroyed on other thread */
+               if (false == tts_client_is_valid(tts)) {
+                       SLOG(LOG_INFO, TAG_TTSC, "[INFO] client is already destroyed");
+                       break;
+               }
        }
 
        pthread_mutex_unlock(&g_pkgmgr_mutex);
-
        return ;
 }
 
 static void __finish_pkgmgr_thread(void* data, Ecore_Thread* thread)
 {
        SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] Finish pkgmgr thread");
+       g_pkgmgr_thread = NULL;
 }
 
 static void __pkgmgr_thread(void* data)
 {
        SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] call pkgmgr_thread");
 
-       ecore_thread_run(__create_pkgmgr_thread, __finish_pkgmgr_thread, NULL, NULL);
+       tts_h tts = (tts_h)data;
+       if (NULL == tts) {
+               SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input handle is null");
+               return ;
+       }
 
+       if (NULL == g_pkgmgr_thread) {
+               SLOG(LOG_INFO, TAG_TTSC, "[INFO] ecore thread run: create_pkgmgr_thread");
+               g_pkgmgr_thread = ecore_thread_run(__create_pkgmgr_thread, __finish_pkgmgr_thread, NULL, tts);
+       }
        return ;
 }
 
@@ -447,7 +470,7 @@ int tts_create(tts_h* tts)
                return __tts_convert_config_error_code(ret);
        }
 
-       ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, NULL);
+       ecore_main_loop_thread_safe_call_async(__pkgmgr_thread, *tts);
 
        SLOG(LOG_INFO, TAG_TTSC, "[INFO] call ecore thread for creating pkgmgr thread");
 
@@ -564,8 +587,23 @@ int tts_destroy(tts_h tts)
                /* Unset registered callbacks */
                __tts_unset_all_callbacks(tts);
 
+               /* Check threads */
+               int thread_count = ecore_thread_active_get();
+               SLOG(LOG_INFO, TAG_TTSC, "[INFO] Active thread count: %d", thread_count);
+               int cnt = 0;
+               while (0 < thread_count) {
+                       usleep(50000);
+                       cnt++;
+                       if (30 == cnt) {
+                               SLOG(LOG_WARN, TAG_TTSC, "[WARNNING] Thread is blocked, %d", thread_count);
+                               break;
+                       }
+                       thread_count = ecore_thread_active_get();
+               }
+
                /* Free resources */
                tts_client_destroy(tts);
+
                break;
 
        default:
@@ -2471,15 +2509,23 @@ static void __start_reprepare_thread(void* data, Ecore_Thread* thread)
 {
        SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] start reprepare thread. engine update status(%d)", g_engine_update_status);
 
-       tts_client_s* temp = (tts_client_s*)data;
-       if (NULL == temp) {
-               SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] data is null");
-               return ;
+       tts_h tts = (tts_h)data;
+       tts_client_s* client = tts_client_get(tts);
+       /* check handle */
+       if (NULL == client) {
+               SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] client is null");
+               return;
        }
 
        int cnt = 0;
-       while (!g_engine_update_status && (cnt < 10)) {
+       while (!g_engine_update_status && cnt < 20) {
                SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for starting update");
+               /* Checking handle which can be destroyed on other thread */
+               if (false == tts_client_is_valid(tts)) {
+                       SLOG(LOG_INFO, TAG_TTSC, "[INFO] client is already destroyed");
+                       return;
+               }
+
                usleep(50000);
                cnt++;
        }
@@ -2487,13 +2533,18 @@ static void __start_reprepare_thread(void* data, Ecore_Thread* thread)
        SLOG(LOG_ERROR, TAG_TTSC, "[DEBUG] update status(%d)", g_engine_update_status);
 
        while (g_engine_update_status && (NULL != g_pkgmgr)) {
-//             SLOG(LOG_WARN, TAG_TTSC, "[WARNING] wait for finishing update");
+               /* Checking handle which can be destroyed on other thread */
+               if (false == tts_client_is_valid(tts)) {
+                       SLOG(LOG_INFO, TAG_TTSC, "[INFO] client is already destroyed");
+                       return;
+               }
+
                usleep(200000);
        }
 
        SLOG(LOG_INFO, TAG_TTSC, "[INFO] finish updating. request to prepare");
 
-       if (0 != tts_prepare(temp->tts)) {
+       if (0 != tts_prepare(client->tts)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare");
        }
 
index 0ed68a8..8ff1a29 100644 (file)
@@ -242,6 +242,16 @@ tts_client_s* tts_client_get_by_uid(const int uid)
        return NULL;
 }
 
+bool tts_client_is_valid(tts_h tts)
+{
+       tts_client_s* client = tts_client_get(tts);
+       if (NULL == client) {
+               SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
+               return false;
+       }
+       return true;
+}
+
 int tts_client_get_size()
 {
        pthread_mutex_lock(&g_client_list_mutex);
index 67b61d2..ce6989c 100644 (file)
@@ -82,6 +82,8 @@ tts_client_s* tts_client_get(tts_h tts);
 
 tts_client_s* tts_client_get_by_uid(const int uid);
 
+bool tts_client_is_valid(tts_h tts);
+
 int tts_client_get_size();
 
 int tts_client_use_callback(tts_client_s* client);