#include "tts_core.h"
#include "tts_dlog.h"
+
#define MAXSLEEP 128
#define MAX_CONNECT_CHECK 100
rpc_port_proxy_tts_h rpc_h;
rpc_port_proxy_tts_notify_cb_h notify_cb_h;
char* engine_app_id;
+ bool destruction_requesting;
} tts_tidl_info_s;
static GList* g_tidl_infos = NULL;
static Ecore_Idler *g_destroy_handles_idler = NULL;
+static pthread_mutex_t g_rpc_h_mutex = PTHREAD_MUTEX_INITIALIZER;
+
static tts_tidl_info_s* __get_tidl_info_s(unsigned int uid)
{
static void destroy_scheduled_handle(gpointer data)
{
+ pthread_mutex_lock(&g_rpc_h_mutex);
rpc_port_proxy_tts_h rpc_h = (rpc_port_proxy_tts_h)data;
SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Destroy rpc handle(%p)", rpc_h);
int ret = rpc_port_proxy_tts_destroy(rpc_h);
if (RPC_PORT_ERROR_NONE != ret) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to destroy handle. ret(%d/%s)", ret, get_error_message(ret));
}
+ pthread_mutex_unlock(&g_rpc_h_mutex);
}
static Eina_Bool destroy_scheduled_handles_by_ecore_idler(void *user_data)
return EINA_FALSE;
}
-static inline void destroy_rpc_port(tts_tidl_info_s* info)
+static void __initialize_tidl_info(tts_tidl_info_s* info)
{
- RETM_IF(NULL == info->rpc_h, "[TIDL] Handle is already destroyed");
-
- g_destruction_scheduled_handles = g_slist_append(g_destruction_scheduled_handles, info->rpc_h);
- if (NULL == g_destroy_handles_idler) {
- g_destroy_handles_idler = ecore_idler_add(destroy_scheduled_handles_by_ecore_idler, NULL);
+ if (NULL == info) {
+ SLOG(LOG_ERROR, TAG_TTSC, "[TIDL] Invalid parameter");
+ return ;
}
info->rpc_h = NULL;
info->engine_app_id = NULL;
info->register_callback_invoked = false;
- info->connection_requesting = false;
info->connected = false;
+ info->connection_requesting = false;
+}
+
+static inline void destroy_rpc_port(tts_tidl_info_s* info)
+{
+ pthread_mutex_lock(&g_rpc_h_mutex);
+ if (NULL == info->rpc_h) {
+ SLOG(LOG_WARN, TAG_TTSC, "[TIDL] Handle is already destroyed");
+ pthread_mutex_unlock(&g_rpc_h_mutex);
+ return ;
+ }
+ if (true == info->destruction_requesting) {
+ SLOG(LOG_WARN, TAG_TTSC, "[TIDL] Destroying rpc port is already requested");
+ pthread_mutex_unlock(&g_rpc_h_mutex);
+ return ;
+ }
+
+ g_destruction_scheduled_handles = g_slist_append(g_destruction_scheduled_handles, info->rpc_h);
+ if (NULL == g_destroy_handles_idler) {
+ g_destroy_handles_idler = ecore_idler_add(destroy_scheduled_handles_by_ecore_idler, NULL);
+ }
+
+ info->destruction_requesting = true;
+
+ pthread_mutex_unlock(&g_rpc_h_mutex);
}
static void __on_connected(rpc_port_proxy_tts_h h, void *user_data)
info->connected = true;
info->connection_requesting = false;
+ info->destruction_requesting = false;
SLOG(LOG_DEBUG, TAG_TTSC, "Connected to server");
}
info->connection_requesting = false;
info->register_callback_invoked = false;
- SLOG(LOG_DEBUG, TAG_TTSC, "Disconnected from server");
+ SLOG(LOG_ERROR, TAG_TTSC, "Disconnected from server");
if (tts_client_is_listening_started(uid)) {
- SLOG(LOG_DEBUG, TAG_TTSC, "Try to reconnect to server");
+ SLOG(LOG_ERROR, TAG_TTSC, "Try to reconnect to server");
destroy_rpc_port(info);
+ __initialize_tidl_info(info);
tts_core_handle_service_reset();
}
}
tts_tidl_info_s* info = __get_tidl_info_s(uid);
RETM_IF(NULL == info, "[ERROR] Fail to get tidl info");
+ info->connected = false;
info->connection_requesting = false;
info->register_callback_invoked = false;
}
info->uid = uid;
+ info->destruction_requesting = false;
g_tidl_infos = g_list_append(g_tidl_infos, info);
SLOG(LOG_ERROR, TAG_TTSC, "[TIDL] uid(%u)", uid);
RETVM_IF(NULL == info, TTS_ERROR_INVALID_PARAMETER, "[ERROR] Fail to get tidl info");
destroy_rpc_port(info);
+ __initialize_tidl_info(info);
if (g_destroy_handles_idler) {
ecore_idler_del(g_destroy_handles_idler);
g_destroy_handles_idler = NULL;
g_slist_free_full(g_steal_pointer(&g_destruction_scheduled_handles), destroy_scheduled_handle);
g_destruction_scheduled_handles = NULL;
- free(info->engine_app_id);
- info->engine_app_id = NULL;
-
g_tidl_infos = g_list_remove(g_tidl_infos, info);
free(info);
static inline bool __is_rpc_port_valid(tts_tidl_info_s* info, const char* engine_id)
{
+ pthread_mutex_lock(&g_rpc_h_mutex);
if (NULL == info->rpc_h || NULL == info->engine_app_id) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is empty");
+ pthread_mutex_unlock(&g_rpc_h_mutex);
return false;
}
if (NULL == engine_id) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine ID is null");
+ pthread_mutex_unlock(&g_rpc_h_mutex);
return false;
}
if (0 != strncmp(info->engine_app_id, engine_id, TTS_ENGINE_APPID_LEN)) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine id is not current engine");
+ pthread_mutex_unlock(&g_rpc_h_mutex);
return false;
}
+ pthread_mutex_unlock(&g_rpc_h_mutex);
+
return true;
}
static inline int __create_rpc_port(tts_tidl_info_s* info, const char* engine_id)
{
- RETVM_IF(NULL != info->rpc_h, TTS_ERROR_NONE, "[TIDL] Handle is already created");
+ pthread_mutex_lock(&g_rpc_h_mutex);
+ if (NULL != info->rpc_h) {
+ SLOG(LOG_INFO, TAG_TTSC, "[TIDL] Handle is already created");
+ pthread_mutex_unlock(&g_rpc_h_mutex);
+ return TTS_ERROR_NONE;
+ }
rpc_port_proxy_tts_callback_s rpc_callback = {
.connected = __on_connected,
uintptr_t ptr_uid = info->uid;
if (RPC_PORT_ERROR_NONE != rpc_port_proxy_tts_create(engine_id, &rpc_callback, (void*)ptr_uid, &handle) || NULL == handle) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create proxy");
+ pthread_mutex_unlock(&g_rpc_h_mutex);
return TTS_ERROR_OPERATION_FAILED;
}
info->rpc_h = handle;
info->engine_app_id = strdup(engine_id);
+ info->destruction_requesting = false;
+
+ pthread_mutex_unlock(&g_rpc_h_mutex);
return TTS_ERROR_NONE;
}
static int __reset_rpc_port(tts_tidl_info_s* info, const char* engine_id)
{
destroy_rpc_port(info);
+ __initialize_tidl_info(info);
if (TTS_ERROR_NONE != __create_rpc_port(info, engine_id)) {
SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create new rpc port");
static int __request_tidl_connect_sync(tts_tidl_info_s* info)
{
+ pthread_mutex_lock(&g_rpc_h_mutex);
int ret = rpc_port_proxy_tts_connect_sync(info->rpc_h);
SLOG(LOG_INFO, TAG_TTSC, "[INFO] Request connection to stub. ret(%d)", ret);
if (RPC_PORT_ERROR_NONE == ret) {
+ pthread_mutex_unlock(&g_rpc_h_mutex);
return TTS_ERROR_NONE;
}
+ pthread_mutex_unlock(&g_rpc_h_mutex);
+
return TTS_ERROR_OPERATION_FAILED;
}
case RPC_PORT_ERROR_IO_ERROR:
SLOG(LOG_INFO, TAG_TTSC, "[INFO] IO error occurs. Destroy old rpc port");
destroy_rpc_port(info);
+ __initialize_tidl_info(info);
return TTS_ERROR_IO_ERROR;
case RPC_PORT_ERROR_OUT_OF_MEMORY:
tts_client_set_start_listening(uid, false);
destroy_rpc_port(info);
+ __initialize_tidl_info(info);
+
SLOG(LOG_ERROR, TAG_TTSC, ">>>> Success tts finalize. uid(%u)", uid);
return TTS_ERROR_NONE;
}
if (TTS_ERROR_NONE != ret) {
- SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request pause pcm : Fail to invoke message(%d)", ret);
+ SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request to add pcm : Fail to invoke message(%d)", ret);
return ret;
}