--- AnyEvent-Fork-RPC/RPC.pm 2013/04/17 15:55:59 1.1 +++ AnyEvent-Fork-RPC/RPC.pm 2013/04/17 17:08:16 1.2 @@ -115,6 +115,10 @@ The actual API in the child is documented in the section that describes the calling semantics of the returned C<$rpc> function. +If you want to pre-load the actual back-end modules to enable memory +sharing, then you should load C for +synchronous, and C for asynchronous mode. + =item serialiser => $string (default: '(sub { pack "(w/a*)*", @_ }, sub { unpack "(w/a*)*", shift })') All arguments, result data and event data have to be serialised to be @@ -130,16 +134,23 @@ perl values and must return an octet string. The second receives the octet string and must return the original list of values. +If you need an external module for serialisation, then you can either +pre-load it into your L process, or you can add a C +or C statement into the serialiser string. Or both. + =back =cut -our $SERIALISE_STRINGS = '(sub { pack "(w/a*)*", @_ }, sub { unpack "(w/a*)*", shift })'; +our $STRING_SERIALISER = '(sub { pack "(w/a*)*", @_ }, sub { unpack "(w/a*)*", shift })'; + +# ideally, we want (SvLEN - SvCUR) || 1024 or somesuch... +sub rlen($) { ($_[0] < 384 ? 512 + 16 : 2 << int +(log $_[0] + 512) / log 2) - $_[0] - 16 } sub run { my ($self, $function, %arg) = @_; - my $serialiser = delete $arg{serialiser} || $SERIALISE_STRINGS; + my $serialiser = delete $arg{serialiser} || $STRING_SERIALISER; my $on_event = delete $arg{on_event}; my $on_error = delete $arg{on_error}; @@ -180,23 +191,24 @@ ->run ("$module\::run", sub { $fh = shift; $rw = AE::io $fh, 0, sub { - my $len = sysread $fh, $rbuf, 512 + length $rbuf, length $rbuf; + my $len = sysread $fh, $rbuf, rlen length $rbuf, length $rbuf; if ($len) { while (5 <= length $rbuf) { $len = unpack "L", $rbuf; - if (4 + $len <= length $rbuf) { - my @r = $t->(substr $rbuf, 4, $len); - substr $rbuf, 0, $len + 4, ""; - - if (pop @r) { - $on_event->(@r); - } elsif (@rcb) { - (shift @rcb)->(@r); - } else { - undef $rw; undef $ww; - $on_error->("unexpected data from child"); - } + 4 + $len <= length $rbuf + or last; + + my @r = $t->(substr $rbuf, 4, $len); + substr $rbuf, 0, $len + 4, ""; + + if (pop @r) { + $on_event->(@r); + } elsif (@rcb) { + (shift @rcb)->(@r); + } else { + undef $rw; undef $ww; + $on_error->("unexpected data from child"); } } } elsif (defined $len) {