}
bool job_is_cancelled(Job *job)
+{
+ /* force_cancel may be true only if cancelled is true, too */
+ assert(job->cancelled || !job->force_cancel);
+ return job->force_cancel;
+}
+
+bool job_cancel_requested(Job *job)
{
return job->cancelled;
}
notifier_list_init(&job->on_finalize_completed);
notifier_list_init(&job->on_pending);
notifier_list_init(&job->on_ready);
+ notifier_list_init(&job->on_idle);
job_state_transition(job, JOB_STATUS_CREATED);
aio_timer_init(qemu_get_aio_context(), &job->sleep_timer,
void job_unref(Job *job)
{
+ GLOBAL_STATE_CODE();
+
if (--job->refcnt == 0) {
assert(job->status == JOB_STATUS_NULL);
assert(!timer_pending(&job->sleep_timer));
void job_user_resume(Job *job, Error **errp)
{
assert(job);
+ GLOBAL_STATE_CODE();
if (!job->user_paused || job->pause_count <= 0) {
error_setg(errp, "Can't resume a job that was not paused");
return;
static void job_commit(Job *job)
{
assert(!job->ret);
+ GLOBAL_STATE_CODE();
if (job->driver->commit) {
job->driver->commit(job);
}
static void job_abort(Job *job)
{
assert(job->ret);
+ GLOBAL_STATE_CODE();
if (job->driver->abort) {
job->driver->abort(job);
}
static void job_clean(Job *job)
{
+ GLOBAL_STATE_CODE();
if (job->driver->clean) {
job->driver->clean(job);
}
static void job_cancel_async(Job *job, bool force)
{
+ GLOBAL_STATE_CODE();
if (job->driver->cancel) {
force = job->driver->cancel(job, force);
} else {
ctx = other_job->aio_context;
aio_context_acquire(ctx);
if (!job_is_completed(other_job)) {
- assert(job_is_cancelled(other_job));
+ assert(job_cancel_requested(other_job));
job_finish_sync(other_job, NULL, NULL);
}
job_finalize_single(other_job);
static int job_prepare(Job *job)
{
+ GLOBAL_STATE_CODE();
if (job->ret == 0 && job->driver->prepare) {
job->ret = job->driver->prepare(job);
job_update_rc(job);
Job *job = opaque;
assert(job && job->driver && job->driver->run);
+ assert(job->aio_context == qemu_get_current_aio_context());
job_pause_point(job);
job->ret = job->driver->run(job, &job->err);
job->deferred_to_main_loop = true;
* job_cancel_async() ignores soft-cancel requests for jobs
* that are already done (i.e. deferred to the main loop). We
* have to check again whether the job is really cancelled.
+ * (job_cancel_requested() and job_is_cancelled() are equivalent
+ * here, because job_cancel_async() will make soft-cancel
+ * requests no-ops when deferred_to_main_loop is true. We
+ * choose to call job_is_cancelled() to show that we invoke
+ * job_completed_txn_abort() only for force-cancelled jobs.)
*/
if (job_is_cancelled(job)) {
job_completed_txn_abort(job);
{
/* Should not be reachable via external interface for internal jobs */
assert(job->id);
+ GLOBAL_STATE_CODE();
if (job_apply_verb(job, JOB_VERB_COMPLETE, errp)) {
return;
}
- if (job_is_cancelled(job) || !job->driver->complete) {
+ if (job_cancel_requested(job) || !job->driver->complete) {
error_setg(errp, "The active block job '%s' cannot be completed",
job->id);
return;