You don't even need your own mainloop, as AnyEvent brings its own main loop with it.
I would rewrite your main loop as follows:
my $loop = AnyEvent->condvar;
my $a = 0;
sub heartbeat {
open( $fh, '>>', $msg_log );
print $fh "looping $a\n";
close $fh;
};
AnyEvent->timer( interval => 5, cb => \&heartbeat );
$loop->recv;
exit 0;
I would move reacting to IO out of the main loop as well:
$iocv->cb( \&on_io );
sub on_io {
open( $fh, '>>', $msg_log );
print $fh "loop data: $data\n";
close $fh;
undef( $iocv );
$iocv = AnyEvent->condvar;
$iocv->cb( \&on_io );
};
Ideally, you don't have your own main loop and only have callbacks and let AnyEvent decide, which callback to run, depending on what kind of event has arrived.