Clean Up Playback Thread in DVR Test Implementation

Bug: 194476544
Test: atest VtsHalTvTunerV1_0TargetTest && atest
VtsHalTvTunerV1_1TargetTest

Change-Id: I639e8314a499c07758c4927fa10cb4ff0e6dcb50
This commit is contained in:
Patrick Rohr 2021-07-23 14:56:53 +02:00
parent 93b2454563
commit 45eff329e0
4 changed files with 28 additions and 38 deletions

View file

@ -37,7 +37,10 @@ Dvr::Dvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb, sp<Demux
mDemux = demux; mDemux = demux;
} }
Dvr::~Dvr() {} Dvr::~Dvr() {
// make sure thread has joined
close();
}
Return<void> Dvr::getQueueDesc(getQueueDesc_cb _hidl_cb) { Return<void> Dvr::getQueueDesc(getQueueDesc_cb _hidl_cb) {
ALOGV("%s", __FUNCTION__); ALOGV("%s", __FUNCTION__);
@ -112,8 +115,7 @@ Return<Result> Dvr::start() {
} }
if (mType == DvrType::PLAYBACK) { if (mType == DvrType::PLAYBACK) {
pthread_create(&mDvrThread, NULL, __threadLoopPlayback, this); mDvrThread = std::thread(&Dvr::playbackThreadLoop, this);
pthread_setname_np(mDvrThread, "playback_waiting_loop");
} else if (mType == DvrType::RECORD) { } else if (mType == DvrType::RECORD) {
mRecordStatus = RecordStatus::DATA_READY; mRecordStatus = RecordStatus::DATA_READY;
mDemux->setIsRecording(mType == DvrType::RECORD); mDemux->setIsRecording(mType == DvrType::RECORD);
@ -128,9 +130,11 @@ Return<Result> Dvr::stop() {
ALOGV("%s", __FUNCTION__); ALOGV("%s", __FUNCTION__);
mDvrThreadRunning = false; mDvrThreadRunning = false;
if (mDvrThread.joinable()) {
lock_guard<mutex> lock(mDvrThreadLock); mDvrThread.join();
}
// thread should always be joinable if it is running,
// so it should be safe to assume recording stopped.
mDemux->setIsRecording(false); mDemux->setIsRecording(false);
return Result::SUCCESS; return Result::SUCCESS;
@ -146,7 +150,7 @@ Return<Result> Dvr::flush() {
Return<Result> Dvr::close() { Return<Result> Dvr::close() {
ALOGV("%s", __FUNCTION__); ALOGV("%s", __FUNCTION__);
stop();
return Result::SUCCESS; return Result::SUCCESS;
} }
@ -173,15 +177,8 @@ EventFlag* Dvr::getDvrEventFlag() {
return mDvrEventFlag; return mDvrEventFlag;
} }
void* Dvr::__threadLoopPlayback(void* user) {
Dvr* const self = static_cast<Dvr*>(user);
self->playbackThreadLoop();
return 0;
}
void Dvr::playbackThreadLoop() { void Dvr::playbackThreadLoop() {
ALOGD("[Dvr] playback threadLoop start."); ALOGD("[Dvr] playback threadLoop start.");
lock_guard<mutex> lock(mDvrThreadLock);
mDvrThreadRunning = true; mDvrThreadRunning = true;
while (mDvrThreadRunning) { while (mDvrThreadRunning) {

View file

@ -20,7 +20,9 @@
#include <android/hardware/tv/tuner/1.0/IDvr.h> #include <android/hardware/tv/tuner/1.0/IDvr.h>
#include <fmq/MessageQueue.h> #include <fmq/MessageQueue.h>
#include <math.h> #include <math.h>
#include <atomic>
#include <set> #include <set>
#include <thread>
#include "Demux.h" #include "Demux.h"
#include "Frontend.h" #include "Frontend.h"
#include "Tuner.h" #include "Tuner.h"
@ -119,7 +121,6 @@ class Dvr : public IDvr {
* Each filter handler handles the data filtering/output writing/filterEvent updating. * Each filter handler handles the data filtering/output writing/filterEvent updating.
*/ */
void startTpidFilter(vector<uint8_t> data); void startTpidFilter(vector<uint8_t> data);
static void* __threadLoopPlayback(void* user);
static void* __threadLoopRecord(void* user); static void* __threadLoopRecord(void* user);
void playbackThreadLoop(); void playbackThreadLoop();
void recordThreadLoop(); void recordThreadLoop();
@ -133,7 +134,7 @@ class Dvr : public IDvr {
DvrSettings mDvrSettings; DvrSettings mDvrSettings;
// Thread handlers // Thread handlers
pthread_t mDvrThread; std::thread mDvrThread;
// FMQ status local records // FMQ status local records
PlaybackStatus mPlaybackStatus; PlaybackStatus mPlaybackStatus;
@ -141,7 +142,7 @@ class Dvr : public IDvr {
/** /**
* If a specific filter's writing loop is still running * If a specific filter's writing loop is still running
*/ */
bool mDvrThreadRunning; std::atomic<bool> mDvrThreadRunning;
bool mKeepFetchingDataFromFrontend; bool mKeepFetchingDataFromFrontend;
/** /**
* Lock to protect writes to the FMQs * Lock to protect writes to the FMQs
@ -152,7 +153,6 @@ class Dvr : public IDvr {
*/ */
std::mutex mPlaybackStatusLock; std::mutex mPlaybackStatusLock;
std::mutex mRecordStatusLock; std::mutex mRecordStatusLock;
std::mutex mDvrThreadLock;
const bool DEBUG_DVR = false; const bool DEBUG_DVR = false;
}; };

View file

@ -38,8 +38,8 @@ Dvr::Dvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb, sp<Demux
} }
Dvr::~Dvr() { Dvr::~Dvr() {
mDvrThreadRunning = false; // make sure thread has joined
lock_guard<mutex> lock(mDvrThreadLock); close();
} }
Return<void> Dvr::getQueueDesc(getQueueDesc_cb _hidl_cb) { Return<void> Dvr::getQueueDesc(getQueueDesc_cb _hidl_cb) {
@ -134,8 +134,7 @@ Return<Result> Dvr::start() {
if (mType == DvrType::PLAYBACK) { if (mType == DvrType::PLAYBACK) {
mDvrThreadRunning = true; mDvrThreadRunning = true;
pthread_create(&mDvrThread, NULL, __threadLoopPlayback, this); mDvrThread = std::thread(&Dvr::playbackThreadLoop, this);
pthread_setname_np(mDvrThread, "playback_waiting_loop");
} else if (mType == DvrType::RECORD) { } else if (mType == DvrType::RECORD) {
mRecordStatus = RecordStatus::DATA_READY; mRecordStatus = RecordStatus::DATA_READY;
mDemux->setIsRecording(mType == DvrType::RECORD); mDemux->setIsRecording(mType == DvrType::RECORD);
@ -150,8 +149,11 @@ Return<Result> Dvr::stop() {
ALOGV("%s", __FUNCTION__); ALOGV("%s", __FUNCTION__);
mDvrThreadRunning = false; mDvrThreadRunning = false;
lock_guard<mutex> lock(mDvrThreadLock); if (mDvrThread.joinable()) {
mDvrThread.join();
}
// thread should always be joinable if it is running,
// so it should be safe to assume recording stopped.
mDemux->setIsRecording(false); mDemux->setIsRecording(false);
return Result::SUCCESS; return Result::SUCCESS;
@ -167,9 +169,7 @@ Return<Result> Dvr::flush() {
Return<Result> Dvr::close() { Return<Result> Dvr::close() {
ALOGV("%s", __FUNCTION__); ALOGV("%s", __FUNCTION__);
stop();
mDvrThreadRunning = false;
lock_guard<mutex> lock(mDvrThreadLock);
return Result::SUCCESS; return Result::SUCCESS;
} }
@ -196,15 +196,8 @@ EventFlag* Dvr::getDvrEventFlag() {
return mDvrEventFlag; return mDvrEventFlag;
} }
void* Dvr::__threadLoopPlayback(void* user) {
Dvr* const self = static_cast<Dvr*>(user);
self->playbackThreadLoop();
return 0;
}
void Dvr::playbackThreadLoop() { void Dvr::playbackThreadLoop() {
ALOGD("[Dvr] playback threadLoop start."); ALOGD("[Dvr] playback threadLoop start.");
lock_guard<mutex> lock(mDvrThreadLock);
while (mDvrThreadRunning) { while (mDvrThreadRunning) {
uint32_t efState = 0; uint32_t efState = 0;

View file

@ -19,7 +19,9 @@
#include <fmq/MessageQueue.h> #include <fmq/MessageQueue.h>
#include <math.h> #include <math.h>
#include <atomic>
#include <set> #include <set>
#include <thread>
#include "Demux.h" #include "Demux.h"
#include "Frontend.h" #include "Frontend.h"
#include "Tuner.h" #include "Tuner.h"
@ -115,7 +117,6 @@ class Dvr : public IDvr {
* Each filter handler handles the data filtering/output writing/filterEvent updating. * Each filter handler handles the data filtering/output writing/filterEvent updating.
*/ */
void startTpidFilter(vector<uint8_t> data); void startTpidFilter(vector<uint8_t> data);
static void* __threadLoopPlayback(void* user);
static void* __threadLoopRecord(void* user); static void* __threadLoopRecord(void* user);
void playbackThreadLoop(); void playbackThreadLoop();
void recordThreadLoop(); void recordThreadLoop();
@ -129,7 +130,7 @@ class Dvr : public IDvr {
DvrSettings mDvrSettings; DvrSettings mDvrSettings;
// Thread handlers // Thread handlers
pthread_t mDvrThread; std::thread mDvrThread;
// FMQ status local records // FMQ status local records
PlaybackStatus mPlaybackStatus; PlaybackStatus mPlaybackStatus;
@ -137,7 +138,7 @@ class Dvr : public IDvr {
/** /**
* If a specific filter's writing loop is still running * If a specific filter's writing loop is still running
*/ */
bool mDvrThreadRunning; std::atomic<bool> mDvrThreadRunning;
bool mKeepFetchingDataFromFrontend; bool mKeepFetchingDataFromFrontend;
/** /**
* Lock to protect writes to the FMQs * Lock to protect writes to the FMQs
@ -148,7 +149,6 @@ class Dvr : public IDvr {
*/ */
std::mutex mPlaybackStatusLock; std::mutex mPlaybackStatusLock;
std::mutex mRecordStatusLock; std::mutex mRecordStatusLock;
std::mutex mDvrThreadLock;
const bool DEBUG_DVR = false; const bool DEBUG_DVR = false;
}; };