I have a task where I'm waiting for connections in one thread and forward them to another thread. Maybe I something misunderstood but why I cannot reopen file descriptor in main thread?
Very simplified code:
sub inthread {
$socket = new IO::Socket::INET ( ... );
# ...
while ( my $client = $socket->accept() ) {
#if i print STDOUT, (fileno $client); # there i'll get 4
push ( @shared, fileno $client);
}
}
sub mainthread {
if ( scalar @shared ) {
$fd = shift @shared;
# if i print (fileno $fd); # there i'll get 4
open my $f, "<&=$fd" or die " error $!"; ### error here: Can't open 4: Bad file descriptor
while ( <$f> ) { ... }
}
}
threads->create(\&inthread);
while(1) { mainthread; }
whole code is there http://dpaste.com/3381RKV
test:
perl -w ./testcode.pl --port=10102 & wget -O - http://127.0.0.1:10102/
my $client
creates a variable scoped to the loop body. And the end of the pass, the last reference to the contained handle is relinquished, freeing the file handle, which closes the associated file descriptor.[1]
This happens before the other thread reaches open <&=
, so the file descriptor is no longer valid when you try to create a new file handle for it.
Self-contained demonstration:
#!/usr/bin/perl
use strict;
use warnings;
my $fd;
{
open(my $fh, '<', $0)
or die($!);
$fd = fileno($fh);
} # File handle closed here.
{
open(my $fh, '<&=', $fd)
or die($!); # Bad file descriptor
}
You'll have to ensure that the file handle doesn't get closed prematurely. You could store them in an array or hash keyed by fd, and the other thread could let the parent thread know which handles it no longer needs via another shared structure.
close $client;
.