From: Suyeon Hwang Date: Fri, 12 Jan 2024 05:53:34 +0000 (+0900) Subject: Remove unnecessary variables for controlling thread X-Git-Tag: accepted/tizen/unified/20240219.160454~5^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F11%2F304211%2F1;p=platform%2Fcore%2Fuifw%2Ftts.git Remove unnecessary variables for controlling thread - Issue: When PlayerThread is destructing, main thread can be in deadlock. - Solution: This patch removes unnecessary condition variable and mutex for thread. The root cause of the deadlock is because of the wrong usage of two different mutex for controlling single thread. This patch simplifies the thread function and thread controlling logic using timed_mutex and condition_variable_any. Through this change, the PlayerThread instance can clear the reserved thread more quickly. Change-Id: I8fa79f7c4e25595641fc651394e550d545360f75 Signed-off-by: Suyeon Hwang --- diff --git a/server/PlayerThread.cpp b/server/PlayerThread.cpp index ce7ccda..95ef600 100644 --- a/server/PlayerThread.cpp +++ b/server/PlayerThread.cpp @@ -48,11 +48,10 @@ PlayerThread::~PlayerThread() mPlayerAvailable = false; mPlayUtterance = nullptr; - mThreadCond.notify_all(); - tryToStopPlayer(); SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Thread is stopped or waiting"); + mThreadCond.notify_all(); mPlayerThread.join(); SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Finish thread"); } @@ -61,9 +60,8 @@ void PlayerThread::tryToStopPlayer() { mCurrentUid = TTS_INVALID_UID; - unique_lock stopCheckLock(mStopCheckMutex); - cv_status ret = mStopCheckCond.wait_for(stopCheckLock, chrono::milliseconds(500)); - if (ret == cv_status::timeout) { + std::unique_lock thread_lock(mThreadMutex, std::defer_lock); + if (false == thread_lock.try_lock_for(std::chrono::milliseconds(500))) { SLOG(LOG_WARN, tts_tag(), "[PlayerThread] Timeout stop request"); } } @@ -125,27 +123,21 @@ void PlayerThread::requestStop() void PlayerThread::runPlayer() { - unique_lock lock(mThreadMutex); + std::unique_lock lock(mThreadMutex); if (nullptr == mPlayUtterance) { SLOG(LOG_ERROR, tts_tag(), "[PlayerThread] Play utterance callback is not set"); return; } while (isPlayerAvailable()) { - SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Wait playing"); if (isThreadStopped()) { + SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Wait for playing"); mThreadCond.wait(lock); - usleep(10000); - } - - while (false == isThreadStopped()) { + } else { unsigned int uid = getCurrentUid(); SLOG(LOG_INFO, tts_tag(), "[Player] Current player uid(%u)", uid); mPlayUtterance(this, uid); } - - SLOG(LOG_INFO, tts_tag(), "[PlayerThread] notify stopCheckCond"); - mStopCheckCond.notify_all(); } } diff --git a/server/PlayerThread.h b/server/PlayerThread.h index bf4fab8..b852ad6 100644 --- a/server/PlayerThread.h +++ b/server/PlayerThread.h @@ -12,20 +12,20 @@ */ -#ifndef __TTSD_PLAYER_MANAGER_H_ -#define __TTSD_PLAYER_MANAGER_H_ +#ifndef __TTSD_PLAYER_THREAD_H__ +#define __TTSD_PLAYER_THREAD_H__ #include #include #include #include -#include class PlayerThread { public: typedef void (*PlayUtteranceCallback)(PlayerThread* player_instance, unsigned int uid); +public: PlayerThread(PlayUtteranceCallback threadFucntion); ~PlayerThread(); @@ -34,9 +34,11 @@ public: void requestPlay(unsigned int uid); void requestStop(); + private: static void runThread(PlayerThread* player); +private: void runPlayer(); void tryToStopPlayer(); bool isPlayerAvailable(); @@ -47,14 +49,12 @@ private: std::atomic mPlayerAvailable; std::thread mPlayerThread; - std::mutex mThreadMutex; + std::timed_mutex mThreadMutex; std::mutex mControlMutex; - std::mutex mStopCheckMutex; - std::condition_variable mThreadCond; - std::condition_variable mStopCheckCond; + std::condition_variable_any mThreadCond; PlayUtteranceCallback mPlayUtterance; }; -#endif /* __TTSD_PLAYER_MANAGER_H_ */ +#endif /* __TTSD_PLAYER_THREAD_H__ */