aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2007-09-13 11:24:25 -0400
committerPaul Mackerras <paulus@samba.org>2007-09-13 11:24:25 -0400
commitb2315372eac9cd9f622c32a93e323cf6f0f03462 (patch)
tree9e1faa7cdcddf5d90bec4fb9523742d4cce699a1 /kernel/signal.c
parent5326152fa182b0a16e4abf913ce403e3c7ab53b7 (diff)
parentc87ce65868bbf9bbea9c3f112ff8315302daf8f2 (diff)
Merge branch 'linux-2.6' into for-2.6.24
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index ad63109e413c..3169bed0b4d0 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1300,20 +1300,19 @@ struct sigqueue *sigqueue_alloc(void)
1300void sigqueue_free(struct sigqueue *q) 1300void sigqueue_free(struct sigqueue *q)
1301{ 1301{
1302 unsigned long flags; 1302 unsigned long flags;
1303 spinlock_t *lock = &current->sighand->siglock;
1304
1303 BUG_ON(!(q->flags & SIGQUEUE_PREALLOC)); 1305 BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
1304 /* 1306 /*
1305 * If the signal is still pending remove it from the 1307 * If the signal is still pending remove it from the
1306 * pending queue. 1308 * pending queue. We must hold ->siglock while testing
1309 * q->list to serialize with collect_signal().
1307 */ 1310 */
1308 if (unlikely(!list_empty(&q->list))) { 1311 spin_lock_irqsave(lock, flags);
1309 spinlock_t *lock = &current->sighand->siglock; 1312 if (!list_empty(&q->list))
1310 read_lock(&tasklist_lock); 1313 list_del_init(&q->list);
1311 spin_lock_irqsave(lock, flags); 1314 spin_unlock_irqrestore(lock, flags);
1312 if (!list_empty(&q->list)) 1315
1313 list_del_init(&q->list);
1314 spin_unlock_irqrestore(lock, flags);
1315 read_unlock(&tasklist_lock);
1316 }
1317 q->flags &= ~SIGQUEUE_PREALLOC; 1316 q->flags &= ~SIGQUEUE_PREALLOC;
1318 __sigqueue_free(q); 1317 __sigqueue_free(q);
1319} 1318}