From 3b8ebe6d4235f5ba12bc9c9854a6dd28cbff06b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Sat, 21 Feb 2015 12:11:42 +0100 Subject: Async: allow appending Jobs to already running or finished Jobs When user gets a Job (from a method call for instance), which is already running or might have even finished already, they can still append a new Job to the chain and re-execute it. The Job will internally chain up to the last finished Job, use it's result and continue from the next Job in the chain. If a Job in the chain is still running, it will wait for it to finish and pass the result to the next Job in the chain. --- common/resourceaccess.cpp | 57 +++++++++++++---------------------------------- 1 file changed, 15 insertions(+), 42 deletions(-) (limited to 'common') diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp index c806478..ffe716b 100644 --- a/common/resourceaccess.cpp +++ b/common/resourceaccess.cpp @@ -154,51 +154,24 @@ Async::Job ResourceAccess::sendCommand(int commandId) }); } -/* - * TODO JOBAPI: This is a workaround to be able to return a job below to - * may or may not already be finished when the job is started. The job API should provide a mechanism - * for this. Essentially we need a way to set a job finished externally (we use the finisher as handle for that). - * If the job is then started the continuation should immediately be executed if the job finished already, and otherwise - * just wait until the work is done, and then execute the continuation as usual. - */ -struct JobFinisher { - bool finished; - std::function callback; - - JobFinisher() : finished(false) {} - - void setFinished(int error, const QString &errorMessage) { - finished = true; - if (callback) { - callback(error, errorMessage); - } - } -}; - Async::Job ResourceAccess::sendCommand(int commandId, flatbuffers::FlatBufferBuilder &fbb) { - auto finisher = QSharedPointer::create(); - auto callback = [finisher] (int error, const QString &errorMessage) { - finisher->setFinished(error, errorMessage); - }; - if (isReady()) { - d->messageId++; - log(QString("Sending command %1 with messageId %2").arg(commandId).arg(d->messageId)); - registerCallback(d->messageId, callback); - Commands::write(d->socket, d->messageId, commandId, fbb); - } else { - d->commandQueue << new QueuedCommand(commandId, fbb, callback); - } - return Async::start([this, finisher](Async::Future &f) { - if (finisher->finished) { - f.setFinished(); - } else { - finisher->callback = [&f](int error, const QString &errorMessage) { - if (error) { - f.setError(error, errorMessage); - } + return Async::start([commandId, &fbb, this](Async::Future &f) { + auto callback = [&f](int error, const QString &errorMessage) { + if (error) { + f.setError(error, errorMessage); + } else { f.setFinished(); - }; + } + }; + + if (isReady()) { + d->messageId++; + log(QString("Sending command %1 with messageId %2").arg(commandId).arg(d->messageId)); + registerCallback(d->messageId, callback); + Commands::write(d->socket, d->messageId, commandId, fbb); + } else { + d->commandQueue << new QueuedCommand(commandId, fbb, callback); } }); } -- cgit v1.2.3