Subject: | Http::Headers not thread safe due to perl sort bug |
libwww-perl-5.800. perl version 5.8.4.
This is a threads-related crash; it affects both Windows and Unix,
but is more common on Windows because fork is emulated via threads.
I was getting random crashes in a forking LWP program on Windows.
The root cause of the crashes turns out to be a perl bug in pp_sort
as described in perl bug #30333 "threads sort crashes with sort
subroutine (but not with sort block)".
Because this perl bug presumably goes way back to many earlier perl
versions, it seems best to work around it in HTTP/Headers.pm.
I did a search of all libwww code and the only place that uses a
sort subroutine is Headers.pm.
In Headers.pm, the _header_cmp subroutine is used in only two places
(both as a sort subroutine). The attached patch inlines _header_cmp
as a sort block to work around perl bug #30333.
/-\
--- lib/HTTP/Headers.pm.orig 2004-06-29 12:27:26.000000000 +1000
+++ lib/HTTP/Headers.pm 2004-06-29 12:31:42.000000000 +1000
@@ -177,15 +177,17 @@
# Compare function which makes it easy to sort headers in the
# recommended "Good Practice" order.
-sub _header_cmp
-{
- ($header_order{$a} || 999) <=> ($header_order{$b} || 999) || $a cmp $b;
-}
+# Inline this function in two places below to work around perl sort
+# multi-threading bug #30333.
+# sub _header_cmp
+# {
+# ($header_order{$a} || 999) <=> ($header_order{$b} || 999) || $a cmp $b;
+# }
sub header_field_names {
my $self = shift;
- return map $standard_case{$_} || $_, sort _header_cmp keys %$self
+ return map $standard_case{$_} || $_, sort { ($header_order{$a} || 999) <=> ($header_order{$b} || 999) || $a cmp $b } keys %$self
if wantarray;
return keys %$self;
}
@@ -195,7 +197,7 @@
{
my($self, $sub) = @_;
my $key;
- foreach $key (sort _header_cmp keys %$self) {
+ foreach $key (sort { ($header_order{$a} || 999) <=> ($header_order{$b} || 999) || $a cmp $b } keys %$self) {
next if $key =~ /^_/;
my $vals = $self->{$key};
if (ref($vals) eq 'ARRAY') {