Destroy the gpodloader, only load the itunes database once, ensure only one Organiser thread can write to the ipod at once, make Organiser threads wait for the device to be loaded before they start writing.

This commit is contained in:
David Sansome 2010-07-24 17:41:18 +00:00
parent 1d5cef0f0d
commit bc97872bc4
4 changed files with 42 additions and 23 deletions

View File

@ -30,7 +30,7 @@ GPodDevice::GPodDevice(
: ConnectedDevice(url, lister, unique_id, manager, database_id, first_time), : ConnectedDevice(url, lister, unique_id, manager, database_id, first_time),
loader_thread_(new QThread(this)), loader_thread_(new QThread(this)),
loader_(new GPodLoader(url.path(), manager->task_manager(), backend_)), loader_(new GPodLoader(url.path(), manager->task_manager(), backend_)),
active_copy_db_(NULL) db_(NULL)
{ {
InitBackendDirectory(url.path(), first_time); InitBackendDirectory(url.path(), first_time);
model_->Init(); model_->Init();
@ -39,35 +39,40 @@ GPodDevice::GPodDevice(
connect(loader_, SIGNAL(Error(QString)), SIGNAL(Error(QString))); connect(loader_, SIGNAL(Error(QString)), SIGNAL(Error(QString)));
connect(loader_, SIGNAL(TaskStarted(int)), SIGNAL(TaskStarted(int))); connect(loader_, SIGNAL(TaskStarted(int)), SIGNAL(TaskStarted(int)));
connect(loader_, SIGNAL(LoadFinished(Itdb_iTunesDB*)), SLOT(LoadFinished(Itdb_iTunesDB*)));
connect(loader_thread_, SIGNAL(started()), loader_, SLOT(LoadDatabase())); connect(loader_thread_, SIGNAL(started()), loader_, SLOT(LoadDatabase()));
loader_thread_->start(); loader_thread_->start();
// TODO: loader cleanup
} }
GPodDevice::~GPodDevice() { GPodDevice::~GPodDevice() {
} }
void GPodDevice::LoadFinished(Itdb_iTunesDB* db) {
QMutexLocker l(&db_mutex_);
db_ = db;
db_wait_cond_.wakeAll();
loader_->deleteLater();
loader_ = NULL;
}
void GPodDevice::StartCopy() { void GPodDevice::StartCopy() {
active_copy_mutex_.lock(); {
// Wait for the database to be loaded
// Load the iTunes database QMutexLocker l(&db_mutex_);
GError* error = NULL; if (!db_)
active_copy_db_ = itdb_parse(url_.path().toLocal8Bit(), &error); db_wait_cond_.wait(&db_mutex_);
// Check for errors
if (!active_copy_db_) {
qDebug() << "GPodDevice error:" << error->message;
emit Error(QString::fromUtf8(error->message));
g_error_free(error);
} }
// Ensure only one "organise files" can be active at any one time
copy_in_progress_.lock();
} }
bool GPodDevice::CopyToStorage( bool GPodDevice::CopyToStorage(
const QString& source, const QString&, const QString& source, const QString&,
const Song& metadata, bool, bool remove_original) const Song& metadata, bool, bool remove_original)
{ {
if (!active_copy_db_) Q_ASSERT(db_);
return false;
// Create the track // Create the track
Itdb_Track* track = itdb_track_new(); Itdb_Track* track = itdb_track_new();
@ -75,8 +80,8 @@ bool GPodDevice::CopyToStorage(
// Add it to the DB and the master playlist // Add it to the DB and the master playlist
// The DB takes ownership of the track // The DB takes ownership of the track
itdb_track_add(active_copy_db_, track, -1); itdb_track_add(db_, track, -1);
Itdb_Playlist* mpl = itdb_playlist_mpl(active_copy_db_); Itdb_Playlist* mpl = itdb_playlist_mpl(db_);
itdb_playlist_add_track(mpl, track, -1); itdb_playlist_add_track(mpl, track, -1);
// Copy the file // Copy the file
@ -97,13 +102,13 @@ bool GPodDevice::CopyToStorage(
void GPodDevice::FinishCopy() { void GPodDevice::FinishCopy() {
GError* error = NULL; GError* error = NULL;
itdb_write(active_copy_db_, &error); itdb_write(db_, &error);
if (error) { if (error) {
qDebug() << "GPodDevice error:" << error->message; qDebug() << "GPodDevice error:" << error->message;
emit Error(QString::fromUtf8(error->message)); emit Error(QString::fromUtf8(error->message));
g_error_free(error); g_error_free(error);
} }
active_copy_mutex_.unlock(); copy_in_progress_.unlock();
} }

View File

@ -21,6 +21,7 @@
#include "core/musicstorage.h" #include "core/musicstorage.h"
#include <QMutex> #include <QMutex>
#include <QWaitCondition>
class GPodLoader; class GPodLoader;
@ -43,12 +44,18 @@ public:
const Song &metadata, bool overwrite, bool remove_original); const Song &metadata, bool overwrite, bool remove_original);
void FinishCopy(); void FinishCopy();
private slots:
void LoadFinished(Itdb_iTunesDB* db);
private: private:
QThread* loader_thread_; QThread* loader_thread_;
GPodLoader* loader_; GPodLoader* loader_;
QMutex active_copy_mutex_; QWaitCondition db_wait_cond_;
Itdb_iTunesDB* active_copy_db_; QMutex db_mutex_;
Itdb_iTunesDB* db_;
QMutex copy_in_progress_;
}; };
#endif // GPODDEVICE_H #endif // GPODDEVICE_H

View File

@ -30,6 +30,7 @@ GPodLoader::GPodLoader(const QString& mount_point, TaskManager* task_manager,
task_manager_(task_manager), task_manager_(task_manager),
backend_(backend) backend_(backend)
{ {
original_thread_ = thread();
} }
void GPodLoader::LoadDatabase() { void GPodLoader::LoadDatabase() {
@ -67,7 +68,8 @@ void GPodLoader::LoadDatabase() {
// Add the songs we've just loaded // Add the songs we've just loaded
backend_->AddOrUpdateSongs(songs); backend_->AddOrUpdateSongs(songs);
// Cleanup moveToThread(original_thread_);
itdb_free(db);
task_manager_->SetTaskFinished(task_id); task_manager_->SetTaskFinished(task_id);
emit LoadFinished(db);
} }

View File

@ -21,6 +21,8 @@
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <gpod/itdb.h>
class LibraryBackend; class LibraryBackend;
class TaskManager; class TaskManager;
@ -37,8 +39,11 @@ public slots:
signals: signals:
void Error(const QString& message); void Error(const QString& message);
void TaskStarted(int task_id); void TaskStarted(int task_id);
void LoadFinished(Itdb_iTunesDB* db);
private: private:
QThread* original_thread_;
QString mount_point_; QString mount_point_;
TaskManager* task_manager_; TaskManager* task_manager_;
LibraryBackend* backend_; LibraryBackend* backend_;