Merge "Refine tuner aidl hal threads."
diff --git a/tv/tuner/aidl/default/Demux.cpp b/tv/tuner/aidl/default/Demux.cpp
index 3937c6a..8e83d06 100644
--- a/tv/tuner/aidl/default/Demux.cpp
+++ b/tv/tuner/aidl/default/Demux.cpp
@@ -37,8 +37,7 @@
}
Demux::~Demux() {
- mFrontendInputThreadRunning = false;
- std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
+ close();
}
::ndk::ScopedAStatus Demux::setFrontendDataSource(int32_t in_frontendId) {
@@ -171,6 +170,8 @@
::ndk::ScopedAStatus Demux::close() {
ALOGV("%s", __FUNCTION__);
+ stopFrontendInput();
+
set<int64_t>::iterator it;
for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
mDvrPlayback->removePlaybackFilter(*it);
@@ -180,8 +181,6 @@
mFilters.clear();
mLastUsedFilterId = -1;
mTuner->removeDemux(mDemuxId);
- mFrontendInputThreadRunning = false;
- std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
return ::ndk::ScopedAStatus::ok();
}
@@ -345,14 +344,7 @@
void Demux::startFrontendInputLoop() {
mFrontendInputThreadRunning = true;
- pthread_create(&mFrontendInputThread, NULL, __threadLoopFrontend, this);
- pthread_setname_np(mFrontendInputThread, "frontend_input_thread");
-}
-
-void* Demux::__threadLoopFrontend(void* user) {
- Demux* const self = static_cast<Demux*>(user);
- self->frontendInputThreadLoop();
- return 0;
+ mFrontendInputThread = std::thread(&Demux::frontendInputThreadLoop, this);
}
void Demux::frontendInputThreadLoop() {
@@ -360,7 +352,6 @@
return;
}
- std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
if (!mDvrPlayback) {
ALOGW("[Demux] No software Frontend input configured. Ending Frontend thread loop.");
mFrontendInputThreadRunning = false;
@@ -402,7 +393,9 @@
ALOGD("[Demux] stop frontend on demux");
mKeepFetchingDataFromFrontend = false;
mFrontendInputThreadRunning = false;
- std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
+ if (mFrontendInputThread.joinable()) {
+ mFrontendInputThread.join();
+ }
}
void Demux::setIsRecording(bool isRecording) {
diff --git a/tv/tuner/aidl/default/Demux.h b/tv/tuner/aidl/default/Demux.h
index 4d9b7fe..1b789bd 100644
--- a/tv/tuner/aidl/default/Demux.h
+++ b/tv/tuner/aidl/default/Demux.h
@@ -20,7 +20,10 @@
#include <fmq/AidlMessageQueue.h>
#include <math.h>
+#include <atomic>
#include <set>
+#include <thread>
+
#include "Dvr.h"
#include "Filter.h"
#include "Frontend.h"
@@ -155,12 +158,14 @@
std::shared_ptr<Dvr> mDvrRecord;
// Thread handlers
- pthread_t mFrontendInputThread;
+ std::thread mFrontendInputThread;
+
/**
* If a specific filter's writing loop is still running
*/
- bool mFrontendInputThreadRunning;
- bool mKeepFetchingDataFromFrontend;
+ std::atomic<bool> mFrontendInputThreadRunning;
+ std::atomic<bool> mKeepFetchingDataFromFrontend;
+
/**
* If the dvr recording is running.
*/
@@ -169,10 +174,6 @@
* Lock to protect writes to the FMQs
*/
std::mutex mWriteLock;
- /**
- * Lock to protect writes to the input status
- */
- std::mutex mFrontendInputThreadLock;
// temp handle single PES filter
// TODO handle mulptiple Pes filters
diff --git a/tv/tuner/aidl/default/Dvr.h b/tv/tuner/aidl/default/Dvr.h
index 586f885..ad8728e 100644
--- a/tv/tuner/aidl/default/Dvr.h
+++ b/tv/tuner/aidl/default/Dvr.h
@@ -129,7 +129,7 @@
* If a specific filter's writing loop is still running
*/
std::atomic<bool> mDvrThreadRunning;
- bool mKeepFetchingDataFromFrontend;
+
/**
* Lock to protect writes to the FMQs
*/
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index 9755e39..bf89d12 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -85,8 +85,7 @@
}
Filter::~Filter() {
- mFilterThreadRunning = false;
- std::lock_guard<std::mutex> lock(mFilterThreadLock);
+ close();
}
::ndk::ScopedAStatus Filter::getId64Bit(int64_t* _aidl_return) {
@@ -187,8 +186,12 @@
::ndk::ScopedAStatus Filter::stop() {
ALOGV("%s", __FUNCTION__);
+
mFilterThreadRunning = false;
- std::lock_guard<std::mutex> lock(mFilterThreadLock);
+ if (mFilterThread.joinable()) {
+ mFilterThread.join();
+ }
+
return ::ndk::ScopedAStatus::ok();
}
@@ -226,8 +229,8 @@
::ndk::ScopedAStatus Filter::close() {
ALOGV("%s", __FUNCTION__);
- mFilterThreadRunning = false;
- std::lock_guard<std::mutex> lock(mFilterThreadLock);
+ stop();
+
return mDemux->removeFilter(mFilterId);
}
@@ -376,22 +379,15 @@
}
::ndk::ScopedAStatus Filter::startFilterLoop() {
- pthread_create(&mFilterThread, NULL, __threadLoopFilter, this);
- pthread_setname_np(mFilterThread, "filter_waiting_loop");
+ mFilterThread = std::thread(&Filter::filterThreadLoop, this);
return ::ndk::ScopedAStatus::ok();
}
-void* Filter::__threadLoopFilter(void* user) {
- Filter* const self = static_cast<Filter*>(user);
- self->filterThreadLoop();
- return 0;
-}
-
void Filter::filterThreadLoop() {
if (!mFilterThreadRunning) {
return;
}
- std::lock_guard<std::mutex> lock(mFilterThreadLock);
+
ALOGD("[Filter] filter %" PRIu64 " threadLoop start.", mFilterId);
// For the first time of filter output, implementation needs to send the filter
diff --git a/tv/tuner/aidl/default/Filter.h b/tv/tuner/aidl/default/Filter.h
index 3f40256..2ca25af 100644
--- a/tv/tuner/aidl/default/Filter.h
+++ b/tv/tuner/aidl/default/Filter.h
@@ -24,7 +24,10 @@
#include <ion/ion.h>
#include <math.h>
#include <sys/stat.h>
+#include <atomic>
#include <set>
+#include <thread>
+
#include "Demux.h"
#include "Dvr.h"
#include "Frontend.h"
@@ -126,15 +129,14 @@
vector<DemuxFilterEvent> mFilterEvents;
// Thread handlers
- pthread_t mFilterThread;
+ std::thread mFilterThread;
// FMQ status local records
DemuxFilterStatus mFilterStatus;
/**
* If a specific filter's writing loop is still running
*/
- bool mFilterThreadRunning;
- bool mKeepFetchingDataFromFrontend;
+ std::atomic<bool> mFilterThreadRunning;
/**
* How many times a filter should write
@@ -204,7 +206,6 @@
* Lock to protect writes to the input status
*/
std::mutex mFilterStatusLock;
- std::mutex mFilterThreadLock;
std::mutex mFilterOutputLock;
std::mutex mRecordFilterOutputLock;
diff --git a/tv/tuner/aidl/vts/functional/DvrTests.cpp b/tv/tuner/aidl/vts/functional/DvrTests.cpp
index e356099..a9c3b51 100644
--- a/tv/tuner/aidl/vts/functional/DvrTests.cpp
+++ b/tv/tuner/aidl/vts/functional/DvrTests.cpp
@@ -24,26 +24,22 @@
mPlaybackSettings = settings;
mPlaybackMQ = std::make_unique<FilterMQ>(playbackMQDescriptor, true /* resetPointers */);
EXPECT_TRUE(mPlaybackMQ);
- pthread_create(&mPlaybackThread, NULL, __threadLoopPlayback, this);
- pthread_setname_np(mPlaybackThread, "test_playback_input_loop");
+
+ mPlaybackThread = std::thread(&DvrCallback::playbackThreadLoop, this);
}
void DvrCallback::stopPlaybackThread() {
mPlaybackThreadRunning = false;
mKeepWritingPlaybackFMQ = false;
- android::Mutex::Autolock autoLock(mPlaybackThreadLock);
-}
-
-void* DvrCallback::__threadLoopPlayback(void* user) {
- DvrCallback* const self = static_cast<DvrCallback*>(user);
- self->playbackThreadLoop();
- return 0;
+ if (mPlaybackThread.joinable()) {
+ mPlaybackThread.join();
+ }
}
void DvrCallback::playbackThreadLoop() {
- android::Mutex::Autolock autoLock(mPlaybackThreadLock);
mPlaybackThreadRunning = true;
+ mKeepWritingPlaybackFMQ = true;
// Create the EventFlag that is used to signal the HAL impl that data have been
// written into the Playback FMQ
@@ -121,43 +117,31 @@
}
void DvrCallback::testRecordOutput() {
- android::Mutex::Autolock autoLock(mMsgLock);
- while (mDataOutputBuffer.empty()) {
- if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
- EXPECT_TRUE(false) << "record output matching pid does not output within timeout";
- stopRecordThread();
- return;
+ bool passed = true;
+ {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ while (mDataOutputBuffer.empty()) {
+ if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+ EXPECT_TRUE(false) << "record output matching pid does not output within timeout";
+ passed = false;
+ break;
+ }
}
}
stopRecordThread();
- ALOGW("[vts] record pass and stop");
+ if (passed) ALOGW("[vts] record pass and stop");
}
-void DvrCallback::startRecordOutputThread(RecordSettings recordSettings,
+void DvrCallback::startRecordOutputThread(RecordSettings /* recordSettings */,
MQDesc& recordMQDescriptor) {
mRecordMQ = std::make_unique<FilterMQ>(recordMQDescriptor, true /* resetPointers */);
EXPECT_TRUE(mRecordMQ);
- struct RecordThreadArgs* threadArgs =
- (struct RecordThreadArgs*)malloc(sizeof(struct RecordThreadArgs));
- threadArgs->user = this;
- threadArgs->recordSettings = &recordSettings;
- threadArgs->keepReadingRecordFMQ = &mKeepReadingRecordFMQ;
- pthread_create(&mRecordThread, NULL, __threadLoopRecord, (void*)threadArgs);
- pthread_setname_np(mRecordThread, "test_record_input_loop");
+ mRecordThread = std::thread(&DvrCallback::recordThreadLoop, this);
}
-void* DvrCallback::__threadLoopRecord(void* threadArgs) {
- DvrCallback* const self =
- static_cast<DvrCallback*>(((struct RecordThreadArgs*)threadArgs)->user);
- self->recordThreadLoop(((struct RecordThreadArgs*)threadArgs)->recordSettings,
- ((struct RecordThreadArgs*)threadArgs)->keepReadingRecordFMQ);
- return 0;
-}
-
-void DvrCallback::recordThreadLoop(RecordSettings* /*recordSettings*/, bool* keepReadingRecordFMQ) {
+void DvrCallback::recordThreadLoop() {
ALOGD("[vts] DvrCallback record threadLoop start.");
- android::Mutex::Autolock autoLock(mRecordThreadLock);
mRecordThreadRunning = true;
mKeepReadingRecordFMQ = true;
@@ -168,7 +152,7 @@
android::OK);
while (mRecordThreadRunning) {
- while (*keepReadingRecordFMQ) {
+ while (mKeepReadingRecordFMQ) {
uint32_t efState = 0;
android::status_t status = recordMQEventFlag->wait(
static_cast<int32_t>(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT,
@@ -206,6 +190,10 @@
void DvrCallback::stopRecordThread() {
mKeepReadingRecordFMQ = false;
mRecordThreadRunning = false;
+
+ if (mRecordThread.joinable()) {
+ mRecordThread.join();
+ }
}
AssertionResult DvrTests::openDvrInDemux(DvrType type, int32_t bufferSize) {
diff --git a/tv/tuner/aidl/vts/functional/DvrTests.h b/tv/tuner/aidl/vts/functional/DvrTests.h
index bda57b3..6662637 100644
--- a/tv/tuner/aidl/vts/functional/DvrTests.h
+++ b/tv/tuner/aidl/vts/functional/DvrTests.h
@@ -22,9 +22,11 @@
#include <log/log.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
+#include <atomic>
#include <fstream>
#include <iostream>
#include <map>
+#include <thread>
#include <aidl/android/hardware/tv/tuner/BnDvrCallback.h>
#include <aidl/android/hardware/tv/tuner/IDvr.h>
@@ -94,7 +96,7 @@
static void* __threadLoopPlayback(void* user);
static void* __threadLoopRecord(void* threadArgs);
void playbackThreadLoop();
- void recordThreadLoop(RecordSettings* recordSetting, bool* keepWritingPlaybackFMQ);
+ void recordThreadLoop();
bool readRecordFMQ();
@@ -115,16 +117,14 @@
std::map<uint32_t, EventFlag*> mFilterMQEventFlag;
android::Mutex mMsgLock;
- android::Mutex mPlaybackThreadLock;
- android::Mutex mRecordThreadLock;
android::Condition mMsgCondition;
- bool mKeepWritingPlaybackFMQ = true;
- bool mKeepReadingRecordFMQ = true;
- bool mPlaybackThreadRunning;
- bool mRecordThreadRunning;
- pthread_t mPlaybackThread;
- pthread_t mRecordThread;
+ std::atomic<bool> mKeepWritingPlaybackFMQ = true;
+ std::atomic<bool> mKeepReadingRecordFMQ = true;
+ std::atomic<bool> mPlaybackThreadRunning;
+ std::atomic<bool> mRecordThreadRunning;
+ std::thread mPlaybackThread;
+ std::thread mRecordThread;
string mInputDataFile;
PlaybackSettings mPlaybackSettings;