Remove unnecessary variables for controlling thread 11/304211/1
authorSuyeon Hwang <stom.hwang@samsung.com>
Fri, 12 Jan 2024 05:53:34 +0000 (14:53 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Fri, 12 Jan 2024 05:53:34 +0000 (14:53 +0900)
- 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 <stom.hwang@samsung.com>
server/PlayerThread.cpp
server/PlayerThread.h

index ce7ccda..95ef600 100644 (file)
@@ -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<mutex> stopCheckLock(mStopCheckMutex);
-       cv_status ret = mStopCheckCond.wait_for(stopCheckLock, chrono::milliseconds(500));
-       if (ret == cv_status::timeout) {
+       std::unique_lock<std::timed_mutex> 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<mutex> lock(mThreadMutex);
+       std::unique_lock<std::timed_mutex> 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();
        }
 }
 
index bf4fab8..b852ad6 100644 (file)
 */
 
 
-#ifndef __TTSD_PLAYER_MANAGER_H_
-#define __TTSD_PLAYER_MANAGER_H_
+#ifndef __TTSD_PLAYER_THREAD_H__
+#define __TTSD_PLAYER_THREAD_H__
 
 
 #include <mutex>
 #include <condition_variable>
 #include <thread>
 #include <atomic>
-#include <queue>
 
 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<bool> 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__ */