Change 34048 by [EMAIL PROTECTED] on 2008/06/13 17:09:19
Subject: [PATCH - revised] threads 1.71
From: "Jerry D. Hedden" <[EMAIL PROTECTED]>
Date: Thu, 12 Jun 2008 08:42:19 -0400
Message-ID: <[EMAIL PROTECTED]>
Affected files ...
... //depot/perl/ext/threads/Makefile.PL#17 edit
... //depot/perl/ext/threads/t/basic.t#23 edit
... //depot/perl/ext/threads/t/blocks.t#6 edit
... //depot/perl/ext/threads/t/context.t#7 edit
... //depot/perl/ext/threads/t/end.t#12 edit
... //depot/perl/ext/threads/t/err.t#3 edit
... //depot/perl/ext/threads/t/exit.t#24 edit
... //depot/perl/ext/threads/t/free.t#9 edit
... //depot/perl/ext/threads/t/free2.t#7 edit
... //depot/perl/ext/threads/t/join.t#28 edit
... //depot/perl/ext/threads/t/kill.t#9 edit
... //depot/perl/ext/threads/t/libc.t#10 edit
... //depot/perl/ext/threads/t/list.t#11 edit
... //depot/perl/ext/threads/t/problems.t#21 edit
... //depot/perl/ext/threads/t/stack.t#4 edit
... //depot/perl/ext/threads/t/stack_env.t#3 edit
... //depot/perl/ext/threads/t/state.t#5 edit
... //depot/perl/ext/threads/t/stress_cv.t#6 edit
... //depot/perl/ext/threads/t/stress_re.t#8 edit
... //depot/perl/ext/threads/t/stress_string.t#8 edit
... //depot/perl/ext/threads/t/thread.t#50 edit
... //depot/perl/ext/threads/threads.pm#95 edit
Differences ...
==== //depot/perl/ext/threads/Makefile.PL#17 (xtext) ====
Index: perl/ext/threads/Makefile.PL
--- perl/ext/threads/Makefile.PL#16~33359~ 2008-02-24 22:45:05.000000000
-0800
+++ perl/ext/threads/Makefile.PL 2008-06-13 10:09:19.000000000 -0700
@@ -55,7 +55,7 @@
# Verify that a 'C' compiler is available
if (! have_cc()) {
- die("No 'C' compiler found to build 'threads'\n");
+ die("OS unsupported: ERROR: No 'C' compiler found to build
'threads'\n");
}
push(@conditional_params, 'DEFINE' => '-DHAS_PPPORT_H',
==== //depot/perl/ext/threads/t/basic.t#23 (xtext) ====
Index: perl/ext/threads/t/basic.t
--- perl/ext/threads/t/basic.t#22~31687~ 2007-08-08 09:43:49.000000000
-0700
+++ perl/ext/threads/t/basic.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -165,4 +165,6 @@
ok(33, "$thr1" eq $thr1->tid(), 'Stringify');
$thr1->join();
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/blocks.t#6 (text) ====
Index: perl/ext/threads/t/blocks.t
--- perl/ext/threads/t/blocks.t#5~31687~ 2007-08-08 09:43:49.000000000
-0700
+++ perl/ext/threads/t/blocks.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -23,7 +23,7 @@
threads::shared->import();
};
if ($@ || ! $threads::shared::threads_shared) {
- print("1..0 # Skip: threads::shared not available\n");
+ print("1..0 # SKIP threads::shared not available\n");
exit(0);
}
@@ -123,4 +123,6 @@
redo if ($COUNT < $TOTAL);
}
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/context.t#7 (text) ====
Index: perl/ext/threads/t/context.t
--- perl/ext/threads/t/context.t#6~31687~ 2007-08-08 09:43:49.000000000
-0700
+++ perl/ext/threads/t/context.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -23,7 +23,7 @@
threads::shared->import();
};
if ($@ || ! $threads::shared::threads_shared) {
- print("1..0 # Skip: threads::shared not available\n");
+ print("1..0 # SKIP threads::shared not available\n");
exit(0);
}
@@ -156,4 +156,6 @@
$res = $thr->join();
ok(! defined($res), 'Explicit void context');
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/end.t#12 (text) ====
Index: perl/ext/threads/t/end.t
--- perl/ext/threads/t/end.t#11~31687~ 2007-08-08 09:43:49.000000000 -0700
+++ perl/ext/threads/t/end.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -23,7 +23,7 @@
threads::shared->import();
};
if ($@ || ! $threads::shared::threads_shared) {
- print("1..0 # Skip: threads::shared not available\n");
+ print("1..0 # SKIP threads::shared not available\n");
exit(0);
}
@@ -75,4 +75,6 @@
}
threads->create(\&thread)->join();
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/err.t#3 (text) ====
Index: perl/ext/threads/t/err.t
--- perl/ext/threads/t/err.t#2~29563~ 2006-12-16 02:03:23.000000000 -0800
+++ perl/ext/threads/t/err.t 2008-06-13 10:09:19.000000000 -0700
@@ -67,4 +67,6 @@
isa_ok($err, 'Foo', 'error object');
is($err->{error}, 'bogus', 'error field');
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/exit.t#24 (text) ====
Index: perl/ext/threads/t/exit.t
--- perl/ext/threads/t/exit.t#23~33359~ 2008-02-24 22:45:05.000000000 -0800
+++ perl/ext/threads/t/exit.t 2008-06-13 10:09:19.000000000 -0700
@@ -57,7 +57,7 @@
ok(! defined($rc), 'Exited: threads->exit()');
-run_perl(prog => 'use threads 1.69;' .
+run_perl(prog => 'use threads 1.71;' .
'threads->exit(86);' .
'exit(99);',
nolib => ($ENV{PERL_CORE}) ? 0 : 1,
@@ -107,7 +107,7 @@
ok(! defined($rc), 'Exited: $thr->set_thread_exit_only');
-run_perl(prog => 'use threads 1.69 qw(exit thread_only);' .
+run_perl(prog => 'use threads 1.71 qw(exit thread_only);' .
'threads->create(sub { exit(99); })->join();' .
'exit(86);',
nolib => ($ENV{PERL_CORE}) ? 0 : 1,
@@ -117,7 +117,7 @@
is($?>>8, 86, "'use threads 'exit' => 'thread_only'");
}
-my $out = run_perl(prog => 'use threads 1.69;' .
+my $out = run_perl(prog => 'use threads 1.71;' .
'threads->create(sub {' .
' exit(99);' .
'});' .
@@ -133,7 +133,7 @@
like($out, '1 finished and unjoined', "exit(status) in thread");
-$out = run_perl(prog => 'use threads 1.69 qw(exit thread_only);' .
+$out = run_perl(prog => 'use threads 1.71 qw(exit thread_only);' .
'threads->create(sub {' .
' threads->set_thread_exit_only(0);' .
' exit(99);' .
@@ -150,7 +150,7 @@
like($out, '1 finished and unjoined', "set_thread_exit_only(0)");
-run_perl(prog => 'use threads 1.69;' .
+run_perl(prog => 'use threads 1.71;' .
'threads->create(sub {' .
' $SIG{__WARN__} = sub { exit(99); };' .
' die();' .
@@ -172,4 +172,6 @@
$rc = $thr->join();
ok(! defined($rc), 'Exited: threads->exit() in thread warn handler');
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/free.t#9 (text) ====
Index: perl/ext/threads/t/free.t
--- perl/ext/threads/t/free.t#8~31687~ 2007-08-08 09:43:49.000000000 -0700
+++ perl/ext/threads/t/free.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -23,7 +23,7 @@
threads::shared->import();
};
if ($@ || ! $threads::shared::threads_shared) {
- print("1..0 # Skip: threads::shared not available\n");
+ print("1..0 # SKIP threads::shared not available\n");
exit(0);
}
@@ -212,4 +212,6 @@
}
ok($COUNT == 2, "Done - $COUNT threads");
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/free2.t#7 (text) ====
Index: perl/ext/threads/t/free2.t
--- perl/ext/threads/t/free2.t#6~31687~ 2007-08-08 09:43:49.000000000 -0700
+++ perl/ext/threads/t/free2.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -23,12 +23,12 @@
threads::shared->import();
};
if ($@ || ! $threads::shared::threads_shared) {
- print("1..0 # Skip: threads::shared not available\n");
+ print("1..0 # SKIP threads::shared not available\n");
exit(0);
}
if (($] < 5.008002) && ($threads::shared::VERSION < 0.92)) {
- print("1..0 # Skip: Needs threads::shared 0.92 or later\n");
+ print("1..0 # SKIP Needs threads::shared 0.92 or later\n");
exit(0);
}
@@ -336,4 +336,6 @@
}
ok($COUNT == 17, "Done - $COUNT threads");
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/join.t#28 (text) ====
Index: perl/ext/threads/t/join.t
--- perl/ext/threads/t/join.t#27~33359~ 2008-02-24 22:45:05.000000000 -0800
+++ perl/ext/threads/t/join.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -23,7 +23,7 @@
threads::shared->import();
};
if ($@ || ! $threads::shared::threads_shared) {
- print("1..0 # Skip: threads::shared not available\n");
+ print("1..0 # SKIP threads::shared not available\n");
exit(0);
}
@@ -57,7 +57,7 @@
}
sub skip {
- ok(1, '# skip: ' . $_[0]);
+ ok(1, '# SKIP ' . $_[0]);
}
@@ -228,4 +228,6 @@
$joiner->join;
}
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/kill.t#9 (text) ====
Index: perl/ext/threads/t/kill.t
--- perl/ext/threads/t/kill.t#8~31687~ 2007-08-08 09:43:49.000000000 -0700
+++ perl/ext/threads/t/kill.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -23,7 +23,7 @@
threads::shared->import();
};
if ($@ || ! $threads::shared::threads_shared) {
- print("1..0 # Skip: threads::shared not available\n");
+ print("1..0 # SKIP threads::shared not available\n");
exit(0);
}
@@ -32,7 +32,7 @@
eval { $thr->kill('HUP') };
$thr->join();
if ($@ && $@ =~ /safe signals/) {
- print("1..0 # Skip: Not using safe signals\n");
+ print("1..0 # SKIP Not using safe signals\n");
exit(0);
}
@@ -175,4 +175,6 @@
ok($thr->kill('TERM') == $thr, 'Ignore signal to terminated thread');
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/libc.t#10 (text) ====
Index: perl/ext/threads/t/libc.t
--- perl/ext/threads/t/libc.t#9~29557~ 2006-12-15 02:14:16.000000000 -0800
+++ perl/ext/threads/t/libc.t 2008-06-13 10:09:19.000000000 -0700
@@ -51,4 +51,6 @@
is($threads[$_]->join(), 0, 'localtime() thread-safe');
}
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/list.t#11 (text) ====
Index: perl/ext/threads/t/list.t
--- perl/ext/threads/t/list.t#10~28099~ 2006-05-04 05:51:51.000000000 -0700
+++ perl/ext/threads/t/list.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -69,4 +69,6 @@
ok(14, scalar @{[threads->list()]} == 0, 'Thread list empty');
ok(15, threads->list() == 0, 'Thread list empty');
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/problems.t#21 (text) ====
Index: perl/ext/threads/t/problems.t
--- perl/ext/threads/t/problems.t#20~33359~ 2008-02-24 22:45:05.000000000
-0800
+++ perl/ext/threads/t/problems.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -23,7 +23,7 @@
threads::shared->import();
};
if ($@ || ! $threads::shared::threads_shared) {
- print("1..0 # Skip: threads::shared not available\n");
+ print("1..0 # SKIP threads::shared not available\n");
exit(0);
}
@@ -95,7 +95,7 @@
my $not = eval { Config::myconfig() } ? '' : 'not ';
print "${not}ok $test - Are we able to call Config::myconfig after
clone\n";
} else {
- print "ok $test # skip: Are we able to call Config::myconfig after
clone\n";
+ print "ok $test # SKIP Are we able to call Config::myconfig after
clone\n";
}
$test++;
}
@@ -123,7 +123,7 @@
print $@ =~ /disallowed/
? '' : 'not ', "ok $test # TODO $TODO - unique_hash\n";
} else {
- print("ok $test # skip: $TODO - unique_hash\n");
+ print("ok $test # SKIP $TODO - unique_hash\n");
}
$test++;
})->join;
@@ -138,7 +138,7 @@
print $@ =~ /^The 'unique' attribute may only be applied to 'our'
variables/
? '' : 'not ', "ok $test - $decl\n";
} else {
- print("ok $test # skip: $decl\n");
+ print("ok $test # SKIP $decl\n");
}
$test++;
}
@@ -178,4 +178,6 @@
$child = threads->create(sub { return (scalar(keys(%h))); })->join;
is($child, 1, "keys correct in child with restricted hash");
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/stack.t#4 (text) ====
Index: perl/ext/threads/t/stack.t
--- perl/ext/threads/t/stack.t#3~31516~ 2007-07-02 06:17:26.000000000 -0700
+++ perl/ext/threads/t/stack.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -102,4 +102,6 @@
ok(18, threads->get_stack_size() == 160*4096,
'Default thread sized changed in thread');
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/stack_env.t#3 (text) ====
Index: perl/ext/threads/t/stack_env.t
--- perl/ext/threads/t/stack_env.t#2~31516~ 2007-07-02 06:17:26.000000000
-0700
+++ perl/ext/threads/t/stack_env.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -48,4 +48,6 @@
ok(4, threads->get_stack_size() == 144*4096,
'Get stack size');
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/state.t#5 (text) ====
Index: perl/ext/threads/t/state.t
--- perl/ext/threads/t/state.t#4~31687~ 2007-08-08 09:43:49.000000000 -0700
+++ perl/ext/threads/t/state.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -23,7 +23,7 @@
threads::shared->import();
};
if ($@ || ! $threads::shared::threads_shared) {
- print("1..0 # Skip: threads::shared not available\n");
+ print("1..0 # SKIP threads::shared not available\n");
exit(0);
}
@@ -263,4 +263,6 @@
for (threads->list) { $_->join; }
}
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/stress_cv.t#6 (text) ====
Index: perl/ext/threads/t/stress_cv.t
--- perl/ext/threads/t/stress_cv.t#5~31516~ 2007-07-02 06:17:26.000000000
-0700
+++ perl/ext/threads/t/stress_cv.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -58,4 +58,6 @@
ok($thr, "Thread joined - iter $_");
}
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/stress_re.t#8 (text) ====
Index: perl/ext/threads/t/stress_re.t
--- perl/ext/threads/t/stress_re.t#7~31516~ 2007-07-02 06:17:26.000000000
-0700
+++ perl/ext/threads/t/stress_re.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -64,4 +64,6 @@
ok($thr && defined($result) && ($result eq 'ok'), "Thread joined - iter
$_");
}
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/stress_string.t#8 (text) ====
Index: perl/ext/threads/t/stress_string.t
--- perl/ext/threads/t/stress_string.t#7~31516~ 2007-07-02 06:17:26.000000000
-0700
+++ perl/ext/threads/t/stress_string.t 2008-06-13 10:09:19.000000000 -0700
@@ -8,7 +8,7 @@
}
use Config;
if (! $Config{'useithreads'}) {
- print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
+ print("1..0 # SKIP Perl not compiled with 'useithreads'\n");
exit(0);
}
}
@@ -62,4 +62,6 @@
ok($thr, "Thread joined - iter $_");
}
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/t/thread.t#50 (text) ====
Index: perl/ext/threads/t/thread.t
--- perl/ext/threads/t/thread.t#49~33359~ 2008-02-24 22:45:05.000000000
-0800
+++ perl/ext/threads/t/thread.t 2008-06-13 10:09:19.000000000 -0700
@@ -170,7 +170,7 @@
# bugid #24165
-run_perl(prog => 'use threads 1.69;' .
+run_perl(prog => 'use threads 1.71;' .
'sub a{threads->create(shift)} $t = a sub{};' .
'$t->tid; $t->join; $t->tid',
nolib => ($ENV{PERL_CORE}) ? 0 : 1,
@@ -313,4 +313,6 @@
"counts of calls to DESTROY");
}
+exit(0);
+
# EOF
==== //depot/perl/ext/threads/threads.pm#95 (xtext) ====
Index: perl/ext/threads/threads.pm
--- perl/ext/threads/threads.pm#94~33359~ 2008-02-24 22:45:05.000000000
-0800
+++ perl/ext/threads/threads.pm 2008-06-13 10:09:19.000000000 -0700
@@ -5,7 +5,7 @@
use strict;
use warnings;
-our $VERSION = '1.69';
+our $VERSION = '1.71';
my $XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
@@ -134,7 +134,7 @@
=head1 VERSION
-This document describes threads version 1.69
+This document describes threads version 1.71
=head1 SYNOPSIS
@@ -967,6 +967,21 @@
later, and if the class supports L<shared objects|threads::shared/"OBJECTS">,
you can pass them via L<shared queues| Thread::Queue>.
+=item END blocks in threads
+
+It is possible to add L<END blocks|perlmod/"BEGIN, UNITCHECK, CHECK, INIT and
+END"> to threads by using L<require|perlfunc/"require VERSION"> or
+L<eval|perlfunc/"eval EXPR"> with the appropriate code. These C<END> blocks
+will then be executed when the thread's interpreter is destroyed (i.e., either
+during a C<-E<gt>join()> call, or at program termination).
+
+However, calling any L<threads> methods in such an C<END> block will most
+likely I<fail> (e.g., the application may hang, or generate an error) due to
+mutexes that are needed to control functionality within the L<threads> module.
+
+For this reason, the use of C<END> blocks in threads is B<strongly>
+discouraged.
+
=item Perl Bugs and the CPAN Version of L<threads>
Support for threads extends beyond the code in this module (i.e.,
@@ -996,7 +1011,7 @@
L<http://www.cpanforum.com/dist/threads>
Annotated POD for L<threads>:
-L<http://annocpan.org/~JDHEDDEN/threads-1.69/threads.pm>
+L<http://annocpan.org/~JDHEDDEN/threads-1.71/threads.pm>
Source repository:
L<http://code.google.com/p/threads-shared/>
@@ -1016,10 +1031,12 @@
Artur Bergman E<lt>sky AT crucially DOT netE<gt>
-threads is released under the same license as Perl.
-
CPAN version produced by Jerry D. Hedden <jdhedden AT cpan DOT org>
+=head1 LICENSE
+
+threads is released under the same license as Perl.
+
=head1 ACKNOWLEDGEMENTS
Richard Soderberg E<lt>perl AT crystalflame DOT netE<gt> -
End of Patch.