Skip Menu |

This queue is for tickets about the libwww-perl CPAN distribution.

Report information
The Basics
Id: 6781
Status: resolved
Priority: 0/
Queue: libwww-perl

People
Owner: Nobody in particular
Requestors: ajsavige [...] yahoo.com.au
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: (no value)



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') {