in reply to Re: "Too Many Files Open" problem
in thread "Too Many Files Open" problem

Hi

All I have to say is eew, you made me look inside Audio::Wav :) all that Inline::C noise is ridiculous

I can confirm this is a bug in Audio::Wav, its not closing the filehandles, in both the ridiculous Inline::C version and the pure-perl version, because of circular references (a closure, mentioned in Changes file)

If you add

use DDS; exit print "\n\n", Dump( { readwav => $readwav, read => $read +, src_details => $src_details } );
You can see the "closure"
my ($block,$channels,$handle,$self); $block = 1; $channels = 1; $handle = bless( do{ require Symbol; Symbol::gensym }, 'FileHandle' ); $self = bless( { data => { bits_sample => 8, block_align => 1, bytes_sec => 8000, channels => 1, cue => { 1 => { bstart => 0, chunk => 'data', cstart => 0, offset => 2179, position => 2179 } }, data_finish => 4044, data_length => 4000, data_start => 44, labl => { 1 => 'Cue 1' }, length => 0.5, note => { 1 => 'cue point' }, sample_rate => 8000, total_length => 4152, "wave-ex" => 0 }, file => '...Audio-Wav-0.12\\xt/../test_tone.wav', handle => $handle, pos => 44, read_sub => sub { package Audio::Wav::Read; use strict 'refs'; my $val; ## THIS IS THE CLOSURE, the reference to $handle lives forever $$self{'pos'} += read($handle, $val, $block); return unless defined $val; return map(($_ - 128), unpack('C' . $channels, +$val)); }, read_sub_string => "\n sub {\n my \$val;\n + \$self -> {'pos'} += read". "( \$handle, \$val, \$block );\n return unless defined +\$val;\n ". " return map \$_ - 128, unpack( 'C'.\$channels, \$val ); \n + };\n". " ", real_size => 4160, tools => bless( { ".01compatible" => 0, debug => 0, errorHandler => undef, oldcooledithack => 0 }, 'Audio::Wav::Tools' ) }, 'Audio::Wav::Read' ); $HASH1 = { read => $self, readwav => bless( { tools => $self->{tools} }, 'Audio:: +Wav' ), src_details => $self->{data} };

I'd offer a fix, but I'm just so disgusted, report to author :)

as a workaround you can use      $read->{handle}->close; in your loop

my  Audio-Wav-0.12\xt\bug.filehandles.t based on your program

#!/usr/bin/perl -- BEGIN { use File::Spec; use File::Basename qw' dirname '; our $thisf = File::Spec->rel2abs(__FILE__); our $thisd = dirname($thisf); } use Audio::Wav; my $wav = "$thisd/../test_tone.wav"; $Audio::Wav::_has_inline ||= $ENV{'--useInlineCanyway'}; $Audio::Wav::_has_inline ||= grep /--useInlineCanyway/ , @ARGV; warn "Audio::Wav::_has_inline => $Audio::Wav::_has_inline \n"; $|=1; eval { for my $ix ( 1 .. ( 2045 + 10 ) ){ print "\r$ix "; print "\n" if $ix > 2044; my $readwav = new Audio::Wav; my $read = $readwav -> read( $wav ); my $src_details = $read -> details(); ## $read->{handle}->close; ## workaround $readwav = undef; $read = undef; } } or warn $@; system qw[ D:/sysinternals/SysinternalsSuite/handle.exe -p ], $$; __END__

Replies are listed 'Best First'.
Re^3: "Too Many Files Open" problem
by Anonymous Monk on Jan 07, 2012 at 15:58 UTC

    That did it!

    You have my deepest thanks. I spent a long time banging my head against a wall thinking I must be missing something really dumb. I never would have solved this without your help...