about summary refs log tree commit diff
path: root/nptl/sysdeps/pthread/createthread.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2004-09-25 07:55:46 +0000
committerJakub Jelinek <jakub@redhat.com>2004-09-25 07:55:46 +0000
commitbd7c3bed543d02fb01f69b29ea1a736e7a0f618d (patch)
tree7e9bf02d1315ce177dd95075686ba769057d04b2 /nptl/sysdeps/pthread/createthread.c
parent338cc5101b59b64358bab982e1311604fdb64651 (diff)
downloadglibc-bd7c3bed543d02fb01f69b29ea1a736e7a0f618d.tar.gz
glibc-bd7c3bed543d02fb01f69b29ea1a736e7a0f618d.tar.xz
glibc-bd7c3bed543d02fb01f69b29ea1a736e7a0f618d.zip
Updated to fedora-glibc-20040925T0738
Diffstat (limited to 'nptl/sysdeps/pthread/createthread.c')
-rw-r--r--nptl/sysdeps/pthread/createthread.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/nptl/sysdeps/pthread/createthread.c b/nptl/sysdeps/pthread/createthread.c
index 49383cf769..8620519887 100644
--- a/nptl/sysdeps/pthread/createthread.c
+++ b/nptl/sysdeps/pthread/createthread.c
@@ -66,8 +66,16 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
 
   if (ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
 		  pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
-    /* Failed.  */
-    return errno;
+    {
+      /* Failed.  If the thread is detached, remove the TCB here since
+	 the caller cannot do this.  The caller remembered the thread
+	 as detached and cannot reverify that it is not since it must
+	 not access the thread descriptor again.  */
+      if (IS_DETACHED (pd))
+	__deallocate_stack (pd);
+
+      return errno;
+    }
 
   /* Now we have the possibility to set scheduling parameters etc.  */
   if (__builtin_expect (stopped != 0, 0))
@@ -95,7 +103,9 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr,
 	      (void) INTERNAL_SYSCALL (tkill, err2, 2, pd->tid, SIGCANCEL);
 #endif
 
-	      return INTERNAL_SYSCALL_ERRNO (res, err);
+	      return (INTERNAL_SYSCALL_ERROR_P (res, err)
+		      ? INTERNAL_SYSCALL_ERRNO (res, err)
+		      : 0);
 	    }
 	}
 
@@ -176,6 +186,9 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr,
       if ((_mask & (__nptl_threads_events.event_bits[_idx]
 		    | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
 	{
+	  /* We always must have the thread start stopped.  */
+	  pd->stopped_start = true;
+
 	  /* Create the thread.  We always create the thread stopped
 	     so that it does not get far before we tell the debugger.  */
 	  int res = do_clone (pd, attr, clone_flags, start_thread,
@@ -214,10 +227,11 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr,
   /* Determine whether the newly created threads has to be started
      stopped since we have to set the scheduling parameters or set the
      affinity.  */
-  int stopped = 0;
+  bool stopped = false;
   if (attr != NULL && (attr->cpuset != NULL
 		       || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))
-    stopped = 1;
+    stopped = true;
+  pd->stopped_start = stopped;
 
   /* Actually create the thread.  */
   int res = do_clone (pd, attr, clone_flags, start_thread,