[vlmc-devel] MediaLibraryModel: Avoid calling functions from the medialibrary thread

yikei lu luyikei.qmltu at gmail.com
Thu Jul 13 11:28:30 CEST 2017


This patch fixes "QQmlEngine: Illegal attempt to connect to
MediaItem_QMLTYPE_62(0x7f484c048fc0) that is in a different thread
than the QML engine QQmlEngine(0x378a480."

It seems that Qt Quick doesn't even allow to do gui-related tasks from
any thread other than the qml engine thread.

But still I'm not really sure that this is the best fix though....

Regards,

On Thu, Jul 13, 2017 at 4:51 PM, Hugo Beauzée-Luyssen <hugo at beauzee.fr> wrote:
> On Sat, Jun 24, 2017, at 12:49 PM, Yikai Lu wrote:
>> vlmc | branch: master | Yikai Lu <luyikei.qmltu at gmail.com> | Sun Jun 25
>> 03:07:48 2017 +0900| [e14eb6dc24560185065ebe68f9359defdd990209] |
>> committer: Yikai Lu
>>
>> MediaLibraryModel: Avoid calling functions from the medialibrary thread
>>
>> > https://code.videolan.org/videolan/vlmc/commit/e14eb6dc24560185065ebe68f9359defdd990209
>> ---
>>
>>  src/Library/Library.cpp           | 23 +++++++++++++++++------
>>  src/Library/MediaLibraryModel.cpp |  1 +
>>  src/Library/MediaLibraryModel.h   | 10 ++++++----
>>  3 files changed, 24 insertions(+), 10 deletions(-)
>>
>> diff --git a/src/Library/Library.cpp b/src/Library/Library.cpp
>> index 8430d08a..a978e365 100644
>> --- a/src/Library/Library.cpp
>> +++ b/src/Library/Library.cpp
>> @@ -212,7 +212,9 @@ Library::onMediaAdded(
>> std::vector<medialibrary::MediaPtr> mediaList )
>>  {
>>      for ( auto m : mediaList )
>>      {
>> -        m_model->addMedia( m );
>> +        QMetaObject::invokeMethod( m_model, "addMedia",
>> +                                   Qt::QueuedConnection,
>> +                                   Q_ARG( medialibrary::MediaPtr, m ) );
>>      }
>>  }
>>
>> @@ -221,7 +223,9 @@ Library::onMediaUpdated(
>> std::vector<medialibrary::MediaPtr> mediaList )
>>  {
>>      for ( auto m : mediaList )
>>      {
>> -        m_model->updateMedia( m );
>> +        QMetaObject::invokeMethod( m_model, "updateMedia",
>> +                                   Qt::QueuedConnection,
>> +                                   Q_ARG( medialibrary::MediaPtr, m ) );
>>      }
>>  }
>>
>> @@ -229,7 +233,9 @@ void
>>  Library::onMediaDeleted( std::vector<int64_t> mediaList )
>>  {
>>      for ( auto id : mediaList )
>> -        m_model->removeMedia( id );
>> +        QMetaObject::invokeMethod( m_model, "removeMedia",
>> +                                   Qt::QueuedConnection,
>> +                                   Q_ARG( int64_t, id ) );
>>  }
>>
>>  void
>> @@ -287,7 +293,8 @@ void
>>  Library::onDiscoveryCompleted( const std::string& entryPoint )
>>  {
>>      if ( entryPoint.empty() == true )
>> -        m_model->refresh();
>> +        QMetaObject::invokeMethod( m_model, "refresh",
>> +                                   Qt::QueuedConnection );
>>
>>      emit discoveryCompleted( QString::fromStdString( entryPoint ) );
>>  }
>> @@ -324,10 +331,14 @@ Library::onReloadCompleted( const std::string&
>> entryPoint )
>>      if ( entryPoint.empty() == true )
>>      {
>>          for ( auto media : m_ml->videoFiles() )
>> -            m_model->addMedia( media );
>> +            QMetaObject::invokeMethod( m_model, "addMedia",
>> +                                       Qt::QueuedConnection,
>> +                                       Q_ARG( medialibrary::MediaPtr,
>> media ) );
>>
>>          for ( auto media : m_ml->audioFiles() )
>> -            m_model->addMedia( media );
>> +            QMetaObject::invokeMethod( m_model, "addMedia",
>> +                                       Qt::QueuedConnection,
>> +                                       Q_ARG( medialibrary::MediaPtr,
>> media ) );
>>      }
>>  }
>>
>> diff --git a/src/Library/MediaLibraryModel.cpp
>> b/src/Library/MediaLibraryModel.cpp
>> index ecd1d1a8..e22581e2 100644
>> --- a/src/Library/MediaLibraryModel.cpp
>> +++ b/src/Library/MediaLibraryModel.cpp
>> @@ -30,6 +30,7 @@ MediaLibraryModel::MediaLibraryModel(
>> medialibrary::IMediaLibrary& ml, QObject *
>>      , m_ml( ml )
>>      , m_rowCount( 0 )
>>  {
>> +    qRegisterMetaType<medialibrary::MediaPtr>();
>>  }
>>
>>  void MediaLibraryModel::addMedia( medialibrary::MediaPtr media )
>> diff --git a/src/Library/MediaLibraryModel.h
>> b/src/Library/MediaLibraryModel.h
>> index 7729ff05..edddb73d 100644
>> --- a/src/Library/MediaLibraryModel.h
>> +++ b/src/Library/MediaLibraryModel.h
>> @@ -46,16 +46,18 @@ public:
>>
>>      explicit MediaLibraryModel( medialibrary::IMediaLibrary& ml, QObject
>>      *parent = 0 );
>>
>> -    void addMedia( medialibrary::MediaPtr media );
>>      medialibrary::MediaPtr findMedia( qint64 mediaId );
>> -    void updateMedia( medialibrary::MediaPtr media );
>> -    bool removeMedia( int64_t media );
>> -    void refresh();
>>
>>      virtual int rowCount( const QModelIndex &parent = QModelIndex() )
>>      const override;
>>      virtual QVariant data( const QModelIndex &index, int role =
>>      Qt::DisplayRole ) const override;
>>      virtual QHash<int, QByteArray> roleNames() const override;
>>
>> +public slots:
>> +    void addMedia( medialibrary::MediaPtr media );
>> +    void updateMedia( medialibrary::MediaPtr media );
>> +    bool removeMedia( int64_t media );
>> +    void refresh();
>> +
>>  private:
>>      medialibrary::IMediaLibrary& m_ml;
>>
>>
>> _______________________________________________
>> Vlmc-devel mailing list
>> Vlmc-devel at videolan.org
>> https://mailman.videolan.org/listinfo/vlmc-devel
>
> Any reason this is using QMetaObject::invokeMethod instead of a signal?
> Also the medialibrary has a dedicated thread for notifications, so you
> can do "long" operations there
>
> --
>   Hugo Beauzée-Luyssen
>   hugo at beauzee.fr
> _______________________________________________
> Vlmc-devel mailing list
> Vlmc-devel at videolan.org
> https://mailman.videolan.org/listinfo/vlmc-devel


More information about the Vlmc-devel mailing list