diff options
Diffstat (limited to 'src/libstrongswan')
-rw-r--r-- | src/libstrongswan/processing/jobs/job.h | 68 | ||||
-rw-r--r-- | src/libstrongswan/processing/processor.c | 54 |
2 files changed, 85 insertions, 37 deletions
diff --git a/src/libstrongswan/processing/jobs/job.h b/src/libstrongswan/processing/jobs/job.h index 43bb5430e..64454718a 100644 --- a/src/libstrongswan/processing/jobs/job.h +++ b/src/libstrongswan/processing/jobs/job.h @@ -25,8 +25,9 @@ typedef struct job_t job_t; typedef enum job_priority_t job_priority_t; -typedef enum job_requeue_t job_requeue_t; typedef enum job_status_t job_status_t; +typedef enum job_requeue_type_t job_requeue_type_t; +typedef struct job_requeue_t job_requeue_t; #include <library.h> @@ -51,23 +52,6 @@ enum job_priority_t { extern enum_name_t *job_priority_names; /** - * Job requeueing policy. - * - * The job requeueing policy defines how a job is handled after it has been - * executed. - */ -enum job_requeue_t { - /** Do not requeue job, destroy it */ - JOB_REQUEUE_NONE = 0, - /** Requeue the job fairly, i.e. it is inserted at the end of the queue */ - JOB_REQUEUE_FAIR, - /** Reexecute the job directly, without the need of requeueing it */ - JOB_REQUEUE_DIRECT, - /** For jobs that rescheduled themselves via scheduler_t */ - JOB_REQUEUE_SCHEDULED, -}; - -/** * Job status */ enum job_status_t { @@ -82,6 +66,54 @@ enum job_status_t { }; /** + * How a job is handled after is has been executed. + */ +enum job_requeue_type_t { + /** Do not requeue job, destroy it */ + JOB_REQUEUE_TYPE_NONE = 0, + /** Requeue the job fairly, i.e. it is inserted at the end of the queue */ + JOB_REQUEUE_TYPE_FAIR, + /** Reexecute the job directly, without the need of requeueing it */ + JOB_REQUEUE_TYPE_DIRECT, + /** Rescheduled the job via scheduler_t */ + JOB_REQUEUE_TYPE_SCHEDULE, +}; + +/** + * Job requeueing policy. + * + * The job requeueing policy defines how a job is handled after it has been + * executed. + */ +struct job_requeue_t { + /** How to handle the job after executing it */ + job_requeue_type_t type; + /** How to reschedule the job, if so */ + enum { + JOB_SCHEDULE, + JOB_SCHEDULE_MS, + JOB_SCHEDULE_TV, + } schedule; + /** Time to reschedule the job */ + union { + u_int32_t rel; + timeval_t abs; + } time; +}; + +/** + * Helper macros to easily define requeueing policies. + */ +#define __JOB_REQUEUE(t) (job_requeue_t){ .type = t } +#define JOB_REQUEUE_NONE __JOB_REQUEUE(JOB_REQUEUE_TYPE_NONE) +#define JOB_REQUEUE_FAIR __JOB_REQUEUE(JOB_REQUEUE_TYPE_FAIR) +#define JOB_REQUEUE_DIRECT __JOB_REQUEUE(JOB_REQUEUE_TYPE_DIRECT) +#define __JOB_RESCHEDULE(t, ...) (job_requeue_t){ .type = JOB_REQUEUE_TYPE_SCHEDULE, .schedule = t, { __VA_ARGS__ } } +#define JOB_RESCHEDULE(s) __JOB_RESCHEDULE(JOB_SCHEDULE, .rel = s) +#define JOB_RESCHEDULE_MS(ms) __JOB_RESCHEDULE(JOB_SCHEDULE_MS, .rel = ms) +#define JOB_RESCHEDULE_TV(tv) __JOB_RESCHEDULE(JOB_SCHEDULE_TV, .abs = tv) + +/** * Job interface as it is stored in the job queue. */ struct job_t { diff --git a/src/libstrongswan/processing/processor.c b/src/libstrongswan/processing/processor.c index 0f0c192d2..5b7fd467c 100644 --- a/src/libstrongswan/processing/processor.c +++ b/src/libstrongswan/processing/processor.c @@ -217,13 +217,13 @@ static void process_jobs(worker_thread_t *worker) while (TRUE) { requeue = worker->job->execute(worker->job); - if (requeue != JOB_REQUEUE_DIRECT) + if (requeue.type != JOB_REQUEUE_TYPE_DIRECT) { break; } else if (!worker->job->cancel) { /* only allow cancelable jobs to requeue directly */ - requeue = JOB_REQUEUE_FAIR; + requeue.type = JOB_REQUEUE_TYPE_FAIR; break; } } @@ -234,25 +234,41 @@ static void process_jobs(worker_thread_t *worker) { /* job was canceled via a custom cancel() method or did not * use JOB_REQUEUE_TYPE_DIRECT */ worker->job->destroy(worker->job); + break; } - else + switch (requeue.type) { - switch (requeue) - { - case JOB_REQUEUE_NONE: - worker->job->status = JOB_STATUS_DONE; - worker->job->destroy(worker->job); - break; - case JOB_REQUEUE_FAIR: - worker->job->status = JOB_STATUS_QUEUED; - this->jobs[i]->insert_last(this->jobs[i], - worker->job); - this->job_added->signal(this->job_added); - break; - case JOB_REQUEUE_SCHEDULED: - default: - break; - } + case JOB_REQUEUE_TYPE_NONE: + worker->job->status = JOB_STATUS_DONE; + worker->job->destroy(worker->job); + break; + case JOB_REQUEUE_TYPE_FAIR: + worker->job->status = JOB_STATUS_QUEUED; + this->jobs[i]->insert_last(this->jobs[i], + worker->job); + this->job_added->signal(this->job_added); + break; + case JOB_REQUEUE_TYPE_SCHEDULE: + /* scheduler_t does not hold its lock when queeuing jobs + * so this should be safe without unlocking our mutex */ + switch (requeue.schedule) + { + case JOB_SCHEDULE: + lib->scheduler->schedule_job(lib->scheduler, + worker->job, requeue.time.rel); + break; + case JOB_SCHEDULE_MS: + lib->scheduler->schedule_job_ms(lib->scheduler, + worker->job, requeue.time.rel); + break; + case JOB_SCHEDULE_TV: + lib->scheduler->schedule_job_tv(lib->scheduler, + worker->job, requeue.time.abs); + break; + } + break; + default: + break; } break; } |