From: Suyeon Hwang Date: Mon, 20 Feb 2023 02:13:24 +0000 (+0900) Subject: Destroy tts handle always on the main thread X-Git-Tag: accepted/tizen/7.0/unified/20230406.152457^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=07b73b9464682ba974d34caf8ae6686016e9c5c0;p=platform%2Fcore%2Fuifw%2Ftts.git Destroy tts handle always on the main thread - Issue: In C# application, the garbage colletor can destroy tts handle on a sub thread, and this behavior can make thread safety issues. - Solution: The C# garbage collector can release the instance on a sub thread, so this can make race condition issues. To prevent this kind of issues, this patch adds a new logic to tts_destroy() function. Through this change, the handle destruction logic of tts_destroy() will always be run on a main thread. This change will prevent race condition issues because the logic insures that every handle destructions are run on a main thread and they are not destroyed at the same time. Change-Id: I90c248a4975410d4211dea93f24ea43e7c00ecb1 Signed-off-by: Suyeon Hwang (cherry picked from commit fc9fbc084158df81c527568df3af343caf75cd4e) --- diff --git a/client/tts.c b/client/tts.c index 3df546b5..a7b67f3a 100644 --- a/client/tts.c +++ b/client/tts.c @@ -292,12 +292,9 @@ int tts_create(tts_h* tts) return TTS_ERROR_NONE; } -int tts_destroy(tts_h tts) +static int destroy_tts_handle(tts_h tts) { - RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED); - - SLOG(LOG_INFO, TAG_TTSC, "@@@ Destroy TTS"); - + SLOG(LOG_INFO, TAG_TTSC, "Destroy TTS handle"); tts_client_s* client = tts_client_get(tts); RETVM_IF(NULL == client, TTS_ERROR_INVALID_PARAMETER, "[ERROR] A handle is not valid. tts(%p)", tts); @@ -367,10 +364,32 @@ int tts_destroy(tts_h tts) } } - SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); return TTS_ERROR_NONE; } +static void *destroy_tts_handle_on_main_thread(void* data) +{ + SLOG(LOG_INFO, TAG_TTSC, "Destroy on main thread synchronously"); + tts_h tts = (tts_h)data; + + int ret = destroy_tts_handle(tts); + intptr_t p_ret = (intptr_t)ret; + + return (void *)p_ret; +} + +int tts_destroy(tts_h tts) +{ + RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED); + SLOG(LOG_INFO, TAG_TTSC, "@@@ Destroy TTS"); + + intptr_t ret = (intptr_t)ecore_main_loop_thread_safe_call_sync(destroy_tts_handle_on_main_thread, (void *)tts); + SLOG(LOG_INFO, TAG_TTSC, "Return value: (%d/%s)", (int)ret, get_error_message((int)ret)); + + SLOG(LOG_DEBUG, TAG_TTSC, "@@@"); + return (int)ret; +} + int tts_set_mode(tts_h tts, tts_mode_e mode) { RETV_IF(TTS_ERROR_NONE != __tts_get_feature_enabled(), TTS_ERROR_NOT_SUPPORTED);