task-manager: Add method to remove a task from a queue

This commit is contained in:
Tobias Brunner
2018-12-07 10:32:12 +01:00
parent 44558547af
commit 4505e3c0df
3 changed files with 155 additions and 18 deletions
+73 -5
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2007-2016 Tobias Brunner * Copyright (C) 2007-2018 Tobias Brunner
* Copyright (C) 2007-2011 Martin Willi * Copyright (C) 2007-2011 Martin Willi
* HSR Hochschule fuer Technik Rapperswil * HSR Hochschule fuer Technik Rapperswil
* *
@@ -1984,19 +1984,86 @@ METHOD(task_manager_t, reset, void,
} }
} }
/**
* Data for a task queue enumerator
*/
typedef struct {
enumerator_t public;
task_queue_t queue;
enumerator_t *inner;
} task_enumerator_t;
METHOD(enumerator_t, task_enumerator_destroy, void,
task_enumerator_t *this)
{
this->inner->destroy(this->inner);
free(this);
}
METHOD(enumerator_t, task_enumerator_enumerate, bool,
task_enumerator_t *this, va_list args)
{
task_t **task;
VA_ARGS_VGET(args, task);
return this->inner->enumerate(this->inner, task);
}
METHOD(task_manager_t, create_task_enumerator, enumerator_t*, METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
private_task_manager_t *this, task_queue_t queue) private_task_manager_t *this, task_queue_t queue)
{ {
task_enumerator_t *enumerator;
INIT(enumerator,
.public = {
.enumerate = enumerator_enumerate_default,
.venumerate = _task_enumerator_enumerate,
.destroy = _task_enumerator_destroy,
},
.queue = queue,
);
switch (queue) switch (queue)
{ {
case TASK_QUEUE_ACTIVE: case TASK_QUEUE_ACTIVE:
return this->active_tasks->create_enumerator(this->active_tasks); enumerator->inner = this->active_tasks->create_enumerator(
this->active_tasks);
break;
case TASK_QUEUE_PASSIVE: case TASK_QUEUE_PASSIVE:
return this->passive_tasks->create_enumerator(this->passive_tasks); enumerator->inner = this->passive_tasks->create_enumerator(
this->passive_tasks);
break;
case TASK_QUEUE_QUEUED: case TASK_QUEUE_QUEUED:
return this->queued_tasks->create_enumerator(this->queued_tasks); enumerator->inner = this->queued_tasks->create_enumerator(
this->queued_tasks);
break;
default: default:
return enumerator_create_empty(); enumerator->inner = enumerator_create_empty();
break;
}
return &enumerator->public;
}
METHOD(task_manager_t, remove_task, void,
private_task_manager_t *this, enumerator_t *enumerator_public)
{
task_enumerator_t *enumerator = (task_enumerator_t*)enumerator_public;
switch (enumerator->queue)
{
case TASK_QUEUE_ACTIVE:
this->active_tasks->remove_at(this->active_tasks,
enumerator->inner);
break;
case TASK_QUEUE_PASSIVE:
this->passive_tasks->remove_at(this->passive_tasks,
enumerator->inner);
break;
case TASK_QUEUE_QUEUED:
this->queued_tasks->remove_at(this->queued_tasks,
enumerator->inner);
break;
default:
break;
} }
} }
@@ -2050,6 +2117,7 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa)
.adopt_child_tasks = _adopt_child_tasks, .adopt_child_tasks = _adopt_child_tasks,
.busy = _busy, .busy = _busy,
.create_task_enumerator = _create_task_enumerator, .create_task_enumerator = _create_task_enumerator,
.remove_task = _remove_task,
.flush = _flush, .flush = _flush,
.flush_queue = _flush_queue, .flush_queue = _flush_queue,
.destroy = _destroy, .destroy = _destroy,
+71 -12
View File
@@ -2186,17 +2186,39 @@ METHOD(task_manager_t, reset, void,
this->reset = TRUE; this->reset = TRUE;
} }
CALLBACK(filter_queued, bool, /**
void *unused, enumerator_t *orig, va_list args) * Data for a task queue enumerator
{ */
typedef struct {
enumerator_t public;
task_queue_t queue;
enumerator_t *inner;
queued_task_t *queued; queued_task_t *queued;
} task_enumerator_t;
METHOD(enumerator_t, task_enumerator_destroy, void,
task_enumerator_t *this)
{
this->inner->destroy(this->inner);
free(this);
}
METHOD(enumerator_t, task_enumerator_enumerate, bool,
task_enumerator_t *this, va_list args)
{
task_t **task; task_t **task;
VA_ARGS_VGET(args, task); VA_ARGS_VGET(args, task);
if (this->queue == TASK_QUEUE_QUEUED)
if (orig->enumerate(orig, &queued)) {
if (this->inner->enumerate(this->inner, &this->queued))
{
*task = this->queued->task;
return TRUE;
}
}
else if (this->inner->enumerate(this->inner, task))
{ {
*task = queued->task;
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
@@ -2205,18 +2227,54 @@ CALLBACK(filter_queued, bool,
METHOD(task_manager_t, create_task_enumerator, enumerator_t*, METHOD(task_manager_t, create_task_enumerator, enumerator_t*,
private_task_manager_t *this, task_queue_t queue) private_task_manager_t *this, task_queue_t queue)
{ {
task_enumerator_t *enumerator;
INIT(enumerator,
.public = {
.enumerate = enumerator_enumerate_default,
.venumerate = _task_enumerator_enumerate,
.destroy = _task_enumerator_destroy,
},
.queue = queue,
);
switch (queue) switch (queue)
{ {
case TASK_QUEUE_ACTIVE: case TASK_QUEUE_ACTIVE:
return array_create_enumerator(this->active_tasks); enumerator->inner = array_create_enumerator(this->active_tasks);
break;
case TASK_QUEUE_PASSIVE: case TASK_QUEUE_PASSIVE:
return array_create_enumerator(this->passive_tasks); enumerator->inner = array_create_enumerator(this->passive_tasks);
break;
case TASK_QUEUE_QUEUED: case TASK_QUEUE_QUEUED:
return enumerator_create_filter( enumerator->inner = array_create_enumerator(this->queued_tasks);
array_create_enumerator(this->queued_tasks), break;
filter_queued, NULL, NULL);
default: default:
return enumerator_create_empty(); enumerator->inner = enumerator_create_empty();
break;
}
return &enumerator->public;
}
METHOD(task_manager_t, remove_task, void,
private_task_manager_t *this, enumerator_t *enumerator_public)
{
task_enumerator_t *enumerator = (task_enumerator_t*)enumerator_public;
switch (enumerator->queue)
{
case TASK_QUEUE_ACTIVE:
array_remove_at(this->active_tasks, enumerator->inner);
break;
case TASK_QUEUE_PASSIVE:
array_remove_at(this->passive_tasks, enumerator->inner);
break;
case TASK_QUEUE_QUEUED:
array_remove_at(this->queued_tasks, enumerator->inner);
free(enumerator->queued);
enumerator->queued = NULL;
break;
default:
break;
} }
} }
@@ -2269,6 +2327,7 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa)
.adopt_child_tasks = _adopt_child_tasks, .adopt_child_tasks = _adopt_child_tasks,
.busy = _busy, .busy = _busy,
.create_task_enumerator = _create_task_enumerator, .create_task_enumerator = _create_task_enumerator,
.remove_task = _remove_task,
.flush = _flush, .flush = _flush,
.flush_queue = _flush_queue, .flush_queue = _flush_queue,
.destroy = _destroy, .destroy = _destroy,
+11 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2013-2016 Tobias Brunner * Copyright (C) 2013-2018 Tobias Brunner
* Copyright (C) 2006 Martin Willi * Copyright (C) 2006 Martin Willi
* HSR Hochschule fuer Technik Rapperswil * HSR Hochschule fuer Technik Rapperswil
* *
@@ -284,6 +284,16 @@ struct task_manager_t {
enumerator_t* (*create_task_enumerator)(task_manager_t *this, enumerator_t* (*create_task_enumerator)(task_manager_t *this,
task_queue_t queue); task_queue_t queue);
/**
* Remove the task the given enumerator points to.
*
* @note This should be used with caution, in partciular, for tasks in the
* active and passive queues.
*
* @param enumerator enumerator created with the method above
*/
void (*remove_task)(task_manager_t *this, enumerator_t *enumerator);
/** /**
* Flush all tasks, regardless of the queue. * Flush all tasks, regardless of the queue.
*/ */