The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl -w
use strict;
use Test::More;

# Note that the strategy for testing for thread failure here is not very good.
# It is very timing dependent. On some systems this test will pass even with a parser
# that is not thread safe. There is some amount of luck in getting the non-thread safe
# code to crash. As it is now, the test below sucessfully crashes version 0.45 of XML::Bare
# seemingly every time I run the test.

my $threads_ok = 0;
eval("use threads;");
if( !$@ ) { $threads_ok = 1; }

my $shared_ok = 0;
if( $threads_ok ) {
    eval("use threads::shared;");
    if( !$@ ) { $shared_ok = 1; }
}

my $numok = 0;

if( !$threads_ok || !$shared_ok ) {
     plan skip_all => 'Cannot load threads and/or threads::shared; skipping multithreading tests';
}
else {
    #plan 'no_plan';
    plan tests => 2;
    use_ok( 'XML::Bare' );
    threads::shared::share( \$numok );
    for( my $i=0;$i<20;$i++ ) {
        threads->create( \&single );
    }
    while( 1 ) {
        my @joinable = threads->list(0);#joinable
        my @running = threads->list(1);#running
        
        for my $thr ( @joinable ) { $thr->join(); }
        last if( !@running );
        sleep(1);
    }
    is( $numok, 20, 'All threads completed okay' );
}

sub single {
    my $xml = '<xml>';
    my @arr;
    for( my $i=0;$i<4000;$i++ ) {
        my $n = rand(1000);
        $arr[ $i ] = $n;
        $xml .= "<node><n>$n</n></node>";
    }
    $xml .= "</xml>";
    my ( $ob, $root ) = XML::Bare->new( text => $xml );
    $root = $root->{'xml'};
    my $nodes = $root->{'node'};
    my $ok = 1;
    my $i = 0;
    for my $node ( @$nodes ) {
        my $n = $node->{'n'}{'value'};
        $ok = 0 if( $n ne $arr[ $i ] ); # note ne here instead of !=. Because $a=405.69280607542502; $a!="$a"; But $a=405.69280607542501; $a=="$a"; :(
        $i++;
    }
    @arr = ();
    
    return if( !$ok );
    
    {
        lock( $numok );
        $numok++;
    }
}