[vlc-commits] qt: cancel preparse requests before destroying/changing model of NetworkMediaModel
Pierre Lamot
git at videolan.org
Thu Feb 13 11:06:33 CET 2020
vlc | branch: master | Pierre Lamot <pierre at videolabs.io> | Thu Feb 6 09:52:39 2020 +0100| [2f1293d41241ca57de72944b417109df762f9aa8] | committer: Jean-Baptiste Kempf
qt: cancel preparse requests before destroying/changing model of NetworkMediaModel
this caused a crash if the UI was destroyed when a request was pending
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2f1293d41241ca57de72944b417109df762f9aa8
---
modules/gui/qt/network/networkmediamodel.cpp | 18 +++++++++++++++++-
modules/gui/qt/network/networkmediamodel.hpp | 5 ++++-
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/modules/gui/qt/network/networkmediamodel.cpp b/modules/gui/qt/network/networkmediamodel.cpp
index 1a24f3de91..ca1e94c51d 100644
--- a/modules/gui/qt/network/networkmediamodel.cpp
+++ b/modules/gui/qt/network/networkmediamodel.cpp
@@ -40,10 +40,23 @@ enum Role {
NetworkMediaModel::NetworkMediaModel( QObject* parent )
: QAbstractListModel( parent )
+ , m_preparseSem(1)
, m_ml( nullptr )
{
}
+NetworkMediaModel::~NetworkMediaModel()
+{
+ //this can only be aquired from UI thread
+ if (!m_preparseSem.tryAcquire())
+ {
+ auto libvlc = vlc_object_instance(m_ctx->getIntf());
+ vlc_media_tree_PreparseCancel( libvlc, this );
+ //wait for the callback call on cancel
+ m_preparseSem.acquire();
+ }
+}
+
QVariant NetworkMediaModel::data( const QModelIndex& index, int role ) const
{
if (!m_ctx)
@@ -255,6 +268,8 @@ bool NetworkMediaModel::initializeMediaSources()
emit isIndexedChanged();
}
+ vlc_media_tree_PreparseCancel( libvlc, this );
+ m_preparseSem.acquire();
vlc_media_tree_Preparse( tree, libvlc, m_treeItem.media.get(), this );
m_parsingPending = true;
emit parsingPendingChanged(m_parsingPending);
@@ -335,8 +350,9 @@ void NetworkMediaModel::onItemRemoved(MediaSourcePtr, input_item_node_t * node,
}, Qt::QueuedConnection);
}
-void NetworkMediaModel::onItemPreparseEnded(MediaSourcePtr, input_item_node_t* node, enum input_item_preparse_status)
+void NetworkMediaModel::onItemPreparseEnded(MediaSourcePtr, input_item_node_t* node, enum input_item_preparse_status )
{
+ m_preparseSem.release();
InputItemPtr p_node { node->p_item };
QMetaObject::invokeMethod(this, [this, p_node=std::move(p_node)]() {
if (p_node != m_treeItem.media)
diff --git a/modules/gui/qt/network/networkmediamodel.hpp b/modules/gui/qt/network/networkmediamodel.hpp
index bc6c2ea8b5..969d085dc4 100644
--- a/modules/gui/qt/network/networkmediamodel.hpp
+++ b/modules/gui/qt/network/networkmediamodel.hpp
@@ -33,6 +33,8 @@
#include <util/qml_main_context.hpp>
#include "networksourcelistener.hpp"
+#include <QSemaphore>
+
#include <memory>
using MediaSourcePtr = vlc_shared_data_ptr_type(vlc_media_source_t,
@@ -98,6 +100,7 @@ public:
explicit NetworkMediaModel(QObject* parent = nullptr);
NetworkMediaModel( QmlMainContext* ctx, QString parentMrl, QObject* parent = nullptr );
+ virtual ~NetworkMediaModel() override;
QVariant data(const QModelIndex& index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
@@ -171,7 +174,7 @@ private:
bool m_indexed = false;
bool m_canBeIndexed = false;
bool m_parsingPending = false;
-
+ QSemaphore m_preparseSem;
std::vector<Item> m_items;
QmlMainContext* m_ctx = nullptr;
More information about the vlc-commits
mailing list