o eliminate modification of task structures after their run to avoid

modify-after-free races when the task structure is malloc'd
o shrink task structure by removing ta_flags (no longer needed with
  avoid fix) and combining ta_pending and ta_priority

Reviewed by:	dwhite, dfr
MFC after:	4 days
This commit is contained in:
Sam Leffler 2005-04-24 16:52:45 +00:00
parent c770569c74
commit f4581151a8
3 changed files with 6 additions and 9 deletions

View File

@ -51,6 +51,7 @@ struct taskqueue {
const char *tq_name; const char *tq_name;
taskqueue_enqueue_fn tq_enqueue; taskqueue_enqueue_fn tq_enqueue;
void *tq_context; void *tq_context;
struct task *tq_running;
struct mtx tq_mutex; struct mtx tq_mutex;
}; };
@ -186,13 +187,13 @@ taskqueue_run(struct taskqueue *queue)
STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link); STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link);
pending = task->ta_pending; pending = task->ta_pending;
task->ta_pending = 0; task->ta_pending = 0;
task->ta_flags |= TAF_PENDING; queue->tq_running = task;
mtx_unlock(&queue->tq_mutex); mtx_unlock(&queue->tq_mutex);
task->ta_func(task->ta_context, pending); task->ta_func(task->ta_context, pending);
mtx_lock(&queue->tq_mutex); mtx_lock(&queue->tq_mutex);
task->ta_flags &= ~TAF_PENDING; queue->tq_running = NULL;
wakeup(task); wakeup(task);
} }
@ -209,7 +210,7 @@ taskqueue_drain(struct taskqueue *queue, struct task *task)
{ {
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "taskqueue_drain"); WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "taskqueue_drain");
mtx_lock(&queue->tq_mutex); mtx_lock(&queue->tq_mutex);
while (task->ta_pending != 0 || (task->ta_flags & TAF_PENDING)) { while (task->ta_pending != 0 || task == queue->tq_running) {
msleep(task, &queue->tq_mutex, PWAIT, "-", 0); msleep(task, &queue->tq_mutex, PWAIT, "-", 0);
} }
mtx_unlock(&queue->tq_mutex); mtx_unlock(&queue->tq_mutex);

View File

@ -41,13 +41,10 @@ typedef void task_fn_t(void *context, int pending);
struct task { struct task {
STAILQ_ENTRY(task) ta_link; /* link for queue */ STAILQ_ENTRY(task) ta_link; /* link for queue */
int ta_pending; /* count times queued */ u_short ta_pending; /* count times queued */
int ta_priority; /* priority of task in queue */ u_short ta_priority; /* Priority */
task_fn_t *ta_func; /* task handler */ task_fn_t *ta_func; /* task handler */
void *ta_context; /* argument for handler */ void *ta_context; /* argument for handler */
int ta_flags; /* Flags */
}; };
#define TAF_PENDING 0x1 /* Task is being run now */
#endif /* !_SYS__TASK_H_ */ #endif /* !_SYS__TASK_H_ */

View File

@ -70,7 +70,6 @@ void taskqueue_thread_enqueue(void *context);
(task)->ta_priority = (priority); \ (task)->ta_priority = (priority); \
(task)->ta_func = (func); \ (task)->ta_func = (func); \
(task)->ta_context = (context); \ (task)->ta_context = (context); \
(task)->ta_flags = 0; \
} while (0) } while (0)
/* /*