Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5494506c authored by sadiqsada's avatar sadiqsada
Browse files

Terminate IPTV read thread on demux close

IPTV reading thread doesn't have a termination condition. This CL
adds a flag mIsIptvReadThreadTerminated which tracks whether the
thread resources should be cleaned up.

Bug: 288170590
Test: atest VtsHalTvTunerTargetTest
Change-Id: I3a19e1045ee67dac2d95457d217adb1375674ed4
parent c5707a25
Loading
Loading
Loading
Loading
+26 −14
Original line number Original line Diff line number Diff line
@@ -53,9 +53,6 @@ void Demux::setTunerService(std::shared_ptr<Tuner> tuner) {


Demux::~Demux() {
Demux::~Demux() {
    ALOGV("%s", __FUNCTION__);
    ALOGV("%s", __FUNCTION__);
    if (mDemuxIptvReadThread.joinable()) {
        mDemuxIptvReadThread.join();
    }
    close();
    close();
}
}


@@ -123,12 +120,17 @@ void Demux::setIptvThreadRunning(bool isIptvThreadRunning) {
    mIsIptvThreadRunningCv.notify_all();
    mIsIptvThreadRunningCv.notify_all();
}
}


void Demux::frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* streamer) {
void Demux::frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* streamer, void* buf) {
    Timer *timer, *fullBufferTimer;
    Timer *timer, *fullBufferTimer;
    bool isTuneBytePushedToDvr = false;
    bool isTuneBytePushedToDvr = false;
    while (true) {
    while (true) {
        std::unique_lock<std::mutex> lock(mIsIptvThreadRunningMutex);
        std::unique_lock<std::mutex> lock(mIsIptvThreadRunningMutex);
        mIsIptvThreadRunningCv.wait(lock, [this] { return mIsIptvReadThreadRunning; });
        mIsIptvThreadRunningCv.wait(
                lock, [this] { return mIsIptvReadThreadRunning || mIsIptvReadThreadTerminated; });
        if (mIsIptvReadThreadTerminated) {
            ALOGI("[Demux] IPTV reading thread for playback terminated");
            break;
        }
        if (mIsIptvDvrFMQFull &&
        if (mIsIptvDvrFMQFull &&
            fullBufferTimer->get_elapsed_time_ms() > IPTV_PLAYBACK_BUFFER_TIMEOUT) {
            fullBufferTimer->get_elapsed_time_ms() > IPTV_PLAYBACK_BUFFER_TIMEOUT) {
            ALOGE("DVR FMQ has not been flushed within timeout of %d ms",
            ALOGE("DVR FMQ has not been flushed within timeout of %d ms",
@@ -137,11 +139,6 @@ void Demux::frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* str
            break;
            break;
        }
        }
        timer = new Timer();
        timer = new Timer();
        void* buf = malloc(sizeof(char) * IPTV_BUFFER_SIZE);
        if (buf == nullptr) {
            ALOGE("[Demux] Buffer allocation failed");
            return;
        }
        ssize_t bytes_read;
        ssize_t bytes_read;
        void* tuneByteBuffer = mFrontend->getTuneByteBuffer();
        void* tuneByteBuffer = mFrontend->getTuneByteBuffer();
        if (!isTuneBytePushedToDvr && tuneByteBuffer != nullptr) {
        if (!isTuneBytePushedToDvr && tuneByteBuffer != nullptr) {
@@ -187,8 +184,6 @@ void Demux::frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* str
            default:
            default:
                ALOGI("Invalid DVR Status");
                ALOGI("Invalid DVR Status");
        }
        }

        free(buf);
    }
    }
}
}


@@ -251,9 +246,16 @@ void Demux::frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* str
                        static_cast<int32_t>(Result::INVALID_STATE));
                        static_cast<int32_t>(Result::INVALID_STATE));
            }
            }
        }
        }

        stopIptvFrontendInput();
        mIsIptvReadThreadTerminated = false;
        void* buf = malloc(sizeof(char) * IPTV_BUFFER_SIZE);
        if (buf == nullptr) {
            ALOGE("[Demux] Buffer allocation failed");
            return ::ndk::ScopedAStatus::fromServiceSpecificError(
                    static_cast<int32_t>(Result::INVALID_STATE));
        }
        mDemuxIptvReadThread =
        mDemuxIptvReadThread =
                std::thread(&Demux::frontendIptvInputThreadLoop, this, interface, streamer);
                std::thread(&Demux::frontendIptvInputThreadLoop, this, interface, streamer, buf);
    }
    }
    return ::ndk::ScopedAStatus::ok();
    return ::ndk::ScopedAStatus::ok();
}
}
@@ -370,6 +372,7 @@ void Demux::frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* str
    ALOGV("%s", __FUNCTION__);
    ALOGV("%s", __FUNCTION__);


    stopFrontendInput();
    stopFrontendInput();
    stopIptvFrontendInput();


    set<int64_t>::iterator it;
    set<int64_t>::iterator it;
    for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
    for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
@@ -565,6 +568,15 @@ void Demux::stopFrontendInput() {
    }
    }
}
}


void Demux::stopIptvFrontendInput() {
    ALOGD("[Demux] stop iptv frontend on demux");
    if (mDemuxIptvReadThread.joinable()) {
        mIsIptvReadThreadTerminated = true;
        mIsIptvThreadRunningCv.notify_all();
        mDemuxIptvReadThread.join();
    }
}

void Demux::setIsRecording(bool isRecording) {
void Demux::setIsRecording(bool isRecording) {
    mIsRecording = isRecording;
    mIsRecording = isRecording;
}
}
+7 −2
Original line number Original line Diff line number Diff line
@@ -106,7 +106,7 @@ class Demux : public BnDemux {
    void setIsRecording(bool isRecording);
    void setIsRecording(bool isRecording);
    bool isRecording();
    bool isRecording();
    void startFrontendInputLoop();
    void startFrontendInputLoop();
    void frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* streamer);
    void frontendIptvInputThreadLoop(dtv_plugin* interface, dtv_streamer* streamer, void* buf);


    /**
    /**
     * A dispatcher to read and dispatch input data to all the started filters.
     * A dispatcher to read and dispatch input data to all the started filters.
@@ -130,6 +130,10 @@ class Demux : public BnDemux {
     * Setter for IPTV Reading thread
     * Setter for IPTV Reading thread
     */
     */
    void setIptvThreadRunning(bool isIptvThreadRunning);
    void setIptvThreadRunning(bool isIptvThreadRunning);
    /**
     * Stops IPTV playback reading thread.
     */
    void stopIptvFrontendInput();


  private:
  private:
    // Tuner service
    // Tuner service
@@ -208,7 +212,8 @@ class Demux : public BnDemux {
    /**
    /**
     * Controls IPTV reading thread status
     * Controls IPTV reading thread status
     */
     */
    bool mIsIptvReadThreadRunning;
    bool mIsIptvReadThreadRunning = false;
    std::atomic<bool> mIsIptvReadThreadTerminated = false;
    std::mutex mIsIptvThreadRunningMutex;
    std::mutex mIsIptvThreadRunningMutex;
    std::condition_variable mIsIptvThreadRunningCv;
    std::condition_variable mIsIptvThreadRunningCv;