summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2004-07-17 09:36:41 +0000
committerNicholas Clark <nick@ccl4.org>2004-07-17 09:36:41 +0000
commit257486d53c90e81b321ffd92246be675abbb9ef5 (patch)
tree2d053afa1c4a4b9e0380b27fe784eb450b5cbcf4
parent14bbf69a04f8ac576d744f6a0564fe904dde880a (diff)
downloadperl-257486d53c90e81b321ffd92246be675abbb9ef5.tar.gz
Integrate:
[ 23120] threads.xs doesn't check the return value of the thread creation call. D'oh! This gives SEGVs if the OS fails to create another thread. Cause of problem located by Nigel Sandever p4raw-link: @23120 on //depot/perl: d94006e83fb3a18ffb59fd5cb41bc7ab9d73a7f6 p4raw-id: //depot/maint-5.8/perl@23133 p4raw-integrated: from //depot/perl@23132 'copy in' ext/threads/threads.pm (@23019..) p4raw-integrated: from //depot/perl@23120 'copy in' ext/threads/threads.xs (@22918..)
-rwxr-xr-xext/threads/threads.pm5
-rwxr-xr-xext/threads/threads.xs32
2 files changed, 30 insertions, 7 deletions
diff --git a/ext/threads/threads.pm b/ext/threads/threads.pm
index a355f49fbe..dcd2aa015c 100755
--- a/ext/threads/threads.pm
+++ b/ext/threads/threads.pm
@@ -50,7 +50,7 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
async
);
-our $VERSION = '1.04';
+our $VERSION = '1.05';
# || 0 to ensure compatibility with previous versions
@@ -139,7 +139,8 @@ it the other way around.
This will create a new thread with the entry point function and give
it LIST as parameters. It will return the corresponding threads
-object. The new() method is an alias for create().
+object, or C<undef> if thread creation failed. The new() method is an
+alias for create().
=item $thread->join
diff --git a/ext/threads/threads.xs b/ext/threads/threads.xs
index e52143d587..4148fb0ac8 100755
--- a/ext/threads/threads.xs
+++ b/ext/threads/threads.xs
@@ -381,6 +381,10 @@ Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* param
SV** tmps_tmp = PL_tmps_stack;
I32 tmps_ix = PL_tmps_ix;
+#ifndef WIN32
+ int failure;
+ const char* panic = NULL;
+#endif
MUTEX_LOCK(&create_destruct_mutex);
@@ -480,10 +484,8 @@ Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* param
/* Start the thread */
#ifdef WIN32
-
thread->handle = CreateThread(NULL, 0, Perl_ithread_run,
(LPVOID)thread, 0, &thread->thr);
-
#else
{
static pthread_attr_t attr;
@@ -498,20 +500,40 @@ Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* param
# endif
# ifdef THREAD_CREATE_NEEDS_STACK
if(pthread_attr_setstacksize(&attr, THREAD_CREATE_NEEDS_STACK))
- Perl_croak(aTHX_ "panic: pthread_attr_setstacksize failed");
+ panic = "panic: pthread_attr_setstacksize failed";
# endif
#ifdef OLD_PTHREADS_API
- pthread_create( &thread->thr, attr, Perl_ithread_run, (void *)thread);
+ failure
+ = panic ? 1 : pthread_create( &thread->thr, attr,
+ Perl_ithread_run, (void *)thread);
#else
# if defined(HAS_PTHREAD_ATTR_SETSCOPE) && defined(PTHREAD_SCOPE_SYSTEM)
pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
# endif
- pthread_create( &thread->thr, &attr, Perl_ithread_run, (void *)thread);
+ failure
+ = panic ? 1 : pthread_create( &thread->thr, &attr,
+ Perl_ithread_run, (void *)thread);
#endif
}
#endif
known_threads++;
+ if (
+#ifdef WIN32
+ thread->handle == NULL
+#else
+ failure
+#endif
+ ) {
+ MUTEX_UNLOCK(&create_destruct_mutex);
+ sv_2mortal(params);
+ Perl_ithread_destruct(aTHX_ thread, "create failed");
+#ifndef WIN32
+ if (panic)
+ Perl_croak(aTHX_ panic);
+#endif
+ return &PL_sv_undef;
+ }
active_threads++;
MUTEX_UNLOCK(&create_destruct_mutex);
sv_2mortal(params);