From 187489e8896ab8c8fa35fdbe5ef2edc952ab4253 Mon Sep 17 00:00:00 2001 From: Kwangyoun Kim Date: Tue, 27 Dec 2016 14:19:27 +0900 Subject: [PATCH] Add error tolerance with dbus signal handling Change-Id: I478fb976499113ceb82630b1eb9b2285ead62ddf Signed-off-by: Kwangyoun Kim (cherry picked from commit 3bac011111d1266c92fc6cdc99b64635074b6c7c) --- client/tts.c | 90 +++++++++++++++++++++++++++++++++++++++------------- client/tts_dbus.c | 43 +++++++++++++++++++++++++ server/ttsd_server.c | 30 ------------------ 3 files changed, 111 insertions(+), 52 deletions(-) diff --git a/client/tts.c b/client/tts.c index 05daf46..6e80252 100644 --- a/client/tts.c +++ b/client/tts.c @@ -1726,34 +1726,80 @@ static Eina_Bool __tts_notify_error(void *data) int __tts_cb_error(int uid, tts_error_e reason, int utt_id, char* err_msg) { - tts_client_s* client = tts_client_get_by_uid(uid); + if (-1 == uid) { + GList* client_list = NULL; + client_list = tts_client_get_client_list(); - if (NULL == client) { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid"); - return TTS_ERROR_INVALID_PARAMETER; - } + GList *iter = NULL; + tts_client_s *data = NULL; - client->utt_id = utt_id; - client->reason = reason; - if (NULL != client->err_msg) { - free(client->err_msg); - client->err_msg = NULL; - } - client->err_msg = strdup(err_msg); + if (g_list_length(client_list) > 0) { + /* Get a first item */ + iter = g_list_first(client_list); - /* call callback function */ - if (NULL != client->error_cb) { - ecore_timer_add(0, __tts_notify_error, client->tts); + while (NULL != iter) { + data = iter->data; + + data->utt_id = utt_id; + data->reason = reason; + if (NULL != data->err_msg) { + free(data->err_msg); + data->err_msg = NULL; + } + if (NULL != err_msg) + data->err_msg = strdup(err_msg); + + /* call callback function */ + if (NULL != data->error_cb) { + ecore_timer_add(0, __tts_notify_error, data->tts); + } else { + SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error "); + } + + if (TTS_ERROR_SERVICE_RESET == reason) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset"); + + data->current_state = TTS_STATE_CREATED; + if (0 != tts_prepare(data->tts)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare"); + } + } + + /* Next item */ + iter = g_list_next(iter); + } + } } else { - SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error "); - } + tts_client_s* client = tts_client_get_by_uid(uid); - if (TTS_ERROR_SERVICE_RESET == reason) { - SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset"); + if (NULL == client) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid"); + return TTS_ERROR_INVALID_PARAMETER; + } - client->current_state = TTS_STATE_CREATED; - if (0 != tts_prepare(client->tts)) { - SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare"); + client->utt_id = utt_id; + client->reason = reason; + if (NULL != client->err_msg) { + free(client->err_msg); + client->err_msg = NULL; + } + if (NULL != err_msg) + client->err_msg = strdup(err_msg); + + /* call callback function */ + if (NULL != client->error_cb) { + ecore_timer_add(0, __tts_notify_error, client->tts); + } else { + SLOG(LOG_WARN, TAG_TTSC, "No registered callback function of error "); + } + + if (TTS_ERROR_SERVICE_RESET == reason) { + SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Service Reset"); + + client->current_state = TTS_STATE_CREATED; + if (0 != tts_prepare(client->tts)) { + SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to prepare"); + } } } diff --git a/client/tts_dbus.c b/client/tts_dbus.c index 72a8ed5..e23aa59 100644 --- a/client/tts_dbus.c +++ b/client/tts_dbus.c @@ -135,6 +135,13 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle } } /* TTSD_SIGNAL_ERROR */ + else if (dbus_message_is_signal(msg, "org.freedesktop.DBus", "NameOwnerChanged")) { + SLOG(LOG_DEBUG, TAG_TTSC, "===== Owner Changed"); + __tts_cb_error(-1, TTS_ERROR_SERVICE_RESET, -1, "Daemon Reset"); + SLOG(LOG_DEBUG, TAG_TTSC, "====="); + SLOG(LOG_DEBUG, TAG_TTSC, " "); + } /* NameOwnerChanged */ + else { SLOG(LOG_DEBUG, TAG_TTSC, "Message is NOT valid"); dbus_message_unref(msg); @@ -385,6 +392,25 @@ int tts_dbus_request_initialize(int uid, bool* credential_needed) if (0 == result) { *credential_needed = (bool)temp; SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts initialize : result = %d, credential_needed(%d)", result, *credential_needed); + + /* add a rule for daemon error */ + char rule_err[256] = {0, }; + tts_client_s* client = tts_client_get_by_uid(uid); + if (TTS_MODE_DEFAULT == client->mode) { + snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", TTS_SERVER_SERVICE_INTERFACE); + } else if (TTS_MODE_NOTIFICATION == client->mode) { + snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", TTS_NOTI_SERVER_SERVICE_INTERFACE); + } else if (TTS_MODE_SCREEN_READER == client->mode) { + snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", TTS_SR_SERVER_SERVICE_INTERFACE); + } + dbus_bus_add_match(g_conn_listener, rule_err, &err); + dbus_connection_flush(g_conn_listener); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_TTSC, "Match Error (%s)", err.message); + dbus_error_free(&err); + return TTS_ERROR_OPERATION_FAILED; + } } else { SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts initialize : result = %d", result); } @@ -404,6 +430,23 @@ int tts_dbus_request_finalize(int uid) DBusError err; dbus_error_init(&err); + /* remove a rule for daemon error */ + char rule_err[256] = {0, }; + tts_client_s* client = tts_client_get_by_uid(uid); + if (TTS_MODE_DEFAULT == client->mode) { + snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", TTS_SERVER_SERVICE_INTERFACE); + } else if (TTS_MODE_NOTIFICATION == client->mode) { + snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", TTS_NOTI_SERVER_SERVICE_INTERFACE); + } else if (TTS_MODE_SCREEN_READER == client->mode) { + snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", TTS_SR_SERVER_SERVICE_INTERFACE); + } + dbus_bus_remove_match(g_conn_listener, rule_err, &err); + dbus_connection_flush(g_conn_listener); + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_TTSC, "Match Error (%s)", err.message); + dbus_error_free(&err); + } + msg = __tts_dbus_make_message(uid, TTS_METHOD_FINALIZE); if (NULL == msg) { diff --git a/server/ttsd_server.c b/server/ttsd_server.c index d2dd19c..5a657a5 100755 --- a/server/ttsd_server.c +++ b/server/ttsd_server.c @@ -430,38 +430,8 @@ void __screen_reader_changed_cb(bool value) /* * Server APIs */ -static bool __send_reset_signal(int pid, int uid, app_state_e state, void* user_data) -{ - ttsdc_send_error_message(pid, uid, -1, TTSD_ERROR_SERVICE_RESET, "TTS service reset"); - return true; -} - -static void __sig_handler(int signo) -{ - /* restore signal handler */ - signal(signo, SIG_DFL); - - /* Send error signal via foreach clients */ - ttsd_data_foreach_clients(__send_reset_signal, NULL); - - /* invoke signal again */ - raise(signo); -} - -static void __register_sig_handler() -{ - signal(SIGSEGV, __sig_handler); - signal(SIGABRT, __sig_handler); - signal(SIGTERM, __sig_handler); - signal(SIGINT, __sig_handler); - signal(SIGQUIT, __sig_handler); -} - int ttsd_initialize(ttse_request_callback_s *callback) { - /* Register signal handler */ - __register_sig_handler(); - if (ttsd_config_initialize(__config_changed_cb)) { SLOG(LOG_ERROR, tts_tag(), "[Server WARNING] Fail to initialize config."); } -- 2.7.4