ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-Fork-RPC/RPC/Async.pm
Revision: 1.2
Committed: Thu Apr 18 07:59:46 2013 UTC (13 years, 4 months ago) by root
Branch: MAIN
CVS Tags: rel-0_1
Changes since 1.1: +2 -2 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 package AnyEvent::Fork::RPC::Async;
2
3 use common::sense; # actually required to avoid spurious warnings...
4
5 use Errno ();
6
7 use AnyEvent;
8
9 # declare only
10 sub AnyEvent::Fork::RPC::event;
11
12 sub run {
13 my ($function, $init, $serialiser) = splice @_, -3, 3,;
14 my $master = shift;
15
16 {
17 package main;
18 &$init if length $init;
19 $function = \&$function; # resolve function early for extra speed
20 }
21
22 my $busy = 1; # exit when == 0
23
24 my ($f, $t) = eval $serialiser; die $@ if $@;
25 my ($wbuf, $ww);
26
27 my $wcb = sub {
28 my $len = syswrite $master, $wbuf;
29
30 unless (defined $len) {
31 if ($! != Errno::EAGAIN && $! != Errno::EWOULDBLOCK) {
32 undef $ww;
33 die "AnyEvent::Fork::RPC: write error ($!), parent gone?\n";
34 }
35 }
36
37 substr $wbuf, 0, $len, "";
38
39 unless (length $wbuf) {
40 undef $ww;
41 exit unless $busy;
42 }
43 };
44
45 my $write = sub {
46 $wbuf .= $_[0];
47 $ww ||= AE::io $master, 1, $wcb;
48 };
49
50 *AnyEvent::Fork::RPC::event = sub {
51 $write->(pack "LL/a*", 0, &$f);
52 };
53
54 my ($rlen, $rbuf, $rw) = 512 - 16;
55
56 my $len;
57
58 $rw = AE::io $master, 0, sub {
59 $rlen = $rlen * 2 + 16 if $rlen - 128 < length $rbuf;
60 $len = sysread $master, $rbuf, $rlen - length $rbuf, length $rbuf;
61
62 if ($len) {
63 while (8 <= length $rbuf) {
64 (my $id, $len) = unpack "LL", $rbuf;
65 8 + $len <= length $rbuf
66 or last;
67
68 my @r = $t->(substr $rbuf, 8, $len);
69 substr $rbuf, 0, 8 + $len, "";
70
71 ++$busy;
72 $function->(sub {
73 --$busy;
74 $write->(pack "LL/a*", $id, &$f);
75 }, @r);
76 }
77 } elsif (defined $len) {
78 undef $rw;
79 --$busy;
80 $ww ||= AE::io $master, 1, $wcb;
81 } elsif ($! != Errno::EAGAIN && $! != Errno::EWOULDBLOCK) {
82 undef $rw;
83 die "AnyEvent::Fork::RPC: read error in child: $!\n";
84 }
85 };
86
87 $AnyEvent::MODEL eq "EV"
88 ? EV::loop ()
89 : AE::cv->recv;
90 }
91
92 1
93