Skip to content

Commit

Permalink
[AdaptiveTree] Stop manifest updates before class deconstruction
Browse files Browse the repository at this point in the history
  • Loading branch information
CastagnaIT committed Sep 15, 2023
1 parent 19e8fae commit 005a9a6
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ CSession::~CSession()
m_streams.clear();
DisposeDecrypter();

m_adaptiveTree->Uninitialize();

delete m_adaptiveTree;
m_adaptiveTree = nullptr;

Expand Down
5 changes: 5 additions & 0 deletions src/common/AdaptiveStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,11 @@ bool AdaptiveStream::ensureSegment()
{
// wait until worker is ready for new segment
std::unique_lock<std::mutex> lck(thread_data_->mutex_dl_);

// check if it has been stopped in the meantime (e.g. playback stop)
if (state_ == STOPPED)
return false;

// lock live segment updates
std::lock_guard<adaptive::AdaptiveTree::TreeUpdateThread> lckUpdTree(tree_.GetTreeUpdMutex());

Expand Down
23 changes: 20 additions & 3 deletions src/common/AdaptiveTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ namespace adaptive
static_cast<uint32_t>(kodi::addon::GetSettingInt("MAXBUFFERDURATION"));
}

void AdaptiveTree::Uninitialize()
{
// Stop the update thread before the tree class deconstruction otherwise derived classes
// will be destructed early, so while an update could be just started
m_updThread.Stop();
}

void AdaptiveTree::PostOpen(const UTILS::PROPERTIES::KodiProperties& kodiProps)
{
SortTree();
Expand Down Expand Up @@ -198,13 +205,12 @@ namespace adaptive
AdaptiveTree::TreeUpdateThread::~TreeUpdateThread()
{
// assert(m_waitQueue == 0); // Debug only, missing resume

// We assume that Stop() method has been called before the deconstruction
m_threadStop = true;

if (m_thread.joinable())
{
m_cvUpdInterval.notify_all(); // Unlock possible waiting
m_thread.join();
}
}

void AdaptiveTree::TreeUpdateThread::Initialize(AdaptiveTree* tree)
Expand All @@ -229,6 +235,8 @@ namespace adaptive
// If paused, wait until last "Resume" will be called
std::unique_lock<std::mutex> lckWait(m_waitMutex);
m_cvWait.wait(lckWait, [&] { return m_waitQueue == 0; });
if (m_threadStop)
break;

updLck.lock();
m_tree->RefreshLiveSegments();
Expand All @@ -252,4 +260,13 @@ namespace adaptive
m_cvWait.notify_all();
}

void AdaptiveTree::TreeUpdateThread::Stop()
{
m_threadStop = true;
// If an update is already in progress wait until exit
std::lock_guard<std::mutex> updLck{m_updMutex};
m_cvUpdInterval.notify_all();
m_cvWait.notify_all();
}

} // namespace adaptive
8 changes: 8 additions & 0 deletions src/common/AdaptiveTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ class ATTR_DLL_LOCAL AdaptiveTree
std::string_view supportedKeySystem,
std::string_view manifestUpdParams);

/*!
* \brief Performs operations to stop running process and release resources.
*/
virtual void Uninitialize();

/*!
* \brief Open manifest data for parsing.
* \param url Effective url where the manifest is downloaded
Expand Down Expand Up @@ -237,6 +242,9 @@ class ATTR_DLL_LOCAL AdaptiveTree
// \brief As "std::mutex" unlock, but resume the manifest updates (support std::lock_guard).
void unlock() { Resume(); }

// \brief Stop performing new updates.
void Stop();

private:
void Worker();
void Pause();
Expand Down

0 comments on commit 005a9a6

Please sign in to comment.