Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Commit dc1faeb

Browse files
committed
threads-2.22_01
Fix Clang macro backward compatibility per patch by Andy Grundman. Keep the old better doc. Keep our modglobal fix in global destruction from 2.12_01. Support PL_sv_zero. Don't Copy() null pointer The documentation now better describes the problems that arise when returning values from threads, and no longer warns about creating threads in BEGIN blocks. [perl #96538]
1 parent 9890bc3 commit dc1faeb

File tree

11 files changed

+141
-50
lines changed

11 files changed

+141
-50
lines changed

Porting/Maintainers.pl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,8 @@ package Maintainers;
14641464
},
14651465

14661466
'threads' => {
1467-
'DISTRIBUTION' => 'JDHEDDEN/threads-2.16.tar.gz',
1467+
# https://github.com/rurban/threads/commits/cperl really
1468+
'DISTRIBUTION' => 'RURBAN/threads-2.22_01.tar.gz',
14681469
'FILES' => q[dist/threads],
14691470
'EXCLUDED' => [
14701471
qr{^examples/},

dist/Module-CoreList/lib/Module/CoreList.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17833,6 +17833,7 @@ our %delta :const = (
1783317833
'TAP::Parser::YAMLish::Writer'=> '3.42_01',
1783417834
'Test::Harness' => '3.42_01',
1783517835
'Thread::Queue' => '3.13',
17836+
'threads' => '2.22_01',
1783617837
'Time::HiRes' => '1.9758_01',
1783717838
'Time::Local' => '1.28',
1783817839
'Time::Piece' => '1.33',

dist/threads/Changes

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
Revision history for Perl extension threads.
22

3+
2.22_01 Fri Sep 7 13:00:29 2018 +0200 rurban
4+
- locale safety backport
5+
6+
2.22 Tue Jan 23 01:14:04 2018 +0100
7+
- more locale safety from perl5
8+
9+
2.21 Mon Jan 22 20:09:07 EST 2018
10+
- Fix to CLANG macros
11+
- Can return subs from threads. See docs.
12+
- Sync from blead
13+
314
2.16 Sun May 7 22:32:59 2017
415
- Fix Clang macro backward compatibility per patch by Andy Grundman
516
- Sync from blead
@@ -10,6 +21,9 @@ Revision history for Perl extension threads.
1021
2.14 Sun Feb 26 21:14:26 2017
1122
- Sync from blead
1223

24+
2.13_01 Sun Mar 5 19:27:49 2017 +0100
25+
- locale safety from cperl
26+
1327
2.13 Sun Feb 26 17:59:01 2017
1428
- Added t/kill3.t to test that dir handles are thread-safe
1529

dist/threads/lib/threads.pm

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use 5.008;
55
use strict;
66
use warnings;
77

8-
our $VERSION = '2.16_01';
8+
our $VERSION = '2.22_01'; # remember to update version in POD!
99
my $XS_VERSION = $VERSION;
1010
$VERSION = eval $VERSION;
1111

@@ -29,8 +29,7 @@ $threads::threads = 1;
2929

3030
# Load the XS code
3131
require XSLoader;
32-
XSLoader::load('threads', $XS_VERSION);
33-
32+
XSLoader::load("threads", $XS_VERSION);
3433

3534
### Export ###
3635

@@ -134,7 +133,7 @@ threads - Perl interpreter-based threads
134133
135134
=head1 VERSION
136135
137-
This document describes threads version 2.16
136+
This document describes threads version 2.22_01 (with fixes from cperl)
138137
139138
=head1 WARNING
140139
@@ -951,6 +950,36 @@ C<chdir()>) will affect all the threads in the application.
951950
On MSWin32, each thread maintains its own the current working directory
952951
setting.
953952
953+
=item Locales
954+
955+
Prior to Perl 5.28 or cperl 5.24 locales could not be used with
956+
threads, due to various race conditions. Starting with Perl 5.28 on
957+
systems that implement thread-safe locale functions, threads can be
958+
used even on perl5 with some caveats. Previously only with cperl,
959+
but perl5 still has many unsolved issues.
960+
This includes Windows starting with Visual Studio 2005, and systems
961+
compatible with POSIX 2008. See L<perllocale/Multi-threaded
962+
operation>.
963+
964+
Each thread (except the main thread) is started using the C locale. The main
965+
thread is started like all other Perl programs; see L<perllocale/ENVIRONMENT>.
966+
You can switch locales in any thread as often as you like.
967+
968+
If you want to inherit the parent thread's locale, you can, in the parent, set
969+
a variable like so:
970+
971+
$foo = POSIX::setlocale(LC_ALL, NULL);
972+
973+
and then pass to threads->create() a sub that closes over C<$foo>. Then, in
974+
the child, you say
975+
976+
POSIX::setlocale(LC_ALL, $foo);
977+
978+
Or you can use the facilities in L<threads::shared> to pass C<$foo>;
979+
or if the environment hasn't changed, in the child, do
980+
981+
POSIX::setlocale(LC_ALL, "");
982+
954983
=item Environment variables
955984
956985
Currently, on all platforms except MSWin32, all I<system> calls (e.g., using
@@ -1001,13 +1030,6 @@ L</"THREAD SIGNALLING"> to relay the signal to the thread:
10011030
On some platforms, it might not be possible to destroy I<parent> threads while
10021031
there are still existing I<child> threads.
10031032
1004-
=item Creating threads inside special blocks
1005-
1006-
Creating threads inside C<BEGIN>, C<CHECK> or C<INIT> blocks should not be
1007-
relied upon. Depending on the Perl version and the application code, results
1008-
may range from success, to (apparently harmless) warnings of leaked scalar, or
1009-
all the way up to crashing of the Perl interpreter.
1010-
10111033
=item Unsafe signals
10121034
10131035
Since Perl 5.8.0, signals have been made safer in Perl by postponing their
@@ -1032,16 +1054,27 @@ signalling behavior is only in effect in the following situations:
10321054
If unsafe signals is in effect, then signal handling is not thread-safe, and
10331055
the C<-E<gt>kill()> signalling method cannot be used.
10341056
1035-
=item Returning closures from threads
1057+
=item Identity of objects returned from threads
1058+
1059+
When a value is returned from a thread through a C<join> operation,
1060+
the value and everything that it references is copied across to the
1061+
joining thread, in much the same way that values are copied upon thread
1062+
creation. This works fine for most kinds of value, including arrays,
1063+
hashes, and subroutines. The copying recurses through array elements,
1064+
reference scalars, variables closed over by subroutines, and other kinds
1065+
of reference.
10361066
1037-
Returning closures from threads should not be relied upon. Depending on the
1038-
Perl version and the application code, results may range from success, to
1039-
(apparently harmless) warnings of leaked scalar, or all the way up to crashing
1040-
of the Perl interpreter.
1067+
However, everything referenced by the returned value is a fresh copy in
1068+
the joining thread, even if a returned object had in the child thread
1069+
been a copy of something that previously existed in the parent thread.
1070+
After joining, the parent will therefore have a duplicate of each such
1071+
object. This sometimes matters, especially if the object gets mutated;
1072+
this can especially matter for private data to which a returned subroutine
1073+
provides access.
10411074
1042-
=item Returning objects from threads
1075+
=item Returning blessed objects from threads
10431076
1044-
Returning objects from threads does not work. Depending on the classes
1077+
Returning blessed objects from threads does not work. Depending on the classes
10451078
involved, you may be able to work around this by returning a serialized
10461079
version of the object (e.g., using L<Data::Dumper> or L<Storable>), and then
10471080
reconstituting it in the joining thread. If you're using Perl 5.10.0 or

dist/threads/t/exit.t

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ my $rc = $thr->join();
4848
ok(! defined($rc), 'Exited: threads->exit()');
4949

5050

51-
run_perl(prog => 'use threads 2.16;' .
51+
run_perl(prog => 'use threads 2.21;' .
5252
'threads->exit(86);' .
5353
'exit(99);',
5454
nolib => ($ENV{PERL_CORE}) ? 0 : 1,
@@ -98,7 +98,7 @@ $rc = $thr->join();
9898
ok(! defined($rc), 'Exited: $thr->set_thread_exit_only');
9999

100100

101-
run_perl(prog => 'use threads 2.16 qw(exit thread_only);' .
101+
run_perl(prog => 'use threads 2.21 qw(exit thread_only);' .
102102
'threads->create(sub { exit(99); })->join();' .
103103
'exit(86);',
104104
nolib => ($ENV{PERL_CORE}) ? 0 : 1,
@@ -108,7 +108,7 @@ run_perl(prog => 'use threads 2.16 qw(exit thread_only);' .
108108
is($?>>8, 86, "'use threads 'exit' => 'thread_only'");
109109
}
110110

111-
my $out = run_perl(prog => 'use threads 2.16;' .
111+
my $out = run_perl(prog => 'use threads 2.21;' .
112112
'threads->create(sub {' .
113113
' exit(99);' .
114114
'});' .
@@ -124,7 +124,7 @@ my $out = run_perl(prog => 'use threads 2.16;' .
124124
like($out, qr/1 finished and unjoined/, "exit(status) in thread");
125125

126126

127-
$out = run_perl(prog => 'use threads 2.16 qw(exit thread_only);' .
127+
$out = run_perl(prog => 'use threads 2.21 qw(exit thread_only);' .
128128
'threads->create(sub {' .
129129
' threads->set_thread_exit_only(0);' .
130130
' exit(99);' .
@@ -141,7 +141,7 @@ $out = run_perl(prog => 'use threads 2.16 qw(exit thread_only);' .
141141
like($out, qr/1 finished and unjoined/, "set_thread_exit_only(0)");
142142

143143

144-
run_perl(prog => 'use threads 2.16;' .
144+
run_perl(prog => 'use threads 2.21;' .
145145
'threads->create(sub {' .
146146
' $SIG{__WARN__} = sub { exit(99); };' .
147147
' die();' .

dist/threads/t/kill3.t

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ BEGIN {
3636

3737
{
3838
$SIG{'KILL'} = undef;
39-
chdir '/tmp';
40-
my $dir = File::Spec->catdir( '/tmp', "toberead$$" );
39+
my $tmp = File::Spec->tmpdir();
40+
chdir $tmp;
41+
my $dir = File::Spec->catdir( $tmp, "toberead$$" );
4142
mkdir $dir;
4243
chdir $dir;
4344
for ('a'..'e') {
@@ -77,8 +78,9 @@ EOI
7778

7879
{
7980
$SIG{'KILL'} = undef;
80-
chdir '/tmp';
81-
my $dir = File::Spec->catdir( '/tmp', "shouldberead$$" );
81+
my $tmp = File::Spec->tmpdir();
82+
chdir $tmp;
83+
my $dir = File::Spec->catdir( $tmp, "shouldberead$$" );
8284
mkdir $dir;
8385
chdir $dir;
8486
for ('a'..'e') {

dist/threads/t/thread.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ package main;
161161

162162
# bugid #24165
163163

164-
run_perl(prog => 'use threads 2.16;' .
164+
run_perl(prog => 'use threads 2.21;' .
165165
'sub a{threads->create(shift)} $t = a sub{};' .
166166
'$t->tid; $t->join; $t->tid',
167167
nolib => ($ENV{PERL_CORE}) ? 0 : 1,

dist/threads/threads.xs

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#endif
2121
#ifdef HAS_PPPORT_H
2222
# define NEED_PL_signals
23+
# define NEED_newRV_noinc
2324
# define NEED_sv_2pv_flags
2425
# include "ppport.h"
2526
# include "threads.h"
@@ -35,6 +36,22 @@
3536
# endif
3637
#endif
3738

39+
#if PERL_VERSION < 28
40+
#define thread_locale_init()
41+
#define thread_locale_term()
42+
#endif
43+
44+
#ifndef CLANG_DIAG_IGNORE
45+
# define CLANG_DIAG_IGNORE(x)
46+
# define CLANG_DIAG_RESTORE
47+
#endif
48+
#ifndef CLANG_DIAG_IGNORE_STMT
49+
# define CLANG_DIAG_IGNORE_STMT(x) CLANG_DIAG_IGNORE(x) NOOP
50+
# define CLANG_DIAG_RESTORE_STMT CLANG_DIAG_RESTORE NOOP
51+
# define CLANG_DIAG_IGNORE_DECL(x) CLANG_DIAG_IGNORE(x) dNOOP
52+
# define CLANG_DIAG_RESTORE_DECL CLANG_DIAG_RESTORE dNOOP
53+
#endif
54+
3855
#ifdef USE_ITHREADS
3956

4057
#ifdef __amigaos4__
@@ -132,9 +149,9 @@ typedef struct {
132149
IV page_size;
133150
} my_pool_t;
134151

135-
#define dMY_POOL \
136-
SV *my_pool_sv = *hv_fetch(PL_modglobal, MY_POOL_KEY, \
137-
sizeof(MY_POOL_KEY)-1, TRUE); \
152+
#define dMY_POOL \
153+
SV *my_pool_sv = *hv_fetch(PL_modglobal, MY_POOL_KEY, \
154+
sizeof(MY_POOL_KEY)-1, TRUE); \
138155
my_pool_t *my_poolp = INT2PTR(my_pool_t*, SvUV(my_pool_sv))
139156

140157
#define MY_POOL_set \
@@ -219,7 +236,7 @@ S_ithread_clear(pTHX_ ithread *thread)
219236
{
220237
PerlInterpreter *interp;
221238
#ifndef WIN32
222-
sigset_t origmask;
239+
static sigset_t origmask;
223240
#endif
224241

225242
assert(((thread->state & PERL_ITHR_FINISHED) &&
@@ -583,6 +600,8 @@ S_ithread_run(void * arg)
583600
S_set_sigmask(&thread->initial_sigmask);
584601
#endif
585602

603+
thread_locale_init();
604+
586605
PL_perl_destruct_level = 2;
587606

588607
{
@@ -668,6 +687,8 @@ S_ithread_run(void * arg)
668687
MUTEX_UNLOCK(&thread->mutex);
669688
MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
670689

690+
thread_locale_term();
691+
671692
/* Exit application if required */
672693
if (exit_app) {
673694
(void)S_jmpenv_run(aTHX_ 2, thread, NULL, &exit_app, &exit_code);
@@ -884,15 +905,18 @@ S_ithread_create(
884905
reallocated (and hence move) as a side effect of calls to
885906
perl_clone() and sv_dup_inc(). Hence copy the parameters
886907
somewhere under our control first, before duplicating. */
908+
if (num_params) {
887909
#if (PERL_VERSION > 8)
888-
Copy(parent_perl->Istack_base + params_start, array, num_params, SV *);
910+
Copy(parent_perl->Istack_base + params_start, array, num_params, SV *);
889911
#else
890-
Copy(parent_perl->Tstack_base + params_start, array, num_params, SV *);
912+
Copy(parent_perl->Tstack_base + params_start, array, num_params, SV *);
891913
#endif
892-
while (num_params--) {
893-
*array = sv_dup_inc(*array, clone_param);
894-
++array;
914+
while (num_params--) {
915+
*array = sv_dup_inc(*array, clone_param);
916+
++array;
917+
}
895918
}
919+
896920
#if (PERL_VERSION > 13) || (PERL_VERSION == 13 && PERL_SUBVERSION > 1)
897921
Perl_clone_params_del(clone_param);
898922
#endif
@@ -1030,15 +1054,10 @@ S_ithread_create(
10301054
MUTEX_UNLOCK(&my_pool->create_destruct_mutex);
10311055
return (thread);
10321056

1033-
#if defined(CLANG_DIAG_IGNORE)
1034-
CLANG_DIAG_IGNORE(-Wthread-safety);
1057+
CLANG_DIAG_IGNORE_STMT(-Wthread-safety);
10351058
/* warning: mutex 'thread->mutex' is not held on every path through here [-Wthread-safety-analysis] */
1036-
#endif
10371059
}
1038-
/* perl.h defines CLANG_DIAG_* but only in 5.24+ */
1039-
#if defined(CLANG_DIAG_RESTORE)
1040-
CLANG_DIAG_RESTORE
1041-
#endif
1060+
CLANG_DIAG_RESTORE_DECL;
10421061

10431062
#endif /* USE_ITHREADS */
10441063

@@ -1161,6 +1180,7 @@ ithread_create(...)
11611180
}
11621181

11631182
/* Create thread */
1183+
/* Unlocked inside S_ithread_create */
11641184
MUTEX_LOCK(&MY_POOL.create_destruct_mutex);
11651185
thread = S_ithread_create(aTHX_ &MY_POOL,
11661186
function_to_call,
@@ -1176,10 +1196,10 @@ ithread_create(...)
11761196

11771197
/* Let thread run. */
11781198
/* See S_ithread_run() for more detail. */
1179-
CLANG_DIAG_IGNORE(-Wthread-safety);
1199+
CLANG_DIAG_IGNORE_STMT(-Wthread-safety);
11801200
/* warning: releasing mutex 'thread->mutex' that was not held [-Wthread-safety-analysis] */
11811201
MUTEX_UNLOCK(&thread->mutex);
1182-
CLANG_DIAG_RESTORE;
1202+
CLANG_DIAG_RESTORE_STMT;
11831203

11841204
/* XSRETURN(1); - implied */
11851205

@@ -1374,6 +1394,9 @@ ithread_join(...)
13741394
ptr_table_store(PL_ptr_table, &other_perl->Isv_undef, &PL_sv_undef);
13751395
ptr_table_store(PL_ptr_table, &other_perl->Isv_no, &PL_sv_no);
13761396
ptr_table_store(PL_ptr_table, &other_perl->Isv_yes, &PL_sv_yes);
1397+
# ifdef PL_sv_zero
1398+
ptr_table_store(PL_ptr_table, &other_perl->Isv_zero, &PL_sv_zero);
1399+
# endif
13771400
params = (AV *)sv_dup((SV*)params_copy, clone_params);
13781401
S_ithread_set(aTHX_ current_thread);
13791402
Perl_clone_params_del(clone_params);
@@ -1802,6 +1825,9 @@ ithread_error(...)
18021825
ptr_table_store(PL_ptr_table, &other_perl->Isv_undef, &PL_sv_undef);
18031826
ptr_table_store(PL_ptr_table, &other_perl->Isv_no, &PL_sv_no);
18041827
ptr_table_store(PL_ptr_table, &other_perl->Isv_yes, &PL_sv_yes);
1828+
# ifdef PL_sv_zero
1829+
ptr_table_store(PL_ptr_table, &other_perl->Isv_zero, &PL_sv_zero);
1830+
# endif
18051831
err = sv_dup(thread->err, clone_params);
18061832
S_ithread_set(aTHX_ current_thread);
18071833
Perl_clone_params_del(clone_params);
@@ -1834,7 +1860,6 @@ BOOT:
18341860
SV *my_pool_sv = *hv_fetch(PL_modglobal, MY_POOL_KEY,
18351861
sizeof(MY_POOL_KEY)-1, TRUE);
18361862
my_pool_t *my_poolp = (my_pool_t*)SvPVX(newSV(sizeof(my_pool_t)-1));
1837-
18381863
MY_CXT_INIT;
18391864

18401865
Zero(my_poolp, 1, my_pool_t);

0 commit comments

Comments
 (0)