aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan/processing
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/processing')
-rw-r--r--src/libstrongswan/processing/jobs/job.h68
-rw-r--r--src/libstrongswan/processing/processor.c54
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;
}