commit 5e57f9adf0e5ce82f32dd8a93b19c716d6bbfe92
parent e1c78d21ea332398bf8ca2542863408ecaf6b274
Author: cfillion <cfillion@users.noreply.github.com>
Date: Tue, 23 Aug 2016 22:28:25 -0400
Merge branch 'task-redesign'
Diffstat:
9 files changed, 234 insertions(+), 297 deletions(-)
diff --git a/src/browser.cpp b/src/browser.cpp
@@ -1012,19 +1012,14 @@ bool Browser::apply()
const Version *target = *entry->target;
if(target)
- tx->install(target);
+ tx->install(target, entry->pin.value_or(false));
else
tx->uninstall(entry->regEntry);
entry->target = boost::none;
}
-
- if(entry->pin) {
- if(entry->regEntry)
- tx->setPinned(entry->regEntry, *entry->pin);
- else
- tx->setPinned(entry->package, *entry->pin);
-
+ else if(entry->pin) {
+ tx->setPinned(entry->regEntry, *entry->pin);
entry->pin = boost::none;
}
}
diff --git a/src/reapack.cpp b/src/reapack.cpp
@@ -432,15 +432,13 @@ Transaction *ReaPack::setupTransaction()
Dialog::Destroy(m_progress);
m_progress = nullptr;
- const Receipt &receipt = m_tx->receipt();
-
- if(m_tx->isCancelled() || receipt.empty())
+ if(m_tx->isCancelled() || m_tx->receipt()->empty())
return;
LockDialog managerLock(m_manager);
LockDialog browserLock(m_browser);
- Dialog::Show<Report>(m_instance, m_mainWindow, receipt);
+ Dialog::Show<Report>(m_instance, m_mainWindow, *m_tx->receipt());
});
m_tx->setCleanupHandler([=] {
diff --git a/src/receipt.cpp b/src/receipt.cpp
@@ -17,7 +17,9 @@
#include "receipt.hpp"
-#include "transaction.hpp"
+#include "index.hpp"
+
+using namespace std;
Receipt::Receipt()
: m_enabled(false), m_needRestart(false)
@@ -26,11 +28,11 @@ Receipt::Receipt()
bool Receipt::empty() const
{
- return
- m_installs.empty() &&
- m_updates.empty() &&
- m_removals.empty() &&
- m_errors.empty();
+ return
+ m_installs.empty() &&
+ m_updates.empty() &&
+ m_removals.empty() &&
+ m_errors.empty();
}
void Receipt::addTicket(const InstallTicket &ticket)
@@ -43,9 +45,12 @@ void Receipt::addTicket(const InstallTicket &ticket)
m_installs.push_back(ticket);
break;
}
+
+ m_indexes.insert(ticket.version->package()->category()
+ ->index()->shared_from_this());
}
-void Receipt::addRemovals(const std::set<Path> &pathList)
+void Receipt::addRemovals(const set<Path> &pathList)
{
m_removals.insert(pathList.begin(), pathList.end());
}
diff --git a/src/receipt.hpp b/src/receipt.hpp
@@ -20,18 +20,22 @@
#include <set>
#include <string>
+#include <unordered_set>
#include <vector>
#include "registry.hpp"
+class Index;
class Path;
+typedef std::shared_ptr<const Index> IndexPtr;
+
struct InstallTicket {
enum Type { Install, Upgrade };
Type type;
const Version *version;
- Registry::Entry regEntry;
+ Registry::Entry previous;
};
class Receipt {
@@ -68,6 +72,8 @@ private:
std::vector<InstallTicket> m_updates;
std::set<Path> m_removals;
std::vector<Error> m_errors;
+
+ std::unordered_set<IndexPtr> m_indexes; // keep them alive!
};
#endif
diff --git a/src/report.cpp b/src/report.cpp
@@ -111,7 +111,6 @@ void Report::printUpdates()
for(const InstallTicket &ticket : m_receipt.updates()) {
const Package *pkg = ticket.version->package();
- const Registry::Entry ®Entry = ticket.regEntry;
const VersionSet &versions = pkg->versions();
if(m_stream.tellp() != start)
@@ -120,7 +119,7 @@ void Report::printUpdates()
m_stream << pkg->fullName() << ":\r\n";
for(const Version *ver : versions | boost::adaptors::reversed) {
- if(*ver <= regEntry.version)
+ if(*ver <= ticket.previous.version)
break;
m_stream << *ver;
diff --git a/src/task.cpp b/src/task.cpp
@@ -18,69 +18,70 @@
#include "task.hpp"
#include "config.hpp"
+#include "errors.hpp"
#include "filesystem.hpp"
-#include "source.hpp"
+#include "index.hpp"
#include "transaction.hpp"
-#include "version.hpp"
using namespace std;
-Task::Task(Transaction *transaction)
- : m_transaction(transaction), m_isCancelled(false)
+Task::Task(Transaction *tx) : m_tx(tx)
{
}
-void Task::start()
+InstallTask::InstallTask(const Version *ver, const bool pin,
+ const Registry::Entry &re, Transaction *tx)
+ : Task(tx), m_version(ver), m_pin(pin), m_oldEntry(move(re)),
+ m_index(ver->package()->category()->index()->shared_from_this())
{
- doStart();
}
-void Task::commit()
+bool InstallTask::start()
{
- if(m_isCancelled)
- return;
-
- if(doCommit())
- m_onCommit();
-}
-
-void Task::rollback()
-{
- m_isCancelled = true;
+ // get current files before overwriting the entry
+ m_oldFiles = tx()->registry()->getFiles(m_oldEntry);
- // it's the transaction queue's job to abort the running downloads, not ours
+ // prevent file conflicts (don't worry, the registry push is reverted)
+ try {
+ vector<Path> conflicts;
+ tx()->registry()->push(m_version, &conflicts);
- doRollback();
-}
+ if(!conflicts.empty()) {
+ for(const Path &path : conflicts) {
+ tx()->receipt()->addError({"Conflict: " + path.join() +
+ " is already owned by another package", m_version->fullName()});
+ }
-InstallTask::InstallTask(const Version *ver,
- const vector<Registry::File> &oldFiles, Transaction *t)
- : Task(t), m_version(ver), m_oldFiles(move(oldFiles))
-{
-}
+ return false;
+ }
+ }
+ catch(const reapack_error &e) {
+ tx()->receipt()->addError({e.what(), m_version->fullName()});
+ return false;
+ }
-void InstallTask::doStart()
-{
const auto &sources = m_version->sources();
for(auto it = sources.begin(); it != sources.end();) {
const Path &path = it->first;
const Source *src = it->second;
- const NetworkOpts &opts = transaction()->config()->network;
+ const NetworkOpts &opts = tx()->config()->network;
Download *dl = new Download(src->fullName(), src->url(), opts);
dl->onFinish(bind(&InstallTask::saveSource, this, dl, src));
- transaction()->downloadQueue()->push(dl);
+ tx()->downloadQueue()->push(dl);
// skip duplicate files
do { it++; } while(it != sources.end() && path == it->first);
}
+
+ return true;
}
void InstallTask::saveSource(Download *dl, const Source *src)
{
- if(isCancelled())
+ if(dl->state() == Download::Aborted)
return;
const Path &targetPath = src->targetPath();
@@ -96,57 +97,101 @@ void InstallTask::saveSource(Download *dl, const Source *src)
if(old != m_oldFiles.end())
m_oldFiles.erase(old);
- if(!transaction()->saveFile(dl, tmpPath)) {
+ if(!tx()->saveFile(dl, tmpPath)) {
rollback();
return;
}
}
-bool InstallTask::doCommit()
+void InstallTask::commit()
{
- for(const Registry::File &file : m_oldFiles)
- FS::remove(file.path);
-
for(const PathGroup &paths : m_newFiles) {
#ifdef _WIN32
+ // TODO: rename to .old
FS::remove(paths.target);
#endif
if(!FS::rename(paths.temp, paths.target)) {
- transaction()->addError("Cannot rename to target: " + FS::lastError(),
- paths.target.join());
+ tx()->receipt()->addError({"Cannot rename to target: " + FS::lastError(),
+ paths.target.join()});
// it's a bit late to rollback here as some files might already have been
// overwritten. at least we can delete the temporary files
rollback();
- return false;
+ return;
}
}
- return true;
+ for(const Registry::File &file : m_oldFiles) {
+ if(FS::remove(file.path))
+ tx()->receipt()->addRemoval(file.path);
+
+ if(file.main)
+ tx()->registerFile({false, m_oldEntry, file});
+ }
+
+ InstallTicket::Type type;
+
+ if(m_oldEntry && m_oldEntry.version < *m_version)
+ type = InstallTicket::Upgrade;
+ else
+ type = InstallTicket::Install;
+
+ tx()->receipt()->addTicket({type, m_version, m_oldEntry});
+
+ const Registry::Entry newEntry = tx()->registry()->push(m_version);
+
+ if(newEntry.type == Package::ExtensionType)
+ tx()->receipt()->setRestartNeeded(true);
+
+ if(m_pin)
+ tx()->registry()->setPinned(newEntry, true);
+
+ tx()->registerAll(true, newEntry);
}
-void InstallTask::doRollback()
+void InstallTask::rollback()
{
for(const PathGroup &paths : m_newFiles)
FS::removeRecursive(paths.temp);
+}
- m_newFiles.clear();
+UninstallTask::UninstallTask(const Registry::Entry &re, Transaction *tx)
+ : Task(tx), m_entry(move(re))
+{
}
-RemoveTask::RemoveTask(const vector<Path> &files, Transaction *t)
- : Task(t), m_files(move(files))
+bool UninstallTask::start()
{
+ tx()->registry()->getFiles(m_entry).swap(m_files);
+
+ return true;
}
-bool RemoveTask::doCommit()
+void UninstallTask::commit()
{
- for(const Path &path : m_files) {
- if(FS::removeRecursive(path))
- m_removedFiles.insert(path);
+ for(const auto &file : m_files) {
+ if(!FS::exists(file.path))
+ continue;
+
+ if(FS::removeRecursive(file.path))
+ tx()->receipt()->addRemoval(file.path);
else
- transaction()->addError(FS::lastError(), path.join());
+ tx()->receipt()->addError({FS::lastError(), file.path.join()});
+
+ if(file.main)
+ tx()->registerFile({false, m_entry, file});
}
- return true;
+ tx()->registry()->forget(m_entry);
+}
+
+PinTask::PinTask(const Registry::Entry &re, const bool pin, Transaction *tx)
+ : Task(tx), m_entry(move(re)), m_pin(pin)
+{
+}
+
+void PinTask::commit()
+{
+ tx()->registry()->setPinned(m_entry, m_pin);
}
diff --git a/src/task.hpp b/src/task.hpp
@@ -21,55 +21,40 @@
#include "path.hpp"
#include "registry.hpp"
-#include <boost/signals2.hpp>
#include <set>
#include <vector>
class Download;
+class Index;
class Source;
class Transaction;
class Version;
+typedef std::shared_ptr<const Index> IndexPtr;
+
class Task {
public:
- typedef boost::signals2::signal<void ()> Signal;
- typedef Signal::slot_type Callback;
-
Task(Transaction *parent);
virtual ~Task() {}
- void onCommit(const Callback &callback) { m_onCommit.connect(callback); }
- bool isCancelled() const { return m_isCancelled; }
-
- void start();
- void commit();
- void rollback();
+ virtual bool start() { return true; }
+ virtual void commit() = 0;
+ virtual void rollback() {}
protected:
- Transaction *transaction() const { return m_transaction; }
-
- virtual void doStart() = 0;
- virtual bool doCommit() = 0;
- virtual void doRollback() = 0;
+ Transaction *tx() const { return m_tx; }
private:
- Transaction *m_transaction;
- bool m_isCancelled;
-
- Signal m_onCommit;
+ Transaction *m_tx;
};
class InstallTask : public Task {
public:
- InstallTask(const Version *ver, const std::vector<Registry::File> &oldFiles,
- Transaction *);
+ InstallTask(const Version *ver, bool pin, const Registry::Entry &, Transaction *);
- const std::vector<Registry::File> &removedFiles() const { return m_oldFiles; }
-
-protected:
- void doStart() override;
- bool doCommit() override;
- void doRollback() override;
+ bool start() override;
+ void commit() override;
+ void rollback() override;
private:
struct PathGroup { Path target; Path temp; };
@@ -77,34 +62,37 @@ private:
void saveSource(Download *, const Source *);
const Version *m_version;
+ bool m_pin;
+ Registry::Entry m_oldEntry;
+ IndexPtr m_index; // keep in memory
std::vector<Registry::File> m_oldFiles;
std::vector<PathGroup> m_newFiles;
};
-class RemoveTask : public Task {
+class UninstallTask : public Task {
public:
- RemoveTask(const std::vector<Path> &files, Transaction *);
-
- const std::set<Path> &removedFiles() const { return m_removedFiles; }
+ UninstallTask(const Registry::Entry &, Transaction *);
protected:
- void doStart() override {}
- bool doCommit() override;
- void doRollback() override {}
+ bool start() override;
+ void commit() override;
private:
- std::vector<Path> m_files;
+ Registry::Entry m_entry;
+ std::vector<Registry::File> m_files;
std::set<Path> m_removedFiles;
};
-class DummyTask : public Task {
+class PinTask : public Task {
public:
- DummyTask(Transaction *t) : Task(t) {}
+ PinTask(const Registry::Entry &, bool pin, Transaction *);
protected:
- void doStart() override {}
- bool doCommit() override { return true; }
- void doRollback() override {}
+ void commit() override;
+
+private:
+ Registry::Entry m_entry;
+ bool m_pin;
};
#endif
diff --git a/src/transaction.cpp b/src/transaction.cpp
@@ -40,25 +40,11 @@ Transaction::Transaction(Config *config)
m_downloadQueue.onAbort([=] {
m_isCancelled = true;
-
- // clear the registration queue
queue<HostTicket>().swap(m_regQueue);
-
- for(const TaskPtr &task : m_tasks)
- task->rollback();
-
- // some downloads may run for a few ms more
- if(m_downloadQueue.idle())
- finish();
});
// run tasks after fetching indexes
- m_downloadQueue.onDone([=] {
- if(m_tasks.empty())
- finish();
- else
- runTasks();
- });
+ m_downloadQueue.onDone(bind(&Transaction::runTasks, this));
}
void Transaction::synchronize(const Remote &remote,
@@ -82,7 +68,7 @@ void Transaction::synchronize(const Remote &remote,
}
catch(const reapack_error &e) {
// index file is invalid (load error)
- addError(e.what(), remote.name());
+ m_receipt.addError({e.what(), remote.name()});
return;
}
@@ -112,7 +98,7 @@ void Transaction::synchronize(const Package *pkg, const InstallOpts &opts)
else if(regEntry.pinned || *latest < regEntry.version)
return;
- install(latest, regEntry);
+ m_currentQueue.push(make_shared<InstallTask>(latest, false, regEntry, this));
}
void Transaction::fetchIndex(const Remote &remote, const function<void()> &cb)
@@ -132,71 +118,10 @@ void Transaction::fetchIndex(const Remote &remote, const function<void()> &cb)
});
}
-void Transaction::install(const Version *ver)
+void Transaction::install(const Version *ver, const bool pin)
{
- install(ver, m_registry.getEntry(ver->package()));
-}
-
-void Transaction::install(const Version *ver,
- const Registry::Entry ®Entry)
-{
- InstallTicket::Type type;
-
- if(regEntry && regEntry.version < *ver)
- type = InstallTicket::Upgrade;
- else
- type = InstallTicket::Install;
-
- // get current files before overwriting the entry
- const auto ¤tFiles = m_registry.getFiles(regEntry);
-
- // prevent file conflicts (don't worry, the registry push is reverted in runTasks)
- try {
- vector<Path> conflicts;
- m_registry.push(ver, &conflicts);
-
- if(!conflicts.empty()) {
- for(const Path &path : conflicts) {
- addError("Conflict: " + path.join() +
- " is already owned by another package",
- ver->fullName());
- }
-
- return;
- }
- }
- catch(const reapack_error &e) {
- // handle database error from Registry::push
- addError(e.what(), ver->fullName());
- return;
- }
-
- // all green! (pronounce with a japanese accent)
- IndexPtr ri = ver->package()->category()->index()->shared_from_this();
- if(!m_indexes.count(ri))
- m_indexes.insert(ri);
-
- auto task = make_shared<InstallTask>(ver, currentFiles, this);
-
- task->onCommit([=] {
- m_receipt.addTicket({type, ver, regEntry});
-
- for(const Registry::File &file : task->removedFiles()) {
- m_receipt.addRemoval(file.path);
-
- if(file.main)
- m_regQueue.push({false, regEntry, file});
- }
-
- const Registry::Entry newEntry = m_registry.push(ver);
-
- if(newEntry.type == Package::ExtensionType)
- m_receipt.setRestartNeeded(true);
-
- registerInHost(true, newEntry);
- });
-
- addTask(task);
+ const auto &oldEntry = m_registry.getEntry(ver->package());
+ m_currentQueue.push(make_shared<InstallTask>(ver, pin, oldEntry, this));
}
void Transaction::registerAll(const Remote &remote)
@@ -204,34 +129,15 @@ void Transaction::registerAll(const Remote &remote)
const vector<Registry::Entry> &entries = m_registry.getEntries(remote.name());
for(const auto &entry : entries)
- registerInHost(remote.isEnabled(), entry);
+ registerAll(remote.isEnabled(), entry);
if(!remote.isEnabled())
inhibit(remote);
}
-void Transaction::setPinned(const Package *pkg, const bool pinned)
-{
- // pkg may or may not be installed yet at this point,
- // waiting for the install task to be commited before querying the registry
-
- auto task = make_shared<DummyTask>(this);
-
- task->onCommit([=] {
- const Registry::Entry &entry = m_registry.getEntry(pkg);
- if(entry)
- m_registry.setPinned(entry, pinned);
- });
-
- addTask(task);
-}
-
void Transaction::setPinned(const Registry::Entry &entry, const bool pinned)
{
- auto task = make_shared<DummyTask>(this);
- task->onCommit(bind(&Registry::setPinned, m_registry, entry, pinned));
-
- addTask(task);
+ m_currentQueue.push(make_shared<PinTask>(entry, pinned, this));
}
void Transaction::uninstall(const Remote &remote)
@@ -242,121 +148,119 @@ void Transaction::uninstall(const Remote &remote)
if(FS::exists(indexPath)) {
if(!FS::remove(indexPath))
- addError(FS::lastError(), indexPath.join());
+ m_receipt.addError({FS::lastError(), indexPath.join()});
}
- const vector<Registry::Entry> &entries = m_registry.getEntries(remote.name());
-
- if(entries.empty())
- return;
-
- for(const auto &entry : entries)
+ for(const auto &entry : m_registry.getEntries(remote.name()))
uninstall(entry);
}
void Transaction::uninstall(const Registry::Entry &entry)
{
- vector<Path> files;
-
- for(const Registry::File &file : m_registry.getFiles(entry)) {
- if(FS::exists(file.path))
- files.push_back(file.path);
- if(file.main)
- m_regQueue.push({false, entry, file});
- }
-
- auto task = make_shared<RemoveTask>(files, this);
-
- task->onCommit([=] {
- m_registry.forget(entry);
- m_receipt.addRemovals(task->removedFiles());
- });
-
- addTask(task);
+ m_currentQueue.push(make_shared<UninstallTask>(entry, this));
}
bool Transaction::saveFile(Download *dl, const Path &path)
{
if(dl->state() != Download::Success) {
- addError(dl->contents(), dl->url());
+ m_receipt.addError({dl->contents(), dl->url()});
return false;
}
if(!FS::write(path, dl->contents())) {
- addError(FS::lastError(), path.join());
+ m_receipt.addError({FS::lastError(), path.join()});
return false;
}
return true;
}
-void Transaction::finish()
+bool Transaction::runTasks()
{
- // called when the download queue is done, or if there is nothing to do
+ if(!m_currentQueue.empty()) {
+ m_taskQueues.push(m_currentQueue);
+ queue<TaskPtr>().swap(m_currentQueue);
+ }
- if(!m_isCancelled) {
- for(const TaskPtr &task : m_tasks)
- task->commit();
+ // do nothing if there are running tasks
+ if(!commitTasks())
+ return false;
- m_registry.commit();
+ while(!m_taskQueues.empty()) {
+ m_registry.savepoint();
- registerQueued();
- }
+ TaskQueue &queue = m_taskQueues.front();
- assert(m_downloadQueue.idle());
- assert(m_taskQueue.empty());
- assert(m_regQueue.empty());
+ while(!queue.empty()) {
+ const TaskPtr &task = queue.front();
- m_onFinish();
- m_cleanupHandler();
-}
+ if(task->start())
+ m_runningTasks.push(task);
-void Transaction::addError(const string &message, const string &title)
-{
- m_receipt.addError({message, title});
-}
+ queue.pop();
+ }
-bool Transaction::allFilesExists(const set<Path> &list) const
-{
- for(const Path &path : list) {
- if(!FS::exists(path))
+ m_registry.restore();
+ m_taskQueues.pop();
+
+ if(!commitTasks())
return false;
}
+ finish();
return true;
}
-void Transaction::addTask(const TaskPtr &task)
+bool Transaction::commitTasks()
{
- m_tasks.push_back(task);
- m_taskQueue.push(task.get());
+ // wait until all running tasks are ready
+ if(!m_downloadQueue.idle())
+ return false;
+
+ // finish current tasks
+ while(!m_runningTasks.empty()) {
+ if(m_isCancelled)
+ m_runningTasks.front()->rollback();
+ else
+ m_runningTasks.front()->commit();
+
+ m_runningTasks.pop();
+ }
+
+ return true;
}
-bool Transaction::runTasks()
+void Transaction::finish()
{
- m_registry.restore();
-
- while(!m_taskQueue.empty()) {
- m_taskQueue.front()->start();
- m_taskQueue.pop();
+ if(!m_isCancelled) {
+ m_registry.commit();
+ registerQueued();
}
- // get ready for new tasks
- m_registry.savepoint();
+ assert(m_downloadQueue.idle());
+ assert(m_currentQueue.empty());
+ assert(m_taskQueues.empty());
+ assert(m_regQueue.empty());
- // return false if transaction is still in progress
- if(!m_downloadQueue.idle())
- return false;
+ m_onFinish();
+ m_cleanupHandler();
+}
+
+bool Transaction::allFilesExists(const set<Path> &list) const
+{
+ for(const Path &path : list) {
+ if(!FS::exists(path))
+ return false;
+ }
- finish();
return true;
}
-void Transaction::registerInHost(const bool add, const Registry::Entry &entry)
+void Transaction::registerAll(const bool add, const Registry::Entry &entry)
{
// don't actually do anything until commit() – which will calls registerQueued
for(const Registry::File &file : m_registry.getMainFiles(entry))
- m_regQueue.push({add, entry, file});
+ registerFile({add, entry, file});
}
void Transaction::registerQueued()
@@ -401,8 +305,10 @@ void Transaction::registerScript(const HostTicket ®)
const string &fullPath = Path::prefixRoot(reg.file.path).join();
const bool isLast = m_regQueue.size() == 1;
- if(!AddRemoveReaScript(reg.add, section, fullPath.c_str(), isLast) && reg.add)
- addError("This script could not be registered in REAPER.", reg.file.path.join());
+ if(!AddRemoveReaScript(reg.add, section, fullPath.c_str(), isLast) && reg.add) {
+ m_receipt.addError({"This script could not be registered in REAPER.",
+ reg.file.path.join()});
+ }
}
void Transaction::inhibit(const Remote &remote)
diff --git a/src/transaction.hpp b/src/transaction.hpp
@@ -30,14 +30,13 @@
#include <unordered_set>
class Config;
-class Index;
class Path;
class Remote;
class Task;
struct InstallOpts;
-typedef std::shared_ptr<const Index> IndexPtr;
typedef std::shared_ptr<Task> TaskPtr;
+typedef std::queue<TaskPtr> TaskQueue;
struct HostTicket { bool add; Registry::Entry entry; Registry::File file; };
@@ -53,8 +52,7 @@ public:
void synchronize(const Remote &,
boost::optional<bool> forceAutoInstall = boost::none);
- void install(const Version *);
- void setPinned(const Package *, bool pinned);
+ void install(const Version *, bool pin = false);
void setPinned(const Registry::Entry &, bool pinned);
void uninstall(const Remote &);
void uninstall(const Registry::Entry &);
@@ -62,28 +60,25 @@ public:
bool runTasks();
bool isCancelled() const { return m_isCancelled; }
- const Receipt &receipt() const { return m_receipt; }
- DownloadQueue *downloadQueue() { return &m_downloadQueue; }
+ Receipt *receipt() { return &m_receipt; }
+ Registry *registry() { return &m_registry; }
const Config *config() { return m_config; }
+ DownloadQueue *downloadQueue() { return &m_downloadQueue; }
+ void registerAll(bool add, const Registry::Entry &);
+ void registerFile(const HostTicket &t) { m_regQueue.push(t); }
bool saveFile(Download *, const Path &);
- void addError(const std::string &msg, const std::string &title);
private:
void fetchIndex(const Remote &, const std::function<void ()> &);
void synchronize(const Package *, const InstallOpts &);
- void install(const Version *, const Registry::Entry &);
- void addTask(const TaskPtr &);
-
bool allFilesExists(const std::set<Path> &) const;
-
- void registerInHost(bool add, const Registry::Entry &);
void registerQueued();
void registerScript(const HostTicket &);
-
- void finish();
void inhibit(const Remote &);
+ bool commitTasks();
+ void finish();
bool m_isCancelled;
const Config *m_config;
@@ -92,11 +87,11 @@ private:
std::unordered_set<std::string> m_syncedRemotes;
std::unordered_set<std::string> m_inhibited;
- std::unordered_set<IndexPtr> m_indexes;
- std::vector<TaskPtr> m_tasks;
DownloadQueue m_downloadQueue;
- std::queue<Task *> m_taskQueue;
+ TaskQueue m_currentQueue;
+ TaskQueue m_runningTasks;
+ std::queue<TaskQueue> m_taskQueues;
std::queue<HostTicket> m_regQueue;
VoidSignal m_onFinish;