Ok, there is more than one way to do it. But IMHO the simplest is to use Coro.
Here is quick example
use strict;
use Coro;
use Coro::Socket;
use Coro::Handle;
use Coro::PatchSet;
my @clients;
pipe(my $reader, my $writer);
defined( my $child = fork )
or die 'fork: ', $!;
if ($child == 0) {
close $reader;
sub blocking_receive_function {
sleep 1;
return "test\n";
}
while (1) {
my $str = blocking_receive_function();
syswrite($writer, $str);
}
exit;
}
close $writer;
$reader = unblock $reader; # make it Coro aware
async_pool {
# thread for reading blocking_receive_function results
# and write it to clients
while (1) {
my $line = $reader->readline();
for (my $i=$#clients; $i>=0; $i--) {
unless (defined $clients[$i]->syswrite($line)) {
# some error
# we need to do smth
# let's remove this client
warn "Error on $clients[$i]: $!";
splice @clients, $i, 1;
}
}
}
}
my $server = Coro::Socket->new(Listen => 1024, LocalPort => 8000)
or die "Can't create server", $@;
while (1) {
my $client = $server->accept()
or next;
push @clients, $client;
}