Instead of implementing a limited cooperative multitasking system using select, it's simpler to use threads or Coro.
The following is the Coro equivalent of the code in the parent post.
#!/usr/bin/perl
use strict;
use warnings;
use Coro qw( async );
use IO::Socket::INET qw( );
sub _read {
my $rv = read($_[0], $_[1], $_[2], $_[3]||0);
die("Read error\n") if !defined($rv);
return if !$rv;
die("Premature end of file\n") if $rv != $_[1];
}
sub client {
my ($sock) = @_;
my $host = $client->peerhost;
print "[Accepted connection from $host]\n";
if (defined(eval {
for (;;) {
_read($sock, 8, my $buf = '')
or last;
my $length = 0+$buf
or next;
_read($sock, $length, my $msg = '')
or die("Premature end of file\n");
print "$host said '$msg'\n";
}
})) {
print "[Connection from $host terminated]\n";
} else {
print "[Connection from $host terminated: $@]\n";
}
}
my $server = IO::Socket::INET->new(
...
) or die("Couldn't create server socket: $!\n");
async(\&client, $server->accept) while 1;