ext/threads/shared/t/wait.t Test cond_wait and cond_timedwait
ext/threads/shared/typemap thread::shared types
ext/threads/t/basic.t ithreads
+ext/threads/t/blocks.t Test threads in special blocks
ext/threads/t/end.t Test end functions
ext/threads/t/free.t Test ithread destruction
ext/threads/t/free2.t More ithread destruction tests
Revision history for Perl extension threads.
+1.29 Thu May 18 16:09:28 EDT 2006
+ - Fix warning/core dump from ->create('foo') in BEGIN block
+
1.28 Wed May 17 14:33:13 EDT 2006
- Fix for build failure under older Perl versions
- Skip signalling tests if using unsafe signals
-threads version 1.28
+threads version 1.29
====================
This module needs perl 5.8.0 or later compiled with 'useithreads'.
--- /dev/null
+use strict;
+use warnings;
+
+BEGIN {
+ if ($ENV{'PERL_CORE'}){
+ chdir 't';
+ unshift @INC, '../lib';
+ }
+ use Config;
+ if (! $Config{'useithreads'}) {
+ print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ exit(0);
+ }
+}
+
+use ExtUtils::testlib;
+
+use threads;
+use threads::shared;
+
+my $TEST;
+BEGIN {
+ $| = 1;
+ print("1..5\n"); ### Number of tests that will be run ###
+
+ share($TEST);
+ $TEST = 1;
+};
+
+ok(1, 'Loaded');
+
+sub ok {
+ my ($ok, $name) = @_;
+
+ lock($TEST);
+ my $id = $TEST++;
+
+ # You have to do it this way or VMS will get confused.
+ if ($ok) {
+ print("ok $id - $name\n");
+ } else {
+ print("not ok $id - $name\n");
+ printf("# Failed test at line %d\n", (caller)[2]);
+ }
+
+ return ($ok);
+}
+
+
+### Start of Testing ###
+
+$SIG{'__WARN__'} = sub { ok(0, "Warning: $_[0]"); };
+
+sub foo { }
+sub baz { 42 }
+
+my $bthr;
+BEGIN {
+ $SIG{'__WARN__'} = sub { ok(0, "BEGIN: $_[0]"); };
+
+ threads->create('foo')->join();
+ threads->create(\&foo)->join();
+ threads->create(sub {})->join();
+
+ threads->create('foo')->detach();
+ threads->create(\&foo)->detach();
+ threads->create(sub {})->detach();
+
+ $bthr = threads->create('baz');
+}
+
+my $mthr;
+MAIN: {
+ threads->create('foo')->join();
+ threads->create(\&foo)->join();
+ threads->create(sub {})->join();
+
+ threads->create('foo')->detach();
+ threads->create(\&foo)->detach();
+ threads->create(sub {})->detach();
+
+ $mthr = threads->create('baz');
+}
+
+ok($mthr, 'Main thread');
+ok($bthr, 'BEGIN thread');
+
+ok($mthr->join() == 42, 'Main join');
+ok($bthr->join() == 42, 'BEGIN join');
+
+# EOF
use strict;
use warnings;
-our $VERSION = '1.28';
+our $VERSION = '1.29';
my $XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
=head1 VERSION
-This document describes threads version 1.28
+This document describes threads version 1.29
=head1 SYNOPSIS
=item Creating threads inside special blocks
-Creating threads inside C<BEGIN>, C<CHECK> or C<INIT> blocks cannot be relied
-upon. Depending on the Perl version and the application code, results may
-range from success, to (apparently harmless) warnings of leaked scalar or
-attempts to free unreferenced scalars, all the way up to crashing of the Perl
-interpreter.
+Creating threads inside C<BEGIN>, C<CHECK> or C<INIT> blocks should not be
+relied upon. Depending on the Perl version and the application code, results
+may range from success, to (apparently harmless) warnings of leaked scalar,
+all the way up to crashing of the Perl interpreter.
=item Unsafe signals
=item Returning closures from threads
-Returning closures from threads cannot be relied upon. Depending of the Perl
-version and the application code, results may range from success, to
+Returning closures from threads should not be relied upon. Depending of the
+Perl version and the application code, results may range from success, to
(apparently harmless) warnings of leaked scalar, all the way up to crashing of
the Perl interpreter.
L<http://www.cpanforum.com/dist/threads>
Annotated POD for L<threads>:
-L<http://annocpan.org/~JDHEDDEN/threads-1.28/shared.pm>
+L<http://annocpan.org/~JDHEDDEN/threads-1.29/shared.pm>
L<threads::shared>, L<perlthrtut>
SvREFCNT_dec(PL_endav);
PL_endav = newAV();
- clone_param.flags = 0;
- thread->init_function = sv_dup(init_function, &clone_param);
- if (SvREFCNT(thread->init_function) == 0) {
- SvREFCNT_inc(thread->init_function);
+ if (SvPOK(init_function)) {
+ thread->init_function = newSV(0);
+ sv_copypv(thread->init_function, init_function);
+ } else {
+ clone_param.flags = 0;
+ thread->init_function = sv_dup(init_function, &clone_param);
+ if (SvREFCNT(thread->init_function) == 0) {
+ SvREFCNT_inc(thread->init_function);
+ }
}
thread->params = sv_dup(params, &clone_param);