2 * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
14 #include "ttsd_main.h"
15 #include "ttsd_data.h"
16 #include "PlayerThread.h"
22 void PlayerThread::runThread(PlayerThread* player)
24 pthread_t thread = pthread_self();
25 int nameSetResult = pthread_setname_np(thread, "ttsd_play_thread");
26 SLOG(LOG_INFO, tts_tag(), "Name : %d %lu", nameSetResult, thread);
28 SLOG(LOG_INFO, tts_tag(), "[Player] Run player thread");
30 SLOG(LOG_INFO, tts_tag(), "[Player] Exit player thread");
33 PlayerThread::PlayerThread(PlayUtteranceCallback threadFucntion)
35 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Constructor");
36 mCurrentUid = TTS_INVALID_UID;
37 mPlayerAvailable = true;
38 mPlayUtterance = threadFucntion;
40 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Start thread");
41 mPlayerThread = thread(runThread, this);
44 PlayerThread::~PlayerThread()
46 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Destructor");
47 unique_lock<mutex> controlLock(mControlMutex);
48 mPlayerAvailable = false;
49 mPlayUtterance = nullptr;
52 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Thread is stopped or waiting");
54 mThreadCond.notify_all();
56 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Finish thread");
59 void PlayerThread::tryToStopPlayer()
61 mCurrentUid = TTS_INVALID_UID;
63 std::unique_lock<std::timed_mutex> thread_lock(mThreadMutex, std::defer_lock);
64 if (false == thread_lock.try_lock_for(std::chrono::milliseconds(500))) {
65 SLOG(LOG_WARN, tts_tag(), "[PlayerThread] Timeout stop request");
69 bool PlayerThread::isPlayerAvailable()
71 return mPlayerAvailable.load();
74 unsigned int PlayerThread::getCurrentUid()
76 return mCurrentUid.load();
79 bool PlayerThread::isCurrentUid(unsigned int uid)
81 if (0 > ttsd_data_is_client(uid)) {
85 if (uid != mCurrentUid.load()) {
92 void PlayerThread::requestPlay(unsigned int uid)
94 lock_guard<mutex> lock(mControlMutex);
95 if (false == isPlayerAvailable()) {
96 SLOG(LOG_ERROR, tts_tag(), "[PlayerThread] Player is already finished.");
100 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Play request. uid(%u)", uid);
102 mThreadCond.notify_all();
105 void PlayerThread::requestStop()
107 lock_guard<mutex> lock(mControlMutex);
108 if (false == isPlayerAvailable()) {
109 SLOG(LOG_ERROR, tts_tag(), "[PlayerThread] Player is already finished.");
113 unsigned int uid = mCurrentUid.load();
114 if (uid == TTS_INVALID_UID) {
115 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Thread is already stopped");
119 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Stop request. current played uid(%u)", uid);
121 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Stop playing");
124 void PlayerThread::runPlayer()
126 std::unique_lock<std::timed_mutex> lock(mThreadMutex);
127 if (nullptr == mPlayUtterance) {
128 SLOG(LOG_ERROR, tts_tag(), "[PlayerThread] Play utterance callback is not set");
132 while (isPlayerAvailable()) {
133 if (isThreadStopped()) {
134 SLOG(LOG_INFO, tts_tag(), "[PlayerThread] Wait for playing");
135 mThreadCond.wait(lock);
137 unsigned int uid = getCurrentUid();
138 SLOG(LOG_INFO, tts_tag(), "[Player] Current player uid(%u)", uid);
139 mPlayUtterance(this, uid);
144 bool PlayerThread::isThreadStopped()
146 bool isStopped = (TTS_INVALID_UID == mCurrentUid.load()) || (false == isPlayerAvailable());