ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-Fork-RPC/RPC/Async.pm
Revision: 1.3
Committed: Sat Apr 20 16:34:24 2013 UTC (13 years, 4 months ago) by root
Branch: MAIN
CVS Tags: rel-0_2
Changes since 1.2: +4 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.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 root 1.3 unless ($busy) {
42     shutdown $master, 1;
43     exit;
44     }
45 root 1.1 }
46     };
47    
48     my $write = sub {
49     $wbuf .= $_[0];
50     $ww ||= AE::io $master, 1, $wcb;
51     };
52    
53     *AnyEvent::Fork::RPC::event = sub {
54     $write->(pack "LL/a*", 0, &$f);
55     };
56    
57     my ($rlen, $rbuf, $rw) = 512 - 16;
58    
59 root 1.2 my $len;
60 root 1.1
61     $rw = AE::io $master, 0, sub {
62     $rlen = $rlen * 2 + 16 if $rlen - 128 < length $rbuf;
63     $len = sysread $master, $rbuf, $rlen - length $rbuf, length $rbuf;
64    
65     if ($len) {
66     while (8 <= length $rbuf) {
67 root 1.2 (my $id, $len) = unpack "LL", $rbuf;
68 root 1.1 8 + $len <= length $rbuf
69     or last;
70    
71     my @r = $t->(substr $rbuf, 8, $len);
72     substr $rbuf, 0, 8 + $len, "";
73    
74     ++$busy;
75     $function->(sub {
76     --$busy;
77     $write->(pack "LL/a*", $id, &$f);
78     }, @r);
79     }
80     } elsif (defined $len) {
81     undef $rw;
82     --$busy;
83     $ww ||= AE::io $master, 1, $wcb;
84     } elsif ($! != Errno::EAGAIN && $! != Errno::EWOULDBLOCK) {
85     undef $rw;
86     die "AnyEvent::Fork::RPC: read error in child: $!\n";
87     }
88     };
89    
90     $AnyEvent::MODEL eq "EV"
91     ? EV::loop ()
92     : AE::cv->recv;
93     }
94    
95     1
96