svn commit: r208623 - in head/sys: kern sys
Zachary Loafman
zml at FreeBSD.org
Fri May 28 18:15:28 UTC 2010
Author: zml
Date: Fri May 28 18:15:28 2010
New Revision: 208623
URL: http://svn.freebsd.org/changeset/base/208623
Log:
Revert r207439 and solve the problem differently. The task handler
ta_func may free the task structure, so no references to its members
are valid after the handler has been called. Using a per-queue member
and having waits longer than strictly necessary was suggested by jhb.
Submitted by: Matthew Fleming <matthew.fleming at isilon.com>
Reviewed by: zml, jhb
Modified:
head/sys/kern/subr_taskqueue.c
head/sys/sys/_task.h
head/sys/sys/taskqueue.h
Modified: head/sys/kern/subr_taskqueue.c
==============================================================================
--- head/sys/kern/subr_taskqueue.c Fri May 28 17:50:35 2010 (r208622)
+++ head/sys/kern/subr_taskqueue.c Fri May 28 18:15:28 2010 (r208623)
@@ -56,6 +56,7 @@ struct taskqueue {
int tq_tcount;
int tq_spin;
int tq_flags;
+ int tq_tasks_running;
};
#define TQ_FLAGS_ACTIVE (1 << 0)
@@ -232,13 +233,13 @@ taskqueue_run(struct taskqueue *queue)
STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link);
pending = task->ta_pending;
task->ta_pending = 0;
- task->ta_flags |= TA_FLAGS_RUNNING;
+ queue->tq_tasks_running++;
TQ_UNLOCK(queue);
task->ta_func(task->ta_context, pending);
TQ_LOCK(queue);
- task->ta_flags &= ~TA_FLAGS_RUNNING;
+ queue->tq_tasks_running--;
wakeup(task);
}
@@ -255,16 +256,14 @@ taskqueue_drain(struct taskqueue *queue,
{
if (queue->tq_spin) { /* XXX */
mtx_lock_spin(&queue->tq_mutex);
- while (task->ta_pending != 0 ||
- (task->ta_flags & TA_FLAGS_RUNNING) != 0)
+ while (task->ta_pending != 0 || queue->tq_tasks_running > 0)
msleep_spin(task, &queue->tq_mutex, "-", 0);
mtx_unlock_spin(&queue->tq_mutex);
} else {
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__);
mtx_lock(&queue->tq_mutex);
- while (task->ta_pending != 0 ||
- (task->ta_flags & TA_FLAGS_RUNNING) != 0)
+ while (task->ta_pending != 0 || queue->tq_tasks_running > 0)
msleep(task, &queue->tq_mutex, PWAIT, "-", 0);
mtx_unlock(&queue->tq_mutex);
}
Modified: head/sys/sys/_task.h
==============================================================================
--- head/sys/sys/_task.h Fri May 28 17:50:35 2010 (r208622)
+++ head/sys/sys/_task.h Fri May 28 18:15:28 2010 (r208623)
@@ -45,8 +45,6 @@ typedef void task_fn_t(void *context, in
struct task {
STAILQ_ENTRY(task) ta_link; /* (q) link for queue */
- u_int ta_flags; /* (q) state of this task */
-#define TA_FLAGS_RUNNING 0x01
u_short ta_pending; /* (q) count times queued */
u_short ta_priority; /* (c) Priority */
task_fn_t *ta_func; /* (c) task handler */
Modified: head/sys/sys/taskqueue.h
==============================================================================
--- head/sys/sys/taskqueue.h Fri May 28 17:50:35 2010 (r208622)
+++ head/sys/sys/taskqueue.h Fri May 28 18:15:28 2010 (r208623)
@@ -75,7 +75,6 @@ void taskqueue_thread_enqueue(void *cont
(task)->ta_priority = (priority); \
(task)->ta_func = (func); \
(task)->ta_context = (context); \
- (task)->ta_flags = 0; \
} while (0)
/*
More information about the svn-src-all
mailing list