patch-2.1.36 linux/kernel/fork.c

Next file: linux/kernel/info.c
Previous file: linux/kernel/exit.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.35/linux/kernel/fork.c linux/kernel/fork.c
@@ -47,11 +47,15 @@
 		max_tasks--;	/* count the new process.. */
 		if (max_tasks < nr_tasks) {
 			struct task_struct *p;
+			read_lock(&tasklist_lock);
 			for_each_task (p) {
 				if (p->uid == current->uid)
-					if (--max_tasks < 0)
+					if (--max_tasks < 0) {
+						read_unlock(&tasklist_lock);
 						return -EAGAIN;
+					}
 			}
+			read_unlock(&tasklist_lock);
 		}
 	}
 	for (i = 0 ; i < NR_TASKS ; i++) {
@@ -67,6 +71,8 @@
 
 	if (flags & CLONE_PID)
 		return current->pid;
+
+	read_lock(&tasklist_lock);
 repeat:
 	if ((++last_pid) & 0xffff8000)
 		last_pid=1;
@@ -76,6 +82,8 @@
 		    p->session == last_pid)
 			goto repeat;
 	}
+	read_unlock(&tasklist_lock);
+
 	return last_pid;
 }
 
@@ -203,13 +211,14 @@
 static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
 {
 	if (clone_flags & CLONE_SIGHAND) {
-		current->sig->count++;
+		atomic_inc(&current->sig->count);
 		return 0;
 	}
 	tsk->sig = kmalloc(sizeof(*tsk->sig), GFP_KERNEL);
 	if (!tsk->sig)
 		return -1;
-	tsk->sig->count = 1;
+	spin_lock_init(&tsk->sig->siglock);
+	atomic_set(&tsk->sig->count, 1);
 	memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action));
 	return 0;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov