package AnyEvent::Fork::RPC::Sync; use common::sense; # actually required to avoid spurious warnings... our ($master, $f, $t); sub main::test {#d# (@_, 5) } sub xwrite($) { my $got = syswrite $master, $_[0]; while ($got < length $_[0]) { my $len = syswrite $master, $_[0], 1<<30, $got; defined $len or die "AnyEvent::Fork::RPC::Sync: write error ($!), parent gone?"; $got += $len; } } sub rlen($) { ($_[0] < 384 ? 512 + 16 : 2 << int +(log $_[0] + 512) / log 2) - $_[0] - 16 } # the goal here is to keep this simple, small and efficient sub run { $master = shift; my ($function, $init, $serialiser) = splice @_, -3, 3,; { package main; &$init if length $init; $function = \&$function; # resolve function early for extra speed } ($f, $t) = eval $serialiser; die $@ if $@; my $rbuf; # the read length here is not optimal, but since we re-use $rbuf, # its allocated size should eventually auto-adjust. while (sysread $master, $rbuf, rlen length $rbuf, length $rbuf) { while () { last if 5 > length $rbuf; my $len = unpack "L", $rbuf; last if 4 + $len > length $rbuf; my @r = $t->(substr $rbuf, 4, $len); substr $rbuf, 0, 4 + $len, ""; xwrite pack "L/a*", $f->($function->(@r), ""); } } shutdown $master, 1; } sub AnyEvent::Fork::RPC::quit { shutdown $master, 0; } sub AnyEvent::Fork::RPC::event { xwrite pack "L/a*", $f->(@_, 1); } 1