reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit 377bd881b534522240ced02d6d2bb072b930788e
parent 8b0478d2699872ba3be4c2c6946376a3931ab748
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Wed, 20 Jan 2016 00:13:10 -0500

perform multiple uninstallations using the same transaction

Diffstat:
Msrc/manager.cpp | 5+++--
Msrc/reapack.cpp | 5++++-
Msrc/reapack.hpp | 2+-
Msrc/task.cpp | 25+++++++++++++++++--------
Msrc/task.hpp | 7++++++-
Msrc/transaction.cpp | 31+++++++++++++++++++++----------
Msrc/transaction.hpp | 9++++++---
7 files changed, 58 insertions(+), 26 deletions(-)

diff --git a/src/manager.cpp b/src/manager.cpp @@ -192,8 +192,9 @@ void Manager::apply() m_reapack->synchronize(remote); } - for(const Remote &remote : m_uninstall) { - m_reapack->uninstall(remote); + for(auto it = m_uninstall.begin(); it != m_uninstall.end(); it++) { + const Remote &remote = *it; + m_reapack->uninstall(remote, next(it) == m_uninstall.end()); list->remove(remote); } diff --git a/src/reapack.cpp b/src/reapack.cpp @@ -119,7 +119,7 @@ void ReaPack::synchronize(const Remote &remote) m_transaction->synchronize(remote); } -void ReaPack::uninstall(const Remote &remote) +void ReaPack::uninstall(const Remote &remote, const bool start) { if(remote.isProtected()) return; @@ -130,6 +130,9 @@ void ReaPack::uninstall(const Remote &remote) } m_transaction->uninstall(remote); + + if(start) + m_transaction->runTasks(); } void ReaPack::importRemote() diff --git a/src/reapack.hpp b/src/reapack.hpp @@ -47,7 +47,7 @@ public: void synchronizeAll(); void synchronize(const Remote &); - void uninstall(const Remote &); + void uninstall(const Remote &, const bool start = true); void importRemote(); void manageRemotes(); diff --git a/src/task.cpp b/src/task.cpp @@ -36,13 +36,9 @@ Task::Task(Transaction *transaction) { } -void Task::rollback() +void Task::start() { - m_isCancelled = true; - - // it's the transaction queue's job to abort the running downloads, not ours - - doRollback(); + doStart(); } void Task::commit() @@ -54,6 +50,15 @@ void Task::commit() m_onCommit(); } +void Task::rollback() +{ + m_isCancelled = true; + + // it's the transaction queue's job to abort the running downloads, not ours + + doRollback(); +} + bool Task::renameFile(const Path &from, const Path &to) const { const string &fullFrom = m_transaction->prefixPath(from).join(); @@ -101,9 +106,13 @@ bool Task::removeFileRecursive(const Path &file) const } InstallTask::InstallTask(Version *ver, const set<Path> &oldFiles, Transaction *t) - : Task(t), m_oldFiles(move(oldFiles)) + : Task(t), m_version(ver), m_oldFiles(move(oldFiles)) +{ +} + +void InstallTask::doStart() { - const auto &sources = ver->sources(); + const auto &sources = m_version->sources(); for(auto it = sources.begin(); it != sources.end();) { const Path &path = it->first; diff --git a/src/task.hpp b/src/task.hpp @@ -39,6 +39,7 @@ public: void onCommit(const Callback &callback) { m_onCommit.connect(callback); } bool isCancelled() const { return m_isCancelled; } + void start(); void commit(); void rollback(); @@ -49,6 +50,7 @@ protected: Transaction *transaction() const { return m_transaction; } + virtual void doStart() = 0; virtual bool doCommit() = 0; virtual void doRollback() = 0; @@ -66,6 +68,7 @@ public: const std::set<Path> &removedFiles() const { return m_oldFiles; } protected: + void doStart() override; bool doCommit() override; void doRollback() override; @@ -74,8 +77,9 @@ private: void saveSource(Download *, Source *); - std::vector<PathPair> m_newFiles; + Version *m_version; std::set<Path> m_oldFiles; + std::vector<PathPair> m_newFiles; }; class RemoveTask : public Task { @@ -85,6 +89,7 @@ public: const std::set<Path> &removedFiles() const { return m_removedFiles; } protected: + void doStart() override {} bool doCommit() override; void doRollback() override {} diff --git a/src/transaction.cpp b/src/transaction.cpp @@ -36,8 +36,8 @@ Transaction::Transaction(const Path &root) m_registry = new Registry(m_dbPath + "registry.db"); - m_queue.onDone([=](void *) { - if(m_packages.empty() || m_hasConflicts) + m_downloadQueue.onDone([=](void *) { + if(m_installQueue.empty() || m_hasConflicts) finish(); else install(); @@ -62,7 +62,7 @@ void Transaction::synchronize(const Remote &remote) Download *dl = new Download(remote.name(), remote.url()); dl->onFinish(bind(&Transaction::upgradeAll, this, dl)); - m_queue.push(dl); + m_downloadQueue.push(dl); } void Transaction::upgradeAll(Download *dl) @@ -91,7 +91,7 @@ void Transaction::upgradeAll(Download *dl) entry.status = Registry::Uninstalled; } - m_packages.push_back({ver, entry}); + m_installQueue.push({ver, entry}); } } catch(const reapack_error &e) { @@ -101,7 +101,10 @@ void Transaction::upgradeAll(Download *dl) void Transaction::install() { - for(const PackageEntry &entry : m_packages) { + while(!m_installQueue.empty()) { + const PackageEntry entry = m_installQueue.front(); + m_installQueue.pop(); + Version *ver = entry.first; const Registry::Entry regEntry = entry.second; const set<Path> &currentFiles = m_registry->getFiles(regEntry); @@ -130,8 +133,7 @@ void Transaction::install() addTask(task); } - // allow further synchronize() calls to be made (transaction hitchhiking) - m_packages.clear(); + runTasks(); } void Transaction::uninstall(const Remote &remote) @@ -169,10 +171,10 @@ void Transaction::cancel() for(Task *task : m_tasks) task->rollback(); - if(m_queue.idle()) + if(m_downloadQueue.idle()) finish(); else - m_queue.abort(); + m_downloadQueue.abort(); } bool Transaction::saveFile(Download *dl, const Path &path) @@ -251,7 +253,16 @@ void Transaction::registerFiles(const set<Path> &list) void Transaction::addTask(Task *task) { m_tasks.push_back(task); + m_taskQueue.push(task); +} + +void Transaction::runTasks() +{ + while(!m_taskQueue.empty()) { + m_taskQueue.front()->start(); + m_taskQueue.pop(); + } - if(m_queue.idle()) + if(m_downloadQueue.idle()) finish(); } diff --git a/src/transaction.hpp b/src/transaction.hpp @@ -54,11 +54,13 @@ public: void synchronize(const Remote &); void uninstall(const Remote &); + void runTasks(); void cancel(); bool isCancelled() const { return m_isCancelled; } - DownloadQueue *downloadQueue() { return &m_queue; } + DownloadQueue *downloadQueue() { return &m_downloadQueue; } size_t taskCount() const { return m_tasks.size(); } + const PackageEntryList &newPackages() const { return m_new; } const PackageEntryList &updates() const { return m_updates; } const std::set<Path> &removals() const { return m_removals; } @@ -84,14 +86,15 @@ private: bool m_isCancelled; std::vector<RemoteIndex *> m_remoteIndexes; - DownloadQueue m_queue; - PackageEntryList m_packages; + DownloadQueue m_downloadQueue; + std::queue<PackageEntry> m_installQueue; PackageEntryList m_new; PackageEntryList m_updates; std::set<Path> m_removals; ErrorList m_errors; std::vector<Task *> m_tasks; + std::queue<Task *> m_taskQueue; std::set<Path> m_files; bool m_hasConflicts;