Commit c78030f3 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen
Browse files

FsHolder: Use a callback interface to signal device reappearance

This allows to break more of the dependency on the media library
instance when dealing with device appearing/disappearing
parent 4328106b
......@@ -319,9 +319,15 @@ MediaLibrary::~MediaLibrary()
{
// Explicitely stop the discoverer, to avoid it writting while tearing down.
if ( m_discovererWorker != nullptr )
{
m_fsHolder.unregisterCallback( m_discovererWorker.get() );
m_discovererWorker->stop();
}
if ( m_parser != nullptr )
{
m_fsHolder.unregisterCallback( m_parser.get() );
m_parser->stop();
}
}
bool MediaLibrary::createAllTables()
......@@ -1103,6 +1109,7 @@ void MediaLibrary::startParser()
}
parser->addService( std::make_shared<parser::MetadataAnalyzer>() );
parser->addService( std::make_shared<parser::LinkService>() );
m_fsHolder.registerCallback( parser.get() );
parser->start();
m_parser = std::move( parser );
}
......@@ -1114,6 +1121,7 @@ void MediaLibrary::startDiscovererLocked()
auto discoverer = std::make_unique<FsDiscoverer>( this, m_fsHolder, m_callback );
m_discovererWorker.reset( new DiscovererWorker( this, &m_fsHolder,
std::move( discoverer ) ) );
m_fsHolder.registerCallback( m_discovererWorker.get() );
}
void MediaLibrary::startDiscoverer()
......@@ -2589,12 +2597,6 @@ void MediaLibrary::setLogger( ILogger* logger )
Log::SetLogger( logger );
}
DiscovererWorker* MediaLibrary::getDiscovererWorker()
{
std::lock_guard<compat::Mutex> lock{ m_mutex };
return m_discovererWorker.get();
}
void MediaLibrary::startFsFactory( fs::IFileSystemFactory &fsFactory ) const
{
m_fsHolder.startFsFactory( fsFactory );
......@@ -2736,6 +2738,7 @@ bool MediaLibrary::setExternalLibvlcInstance( libvlc_instance_t* inst )
std::lock_guard<compat::Mutex> lock{ m_mutex };
if ( m_discovererWorker != nullptr )
{
m_fsHolder.unregisterCallback( m_discovererWorker.get() );
m_discovererWorker->stop();
m_discovererWorker.reset();
restartDiscoverer = true;
......
......@@ -330,10 +330,6 @@ private:
virtual bool forceRescanLocked();
void startDiscovererLocked();
/* Temporary public accessors during refactoring */
public:
DiscovererWorker* getDiscovererWorker();
protected:
virtual void addLocalFsFactory();
void deleteAllTables( medialibrary::sqlite::Connection *dbConn );
......
......@@ -282,6 +282,11 @@ bool DiscovererWorker::filter( const DiscovererWorker::Task& newTask )
return filterOut;
}
void DiscovererWorker::onDeviceReappearing( int64_t deviceId )
{
reloadDevice( deviceId );
}
void DiscovererWorker::enqueue( DiscovererWorker::Task t )
{
std::unique_lock<compat::Mutex> lock( m_mutex );
......
......@@ -32,6 +32,7 @@
#include "compat/Mutex.h"
#include "compat/Thread.h"
#include "FsDiscoverer.h"
#include "filesystem/FsHolder.h"
namespace medialibrary
{
......@@ -44,7 +45,7 @@ namespace parser
class IParserCb;
}
class DiscovererWorker
class DiscovererWorker : public IFsHolderCb
{
protected:
struct Task
......@@ -108,6 +109,7 @@ private:
void runReloadAllDevices();
void runAddEntryPoint( const std::string& entryPoint );
bool filter( const Task& newTask );
virtual void onDeviceReappearing( int64_t deviceId ) override;
protected:
std::list<Task> m_tasks;
......
......@@ -60,6 +60,11 @@ FsHolder::FsHolder( MediaLibrary* ml )
#endif
}
FsHolder::~FsHolder()
{
assert( m_callbacks.empty() == true );
}
bool FsHolder::addFsFactory( std::shared_ptr<fs::IFileSystemFactory> fsFactory )
{
std::lock_guard<compat::Mutex> lock{ m_mutex };
......@@ -241,8 +246,34 @@ void FsHolder::startFsFactory( fs::IFileSystemFactory& fsFactory ) const
fsFactory.refreshDevices();
}
void FsHolder::registerCallback( IFsHolderCb* cb )
{
std::lock_guard<compat::Mutex> lock{ m_mutex };
auto it = std::find( cbegin( m_callbacks ), cend( m_callbacks ), cb );
if ( it != cend( m_callbacks ) )
{
assert( !"Double registration of IFsHolderCb" );
return;
}
m_callbacks.push_back( cb );
}
void FsHolder::unregisterCallback( IFsHolderCb* cb )
{
std::lock_guard<compat::Mutex> lock{ m_mutex };
auto it = std::find( cbegin( m_callbacks ), cend( m_callbacks ), cb );
if ( it == cend( m_callbacks ) )
{
assert( !"Unregistering unregistered callback" );
return;
}
m_callbacks.erase( it );
}
void FsHolder::onDeviceMounted( const fs::IDevice& deviceFs,
const std::string& newMountpoint )
const std::string& newMountpoint )
{
auto device = Device::fromUuid( m_ml, deviceFs.uuid(), deviceFs.scheme() );
if ( device == nullptr )
......@@ -274,13 +305,10 @@ void FsHolder::onDeviceMounted( const fs::IDevice& deviceFs,
// scanned.
// We also want to resume any parsing tasks that were previously
// started before the device went away
std::lock_guard<compat::Mutex> lock{ m_mutex };
assert( deviceFs.isPresent() == true );
auto discovererWorker = m_ml->getDiscovererWorker();
if ( discovererWorker != nullptr )
discovererWorker->reloadDevice( device->id() );
auto parser = m_ml->tryGetParser();
if ( parser != nullptr )
parser->refreshTaskList();
for ( const auto cb : m_callbacks )
cb->onDeviceReappearing( device->id() );
}
}
......
......@@ -38,10 +38,18 @@ namespace medialibrary
class Device;
class IFsHolderCb
{
public:
virtual ~IFsHolderCb() = default;
virtual void onDeviceReappearing( int64_t deviceId ) = 0;
};
class FsHolder : public fs::IFileSystemFactoryCb
{
public:
FsHolder( MediaLibrary* ml );
virtual ~FsHolder();
bool addFsFactory( std::shared_ptr<fs::IFileSystemFactory> fsFactory );
void registerDeviceLister( const std::string& scheme, DeviceListerPtr lister );
......@@ -77,6 +85,9 @@ public:
void startFsFactory( fs::IFileSystemFactory& fsFactory ) const;
void registerCallback( IFsHolderCb* cb );
void unregisterCallback( IFsHolderCb* cb );
private:
virtual void onDeviceMounted( const fs::IDevice& deviceFs,
const std::string& newMountpoint ) override;
......@@ -99,6 +110,8 @@ private:
std::unordered_map<std::string, DeviceListerPtr> m_deviceListers;
std::atomic_bool m_networkDiscoveryEnabled;
std::atomic_bool m_started;
std::vector<IFsHolderCb*> m_callbacks;
};
}
......@@ -142,6 +142,11 @@ void Parser::restore()
m_serviceWorkers[0]->parse( std::move( tasks ) );
}
void Parser::onDeviceReappearing( int64_t )
{
refreshTaskList();
}
void Parser::refreshTaskList()
{
/*
......
......@@ -26,6 +26,7 @@
#include <atomic>
#include <vector>
#include "medialibrary/parser/Parser.h"
#include "filesystem/FsHolder.h"
namespace medialibrary
{
......@@ -57,7 +58,7 @@ public:
virtual void refreshTaskList() = 0;
};
class Parser : public IParserCb
class Parser : public IParserCb, public IFsHolderCb
{
public:
using ServicePtr = std::shared_ptr<IParserService>;
......@@ -95,6 +96,7 @@ private:
virtual void onIdleChanged( bool idle ) override;
// Queues all unparsed files for parsing.
void restore();
virtual void onDeviceReappearing( int64_t deviceId ) override;
private:
std::vector<std::unique_ptr<Worker>> m_serviceWorkers;
......
Supports Markdown
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