jobs: group together API calls under the same job lock
Now that the API offers also _locked() functions, take advantage
of it and give also the caller control to take the lock and call
_locked functions.
This makes sense especially when we have for loops, because it
makes no sense to have:
for(job = job_next(); ...)
where each job_next() takes the lock internally.
Instead we want
JOB_LOCK_GUARD();
for(job = job_next_locked(); ...)
In addition, protect also direct field accesses, by either creating a
new critical section or widening the existing ones.
Note: at this stage, job_{lock/unlock} and job lock guard macros
are *nop*.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Message-Id: <20220926093214.506243-12-eesposit@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
1 parent
279ac06e55
commit
880eeec613
6 files changed
+63
-34
No files matched your search
+22
-13
@@ -111,8 +111,10 @@ static bool child_job_drained_poll(BdrvChild *c)
|
||||
/* An inactive or completed job doesn't have any pending requests. Jobs
|
||||
* with !job->busy are either already paused or have a pause point after
|
||||
* being reentered, so no job driver code will run before they pause. */
|
||||
if (!job->busy || job_is_completed(job)) {
|
||||
return false;
|
||||
WITH_JOB_LOCK_GUARD() {
|
||||
if (!job->busy || job_is_completed_locked(job)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, assume that it isn't fully stopped yet, but allow the job to
|
||||
@@ -475,13 +477,15 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
|
||||
job->ready_notifier.notify = block_job_event_ready;
|
||||
job->idle_notifier.notify = block_job_on_idle;
|
||||
|
||||
notifier_list_add(&job->job.on_finalize_cancelled,
|
||||
&job->finalize_cancelled_notifier);
|
||||
notifier_list_add(&job->job.on_finalize_completed,
|
||||
&job->finalize_completed_notifier);
|
||||
notifier_list_add(&job->job.on_pending, &job->pending_notifier);
|
||||
notifier_list_add(&job->job.on_ready, &job->ready_notifier);
|
||||
notifier_list_add(&job->job.on_idle, &job->idle_notifier);
|
||||
WITH_JOB_LOCK_GUARD() {
|
||||
notifier_list_add(&job->job.on_finalize_cancelled,
|
||||
&job->finalize_cancelled_notifier);
|
||||
notifier_list_add(&job->job.on_finalize_completed,
|
||||
&job->finalize_completed_notifier);
|
||||
notifier_list_add(&job->job.on_pending, &job->pending_notifier);
|
||||
notifier_list_add(&job->job.on_ready, &job->ready_notifier);
|
||||
notifier_list_add(&job->job.on_idle, &job->idle_notifier);
|
||||
}
|
||||
|
||||
error_setg(&job->blocker, "block device is in use by block job: %s",
|
||||
job_type_str(&job->job));
|
||||
@@ -558,10 +562,15 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
|
||||
action);
|
||||
}
|
||||
if (action == BLOCK_ERROR_ACTION_STOP) {
|
||||
if (!job->job.user_paused) {
|
||||
job_pause(&job->job);
|
||||
/* make the pause user visible, which will be resumed from QMP. */
|
||||
job->job.user_paused = true;
|
||||
WITH_JOB_LOCK_GUARD() {
|
||||
if (!job->job.user_paused) {
|
||||
job_pause_locked(&job->job);
|
||||
/*
|
||||
* make the pause user visible, which will be
|
||||
* resumed from QMP.
|
||||
*/
|
||||
job->job.user_paused = true;
|
||||
}
|
||||
}
|
||||
block_job_iostatus_set_err(job, error);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user