summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-09-24 18:22:04 +0000
committerUlrich Drepper <drepper@redhat.com>2004-09-24 18:22:04 +0000
commit3f80a99b8f5c9b7927a5a77f0c1854f0deeb1b25 (patch)
tree5a289c9186beda8f0fbc620dc1e2ca9f5088e341
parentebfa58bb230933c35798a83f99a7a0c95c9d2217 (diff)
[BZ #405]
Update. * pthread_create.c (__pthread_create_2_1): Remember whether thread is created detached and if yes, do not try to free the stack in case the thread creation failed. * sysdeps/pthread/createthread.c (do_clone): Free stack here if clone call fails. Don't depend on INTERNAL_SYSCALL_ERRNO return zero in case there has been no error. [BZ #405]
-rw-r--r--nptl/ChangeLog7
-rw-r--r--nptl/sysdeps/pthread/createthread.c16
2 files changed, 20 insertions, 3 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 2182cac1cf..01c6c10165 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,5 +1,12 @@
2004-09-24 Ulrich Drepper <drepper@redhat.com>
+ * pthread_create.c (__pthread_create_2_1): Remember whether thread
+ is created detached and if yes, do not try to free the stack in case
+ the thread creation failed.
+ * sysdeps/pthread/createthread.c (do_clone): Free stack here if clone
+ call fails. Don't depend on INTERNAL_SYSCALL_ERRNO return zero in
+ case there has been no error. [BZ #405]
+
* pthread_create.c (start_thread): Don't wait for scheduler data
etc to be set at the beginning of the function. The cancellation
infrastructure must have been set up. And enable async
diff --git a/nptl/sysdeps/pthread/createthread.c b/nptl/sysdeps/pthread/createthread.c
index 49383cf769..fb8d8ce937 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);
}
}