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:
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> ¤tFiles = 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;