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

Alright, so in looking deeper at the warnings I am receiving it seems as though windows is likely reusing the OS level filehandle I am pulling out from under the Perl handle via my hardclose logic.

Then when perl implicitly closes the Perl handle it is closing whatever ended up reusing that OS handle causing unspecified behavior.

So perhaps to avoid this I should ask for assistance in accomplishing my goal.

I want to spawn a thread then close a handle that was open in the main thread prior to the creation of the thread. In experimenting with this I was not able to have the process actually release the OS file handle. I don't remember the details, but I was not able to call close from both the main thread and "child" thread.
  • Comment on Re^2: Perl jumps to END logic after fileno (Win32)

Replies are listed 'Best First'.
Re^3: Perl jumps to END logic after fileno (Win32)
by Anonymous Monk on Aug 09, 2017 at 23:49 UTC

    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

      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