aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-05-10 00:03:52 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-05-10 00:03:52 -0700
commit5805ad402642142b5a769e1553c4e45a52653efe (patch)
tree094e0215b2fc90f17a651413af1904d4d377209c /kernel
parentdf125ce9fe67e9b5b4e39c98d11dcc5fc3f297e4 (diff)
downloadhistory-5805ad402642142b5a769e1553c4e45a52653efe.tar.gz
[PATCH] worker_thread race fix
Fix a waitqueue-handling race in worker_thread().
Diffstat (limited to 'kernel')
-rw-r--r--kernel/workqueue.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 8c0be4dc39bb7..c2d0680a2cbb5 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -201,19 +201,20 @@ static int worker_thread(void *__cwq)
siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD));
do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0);
+ set_current_state(TASK_INTERRUPTIBLE);
while (!kthread_should_stop()) {
- set_task_state(current, TASK_INTERRUPTIBLE);
-
add_wait_queue(&cwq->more_work, &wait);
if (list_empty(&cwq->worklist))
schedule();
else
- set_task_state(current, TASK_RUNNING);
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&cwq->more_work, &wait);
if (!list_empty(&cwq->worklist))
run_workqueue(cwq);
+ set_current_state(TASK_INTERRUPTIBLE);
}
+ __set_current_state(TASK_RUNNING);
return 0;
}