diff options
author | Andrew Morton <akpm@osdl.org> | 2004-05-10 00:03:52 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-05-10 00:03:52 -0700 |
commit | 5805ad402642142b5a769e1553c4e45a52653efe (patch) | |
tree | 094e0215b2fc90f17a651413af1904d4d377209c /kernel | |
parent | df125ce9fe67e9b5b4e39c98d11dcc5fc3f297e4 (diff) | |
download | history-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.c | 7 |
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; } |