in reply to Re^2: Perl jumps to END logic after fileno (Win32)
in thread Perl jumps to END logic after fileno (Win32)

Hi,

What?

#!/usr/bin/perl -- use strict; use warnings; use autodie qw/ open close /; use threads stack_size => 4096; open FOO, '<', __FILE__ or die $!; if( @ARGV ){ #~ threads->create(sub { use autodie qw/ close /; close FOO; })->d +etach; threads->create(sub { close FOO; })->join; threads->create(sub { close FOO; ## close FOO; ## this one autodies, "terminated abnormally:" eval { close FOO; 1 } or warn $@; return; })->join; close FOO; close FOO; ## this one autodies } else { close FOO; close FOO; ## this one autodies } __END__ $ perl threads-close-filehandle.pl Can't close filehandle 'FOO': 'Bad file descriptor' at threads-close-f +ilehandle.pl line 22 $ perl threads-close-filehandle.pl 1 Can't close filehandle 'FOO': 'Bad file descriptor' at threads-close-f +ilehandle.pl line 15 Can't close filehandle 'FOO': 'Bad file descriptor' at threads-close-f +ilehandle.pl line 19

Replies are listed 'Best First'.
Re^4: Perl jumps to END logic after fileno (Win32)
by dchidelf (Novice) on Aug 10, 2017 at 18:41 UTC

    Thanks. At first I was responding with "it's not that easy", but this actually seems like it might have helped.

    I am creating the threads from within a "constructor" in a package and need to close a file handle that is being assigned to a scalar rather than a type glob. Since the scalar is scoped to the scope of the subroutine and the thread logic was outside of that function I was attempting to pass the handle as an argument to the thread, which fails in various ways.

    If I declare the thread logic in an anonymous sub nested inside the "constructor" it seems like I will be able to just reference the scalar within that same scope and be able to close the copy that gets dup'd into the new thread.

    Test mockup works, I just need to test it with pipes and all the other details

    #!/usr/bin/perl -- use strict; use warnings; use autodie qw/ open close /; use threads stack_size => 4096; package test; sub doit { my $self = {}; my $FOO; open $FOO, '<', 'WISDOM.ico' or die $!; my $threadcode = sub { close $FOO; eval { close $FOO; 1 } or warn $@; sleep 60; return; }; $self->{'th'} = threads->create($threadcode); close $FOO; eval { close $FOO; 1 } or warn $@; bless $self; } sub joinit { my ($self) = @_; my $th = $self->{'th'}; $th->join(); } my $t = test::doit(); print "thread created\n"; # OS Tests here indicate the file descriptor is closed $t->joinit(); print "thread ended\n"; sleep 100;

      Since the scalar is scoped to the scope of the subroutine and the thread logic was outside of that function I was attempting to pass the handle as an argument to the thread, which fails in various ways.

      Hi, to me it seems like it works the same way, just no globals or no closures

      #!/usr/bin/perl -- use strict; use warnings; use autodie qw/ open close /; use threads stack_size => 4096; { open my $fh, '<', __FILE__; threads->create(\&close_once, $fh )->join; threads->create(\&close_twice, $fh )->join; close $fh; close $fh; ## 11 } sub close_once { my( $fh ) = @_; close $fh; } sub close_twice { my( $fh ) = @_; close $fh; eval { close $fh; 1 } or warn $@; ## 20 return; } __END__ Can't close(GLOB(0xc38d6c)) filehandle: 'Bad file descriptor' at threa +ds-close-filehandle-LEXICAL.pl line 20 Can't close(GLOB(0x99b26c)) filehandle: 'Bad file descriptor' at threa +ds-close-filehandle-LEXICAL.pl line 11