Commit 30140738 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

VLCMetadataService: Simplify and fix concurrency issues

We now only process one file at a time, as we do for snapshots.
The correct way would be to spawn more threads from the Parser class,
shall we want to process multiple items at once
parent ada103e4
......@@ -19,11 +19,6 @@ VLCMetadataService::VLCMetadataService( const VLC::Instance& vlc )
{
}
VLCMetadataService::~VLCMetadataService()
{
cleanup();
}
bool VLCMetadataService::initialize( IMetadataServiceCb* callback, IMediaLibrary* ml )
{
m_cb = callback;
......@@ -38,29 +33,26 @@ unsigned int VLCMetadataService::priority() const
bool VLCMetadataService::run( FilePtr file, void* data )
{
cleanup();
LOG_INFO( "Parsing ", file->mrl() );
auto ctx = new Context( file );
ctx->media = VLC::Media( m_instance, file->mrl(), VLC::Media::FromPath );
ctx->media.eventManager().onParsedChanged([this, ctx, data](bool status) mutable {
std::unique_lock<std::mutex> lock( m_mutex );
bool parsed;
ctx->media.eventManager().onParsedChanged([this, ctx, data, &parsed](bool status) mutable {
if ( status == false )
return;
auto res = handleMediaMeta( ctx->file, ctx->media );
m_cb->done( ctx->file, res, data );
// Delegate cleanup for a later time.
// Context owns a media, which owns an EventManager, which owns this lambda
// If we were to delete the context from here, the Media refcount would reach 0,
// thus deleting the media while in use.
// If we use a smart_ptr, then we get cyclic ownership:
// ctx -> media -> eventmanager -> event lambda -> ctx
// leading resources to never be released.
std::unique_lock<std::mutex> lock( m_cleanupLock );
m_cleanup.push_back( ctx );
std::unique_lock<std::mutex> lock( m_mutex );
parsed = true;
m_cond.notify_all();
});
ctx->media.parseAsync();
m_cond.wait( lock, [&parsed]() { return parsed == true; } );
return true;
}
......@@ -204,11 +196,3 @@ bool VLCMetadataService::parseVideoFile( FilePtr file, VLC::Media& media ) const
}
return true;
}
void VLCMetadataService::cleanup()
{
std::unique_lock<std::mutex> lock( m_cleanupLock );
for ( auto ctx : m_cleanup )
delete ctx;
m_cleanup.clear();
}
#ifndef VLCMETADATASERVICE_H
#define VLCMETADATASERVICE_H
#include <condition_variable>
#include <vlcpp/vlc.hpp>
#include <mutex>
......@@ -21,7 +22,6 @@ class VLCMetadataService : public IMetadataService
public:
VLCMetadataService(const VLC::Instance& vlc);
~VLCMetadataService();
virtual bool initialize( IMetadataServiceCb *callback, IMediaLibrary* ml );
virtual unsigned int priority() const;
......@@ -32,13 +32,12 @@ class VLCMetadataService : public IMetadataService
bool parseAudioFile(FilePtr file , VLC::Media &media) const;
bool parseVideoFile(FilePtr file , VLC::Media &media) const;
void cleanup();
VLC::Instance m_instance;
IMetadataServiceCb* m_cb;
IMediaLibrary* m_ml;
std::mutex m_cleanupLock;
std::vector<Context*> m_cleanup;
std::vector<Context*> m_keepAlive;
std::mutex m_mutex;
std::condition_variable m_cond;
};
#endif // VLCMETADATASERVICE_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment