diff options
author | Kevin Wolf <kwolf@redhat.com> | 2018-04-18 16:32:20 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2018-05-23 14:30:50 +0200 |
commit | 5d43e86e11f488fda7956b13160e0c0105a84845 (patch) | |
tree | b5c4200538b55bb476e92b197a352ea4e3c09ce0 /job.c | |
parent | da01ff7f38f52791f93fc3ca59afcfbb220f15af (diff) |
job: Add job_sleep_ns()
There is nothing block layer specific about block_job_sleep_ns(), so
move the function to Job.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'job.c')
-rw-r--r-- | job.c | 32 |
1 files changed, 32 insertions, 0 deletions
@@ -152,6 +152,13 @@ Job *job_get(const char *id) return NULL; } +static void job_sleep_timer_cb(void *opaque) +{ + Job *job = opaque; + + job_enter(job); +} + void *job_create(const char *job_id, const JobDriver *driver, AioContext *ctx, Error **errp) { @@ -178,6 +185,9 @@ void *job_create(const char *job_id, const JobDriver *driver, AioContext *ctx, job->pause_count = 1; job_state_transition(job, JOB_STATUS_CREATED); + aio_timer_init(qemu_get_aio_context(), &job->sleep_timer, + QEMU_CLOCK_REALTIME, SCALE_NS, + job_sleep_timer_cb, job); QLIST_INSERT_HEAD(&jobs, job, job_list); @@ -193,6 +203,7 @@ void job_unref(Job *job) { if (--job->refcnt == 0) { assert(job->status == JOB_STATUS_NULL); + assert(!timer_pending(&job->sleep_timer)); if (job->driver->free) { job->driver->free(job); @@ -232,6 +243,11 @@ void job_enter_cond(Job *job, bool(*fn)(Job *job)) aio_co_wake(job->co); } +void job_enter(Job *job) +{ + job_enter_cond(job, NULL); +} + /* Yield, and schedule a timer to reenter the coroutine after @ns nanoseconds. * Reentering the job coroutine with block_job_enter() before the timer has * expired is allowed and cancels the timer. @@ -283,6 +299,22 @@ void coroutine_fn job_pause_point(Job *job) } } +void coroutine_fn job_sleep_ns(Job *job, int64_t ns) +{ + assert(job->busy); + + /* Check cancellation *before* setting busy = false, too! */ + if (job_is_cancelled(job)) { + return; + } + + if (!job_should_pause(job)) { + job_do_yield(job, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + ns); + } + + job_pause_point(job); +} + /** * All jobs must allow a pause point before entering their job proper. This * ensures that jobs can be paused prior to being started, then resumed later. |