Fix paused data handling logic 59/274959/1
authorSuyeon Hwang <stom.hwang@samsung.com>
Thu, 12 May 2022 12:46:19 +0000 (21:46 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Thu, 12 May 2022 12:46:19 +0000 (21:46 +0900)
- Issue:
If sound_data queue is cleared still player thread has reference of the first element of the
sound_data queue, then player thread makes double free problem of sound_data.

- Solution:
Problem is because the player thread tries to destroy the data without ownership of the data. So
This patch makes the player thread has ownership of played sound_data. By this change, player
thread can destroy the data that the thread has its ownership.

Change-Id: Ib3e34f9cc8632458f097edd760da2179471bc864
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
server/ttsd_data.cpp
server/ttsd_data.h
server/ttsd_player.cpp

index 658387f2ff59f8110a0fccf5bbeeae2353921e4e..110cd11d4782bf079760a7c7423f987eec123325 100644 (file)
@@ -680,25 +680,14 @@ sound_data_s* ttsd_data_get_first_sound_data(unsigned int uid)
                return nullptr;
        }
 
-       return __get_sound_data(app_data);
-}
-
-int ttsd_data_pop_sound_data(unsigned int uid)
-{
-       lock_guard<mutex> lock(g_app_data_mutex);
-       app_data_s* app_data = __get_client_app_data(uid);
-       if (nullptr == app_data) {
-               SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] uid is not valid (%u)", uid);
-               return TTSD_ERROR_INVALID_PARAMETER;
-       }
-
-       if (app_data->m_wav_data.empty()) {
-               SECURE_SLOG(LOG_ERROR, tts_tag(), "[DATA ERROR] Sound data is empty (%u)", uid);
-               return TTSD_ERROR_OPERATION_FAILED;
+       sound_data_s* soundData = __get_sound_data(app_data);
+       if (nullptr == soundData) {
+               SLOG(LOG_WARN, tts_tag(), "[DATA WARNING] There is no sound data");
+               return nullptr;
        }
 
        app_data->m_wav_data.pop_front();
-       return TTSD_ERROR_NONE;
+       return soundData;
 }
 
 int ttsd_data_get_sound_data_size(unsigned int uid)
@@ -827,7 +816,7 @@ int ttsd_data_set_play_type(unsigned int uid, tts_app_play_type_e type)
        return TTSD_ERROR_NONE;
 }
 
-int ttsd_data_set_paused_data_existing(unsigned int uid, bool is_paused_data_existing)
+int ttsd_data_set_paused_data(unsigned int uid, sound_data_s* sound_data)
 {
        lock_guard<mutex> lock(g_app_data_mutex);
        app_data_s* app_data = __get_client_app_data(uid);
@@ -836,7 +825,13 @@ int ttsd_data_set_paused_data_existing(unsigned int uid, bool is_paused_data_exi
                return TTSD_ERROR_INVALID_PARAMETER;
        }
 
-       app_data->paused_data_existing = is_paused_data_existing;
+       if (sound_data) {
+               app_data->m_wav_data.push_front(sound_data);
+               app_data->paused_data_existing = true;
+       } else {
+               app_data->paused_data_existing = false;
+       }
+
        return TTSD_ERROR_NONE;
 }
 
index d59b3115088f18db46ad925e3bf0734a08445a60..740cb6f02201058d7d7b5951a6f875125fb39069 100644 (file)
@@ -113,8 +113,6 @@ int ttsd_data_add_sound_data(unsigned int uid, sound_data_s* data);
 
 sound_data_s* ttsd_data_get_first_sound_data(unsigned int uid);
 
-int ttsd_data_pop_sound_data(unsigned int uid);
-
 int ttsd_data_get_sound_data_size(unsigned int uid);
 
 int ttsd_data_set_last_sound_result_event(unsigned int uid, ttse_result_event_e event);
@@ -136,7 +134,7 @@ tts_app_play_type_e ttsd_data_get_play_type(unsigned int uid);
 
 int ttsd_data_set_play_type(unsigned int uid, tts_app_play_type_e type);
 
-int ttsd_data_set_paused_data_existing(unsigned int uid, bool is_paused_data_existing);
+int ttsd_data_set_paused_data(unsigned int uid, sound_data_s* sound_data);
 
 bool ttsd_data_is_paused_data_existing(unsigned int uid);
 
index 1bdd4f2f4f793ed6dd557d2edba3f7bb60cc33a3..b0a7729eb848881275764c3a446232ce51ff0328 100644 (file)
@@ -271,6 +271,13 @@ static void __wait_sound_data(PlayerThread* player, unsigned int uid)
        }
 }
 
+static void __set_paused_data(unsigned int uid, sound_data_s* sound_data) {
+       int ret = ttsd_data_set_paused_data(uid, sound_data);
+       if (TTSD_ERROR_NONE != ret) {
+               ttsd_data_destroy_sound_data(sound_data);
+       }
+}
+
 static void __play_utterance_cb(PlayerThread* player, unsigned int uid)
 {
        SLOG(LOG_DEBUG, tts_tag(), "[PLAYER] Start play utterance. uid(%u)", uid);
@@ -278,7 +285,7 @@ static void __play_utterance_cb(PlayerThread* player, unsigned int uid)
        while (player->isCurrentUid(uid)) {
                sound_data_s* sound_data = ttsd_data_get_first_sound_data(uid);
                if (ttsd_data_is_paused_data_existing(uid)) {
-                       ttsd_data_set_paused_data_existing(uid, false);
+                       ttsd_data_set_paused_data(uid, nullptr);
 
                        if (nullptr == sound_data) {
                                break;
@@ -321,9 +328,7 @@ static void __play_utterance_cb(PlayerThread* player, unsigned int uid)
                                ttse_result_event_e event = sound_data->event;
                                int utt_id = sound_data->utt_id;
 
-                               if (TTSD_ERROR_NONE == ttsd_data_pop_sound_data(uid)) {
-                                       ttsd_data_destroy_sound_data(sound_data);
-                               }
+                               ttsd_data_destroy_sound_data(sound_data);
                                sound_data = nullptr;
 
                                SLOG(LOG_INFO, tts_tag(), "[Player] No Sound data. Event(%d), uid(%u), uttid(%d)", event, uid, utt_id);
@@ -341,19 +346,19 @@ static void __play_utterance_cb(PlayerThread* player, unsigned int uid)
                int ret = __play_sound_data(player, uid, sound_data);
                if (TTSD_ERROR_INVALID_STATE == ret) {
                        SLOG(LOG_DEBUG, tts_tag(), "[Player] Uid(%u) is paused", uid);
-                       ttsd_data_set_paused_data_existing(uid, true);
+                       __set_paused_data(uid, sound_data);
                        break;
                } else if (TTSD_ERROR_NONE != ret) {
                        SLOG(LOG_ERROR, tts_tag(), "[Player] Fail to play audio data. uid(%u)", uid);
+                       ttsd_data_destroy_sound_data(sound_data);
+                       sound_data = nullptr;
                        break;
                }
 
                ttse_result_event_e event = sound_data->event;
                int utt_id = sound_data->utt_id;
 
-               if (TTSD_ERROR_NONE == ttsd_data_pop_sound_data(uid)) {
-                       ttsd_data_destroy_sound_data(sound_data);
-               }
+               ttsd_data_destroy_sound_data(sound_data);
                sound_data = nullptr;
 
                if (TTSE_RESULT_EVENT_FINISH == event) {
@@ -468,7 +473,7 @@ int ttsd_player_stop(unsigned int uid)
 
        __set_playing_status(false);
        ttsd_data_set_last_sound_result_event(uid, TTSE_RESULT_EVENT_FINISH);
-       ttsd_data_set_paused_data_existing(uid, false);
+       ttsd_data_set_paused_data(uid, nullptr);
 
        SLOG(LOG_INFO, tts_tag(), "[Player SUCCESS] Stop player : uid(%u)", uid);
 
@@ -512,7 +517,7 @@ bool __stop_all_client_callback(int pid, unsigned int uid, app_tts_state_e state
 
        if (APP_STATE_PLAYING == state || APP_STATE_PAUSED == state) {
                ttsd_data_set_last_sound_result_event(uid, TTSE_RESULT_EVENT_FINISH);
-               ttsd_data_set_paused_data_existing(uid, false);
+               ttsd_data_set_paused_data(uid, nullptr);
        }
 
        return true;