Add mutex lock for global variables in tts_client 09/231109/2
authorSuyeon Hwang <stom.hwang@samsung.com>
Fri, 17 Apr 2020 08:23:50 +0000 (17:23 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Thu, 9 Jul 2020 09:03:27 +0000 (18:03 +0900)
Global varaibles, g_client_list and g_allocated_handle, can occur thread safety issue, because
any threads can access these variables.

This patch makes mutex lock for these variables to avoid thread safety issue.

Change-Id: I7ce1adf0c625715b619573d130408f0924da9785
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
client/tts_client.c

index 570910bb6e12645544c6cae3487b2dcf1040d0f7..f0f0a823ea210134d69cc6cf45a3ce79e45106e0 100644 (file)
@@ -1,5 +1,5 @@
 /*
-*  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved 
+*  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
@@ -21,9 +21,16 @@ static int g_allocated_handle = 0;
 /* client list */
 static GList *g_client_list = NULL;
 
+/* pthread mutex */
+static pthread_mutex_t g_allocated_handle_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t g_client_list_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 /* private functions */
 static int __client_generate_uid(int pid)
 {
+       int uid = 0;
+
+       pthread_mutex_lock(&g_allocated_handle_mutex);
        g_allocated_handle++;
 
        if (g_allocated_handle > g_max_handle) {
@@ -31,7 +38,10 @@ static int __client_generate_uid(int pid)
        }
 
        /* generate uid, handle number should be smaller than 1000 */
-       return pid * 1000 + g_allocated_handle;
+       uid = pid * 1000 + g_allocated_handle;
+       pthread_mutex_unlock(&g_allocated_handle_mutex);
+
+       return uid;
 }
 
 int tts_client_new(tts_h* tts)
@@ -48,11 +58,11 @@ int tts_client_new(tts_h* tts)
                free(client);
                return TTS_ERROR_OUT_OF_MEMORY;
        }
-       temp->handle = __client_generate_uid(getpid()); 
+       temp->handle = __client_generate_uid(getpid());
 
        /* initialize client data */
        client->tts = temp;
-       client->pid = getpid(); 
+       client->pid = getpid();
        client->uid = temp->handle;
        client->current_utt_id = 0;
 
@@ -72,8 +82,8 @@ int tts_client_new(tts_h* tts)
        client->supported_voice_user_data = NULL;
 
        client->mode = TTS_MODE_DEFAULT;
-       client->before_state = TTS_STATE_CREATED; 
-       client->current_state = TTS_STATE_CREATED; 
+       client->before_state = TTS_STATE_CREATED;
+       client->current_state = TTS_STATE_CREATED;
 
        client->cb_ref_count = 0;
 
@@ -90,7 +100,9 @@ int tts_client_new(tts_h* tts)
 
        client->text_repeat = NULL;
 
+       pthread_mutex_lock(&g_client_list_mutex);
        g_client_list = g_list_append(g_client_list, client);
+       pthread_mutex_unlock(&g_client_list_mutex);
 
        *tts = temp;
 
@@ -109,6 +121,7 @@ int tts_client_destroy(tts_h tts)
        GList *iter = NULL;
        tts_client_s *data = NULL;
 
+       pthread_mutex_lock(&g_client_list_mutex);
        /* if list have item */
        if (g_list_length(g_client_list) > 0) {
                /* Get a first item */
@@ -147,6 +160,7 @@ int tts_client_destroy(tts_h tts)
 
                                g_list_free(iter);
 
+                               pthread_mutex_unlock(&g_client_list_mutex);
                                SLOG(LOG_ERROR, TAG_TTSC, "Client destroy : uid(%d)", uid);
                                return TTS_ERROR_NONE;
                        }
@@ -155,6 +169,7 @@ int tts_client_destroy(tts_h tts)
                        iter = g_list_next(iter);
                }
        }
+       pthread_mutex_unlock(&g_client_list_mutex);
        SLOG(LOG_ERROR, TAG_TTSC, "Fail to destroy client : handle is not valid");
 
        return TTS_ERROR_INVALID_PARAMETER;
@@ -170,6 +185,7 @@ tts_client_s* tts_client_get(tts_h tts)
        GList *iter = NULL;
        tts_client_s *data = NULL;
 
+       pthread_mutex_lock(&g_client_list_mutex);
        if (g_list_length(g_client_list) > 0) {
                /* Get a first item */
                iter = g_list_first(g_client_list);
@@ -177,14 +193,17 @@ tts_client_s* tts_client_get(tts_h tts)
                while (NULL != iter) {
                        data = iter->data;
 
-                       if (tts->handle == data->tts->handle) 
+                       if (tts->handle == data->tts->handle) {
+                               pthread_mutex_unlock(&g_client_list_mutex);
                                return data;
+                       }
 
                        /* Next item */
                        iter = g_list_next(iter);
                }
        }
 
+       pthread_mutex_unlock(&g_client_list_mutex);
        SLOG(LOG_ERROR, TAG_TTSC, "handle is not valid");
 
        return NULL;
@@ -200,6 +219,7 @@ tts_client_s* tts_client_get_by_uid(const int uid)
        GList *iter = NULL;
        tts_client_s *data = NULL;
 
+       pthread_mutex_lock(&g_client_list_mutex);
        if (g_list_length(g_client_list) > 0) {
                /* Get a first item */
                iter = g_list_first(g_client_list);
@@ -207,6 +227,7 @@ tts_client_s* tts_client_get_by_uid(const int uid)
                while (NULL != iter) {
                        data = iter->data;
                        if (uid == data->uid) {
+                               pthread_mutex_unlock(&g_client_list_mutex);
                                return data;
                        }
 
@@ -215,6 +236,7 @@ tts_client_s* tts_client_get_by_uid(const int uid)
                }
        }
 
+       pthread_mutex_unlock(&g_client_list_mutex);
        SLOG(LOG_WARN, TAG_TTSC, "uid is not valid");
 
        return NULL;
@@ -222,7 +244,11 @@ tts_client_s* tts_client_get_by_uid(const int uid)
 
 int tts_client_get_size()
 {
-       return g_list_length(g_client_list);
+       pthread_mutex_lock(&g_client_list_mutex);
+       int size = g_list_length(g_client_list);
+       pthread_mutex_unlock(&g_client_list_mutex);
+
+       return size;
 }
 
 int tts_client_use_callback(tts_client_s* client)
@@ -249,6 +275,7 @@ int tts_client_get_connected_client_count()
        tts_client_s *data = NULL;
        int number = 0;
 
+       pthread_mutex_lock(&g_client_list_mutex);
        if (g_list_length(g_client_list) > 0) {
                /* Get a first item */
                iter = g_list_first(g_client_list);
@@ -263,6 +290,7 @@ int tts_client_get_connected_client_count()
                        iter = g_list_next(iter);
                }
        }
+       pthread_mutex_unlock(&g_client_list_mutex);
        return number;
 }
 
@@ -272,6 +300,7 @@ int tts_client_get_mode_client_count(tts_mode_e mode)
        tts_client_s *data = NULL;
        int number = 0;
 
+       pthread_mutex_lock(&g_client_list_mutex);
        if (g_list_length(g_client_list) > 0) {
                /* Get a first item */
                iter = g_list_first(g_client_list);
@@ -286,9 +315,11 @@ int tts_client_get_mode_client_count(tts_mode_e mode)
                        iter = g_list_next(iter);
                }
        }
+       pthread_mutex_unlock(&g_client_list_mutex);
        return number;
 }
 
+// FIXME: remove this function
 GList* tts_client_get_client_list()
 {
        return g_client_list;