From 1ec7dcbf00714896f738c92cbf89693a880032cf Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Fri, 17 Apr 2020 17:23:50 +0900 Subject: [PATCH] Add mutex lock for global variables in tts_client 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 --- client/tts_client.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/client/tts_client.c b/client/tts_client.c index 570910b..f0f0a82 100644 --- a/client/tts_client.c +++ b/client/tts_client.c @@ -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; -- 2.7.4