sub Run { my $self = $_[0]; my( $server, $Qwork, $Qclean, $accept ) = @{ $self }{ qw[ Socket Qwork Qclean Accept ] }; while( local $_ = $server->accept ) { my $fileno = fileno $_; $self->{ Clients }{ $fileno } = $_; my $clientArgs = eval{ join chr(0), $accept->() } || ''; $Qwork->enqueue( "$fileno\0$clientArgs" ); while( my $fno = $Qclean->dequeue() ) { #warnf "Cleanup of %d\n", $fno; close delete $self->{ Clients }{ $fno }; } } } sub _thread { #warnf "Starting thread %d\n", threads->tid; my( $userCode, $Qwork, $Qin, $Qclean ) = @_; while( my $work = $Qwork->dequeue() ) { my( $fileno, @args ) = split chr(0), $work; open my $client, '+<&=' . $fileno or cluck "Failed to dup $fileno in ${ \threads->tid } : $!\n" and next; $Qclean->enqueue( $fileno ); $userCode->( $client, $Qin, @args ); close $client; } }