|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package RMI::Node;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
38
 | 
 
 | 
 
 | 
  
38
  
 | 
 
 | 
112815
 | 
 use strict;  | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
    | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1430
 | 
    | 
| 
4
 | 
38
 | 
 
 | 
 
 | 
  
38
  
 | 
 
 | 
206
 | 
 use warnings;  | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
    | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4146
 | 
    | 
| 
5
 | 
38
 | 
 
 | 
 
 | 
  
38
  
 | 
 
 | 
20582
 | 
 use version;  | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58752
 | 
    | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
699
 | 
    | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = $RMI::VERSION;  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Note: if any of these get proxied as full classes, we'd have issues.  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Since it's impossible to proxy a class which has already been "used",  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # we use them at compile time...  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
12
 | 
38
 | 
 
 | 
 
 | 
  
38
  
 | 
 
 | 
19761
 | 
 use RMI;  | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
    | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1207
 | 
    | 
| 
13
 | 
38
 | 
 
 | 
 
 | 
  
38
  
 | 
 
 | 
24521
 | 
 use Tie::Array;  | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32015
 | 
    | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1295
 | 
    | 
| 
14
 | 
38
 | 
 
 | 
 
 | 
  
38
  
 | 
 
 | 
23233
 | 
 use Tie::Hash;  | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24107
 | 
    | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1316
 | 
    | 
| 
15
 | 
38
 | 
 
 | 
 
 | 
  
38
  
 | 
 
 | 
29627
 | 
 use Tie::Scalar;  | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13972
 | 
    | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1448
 | 
    | 
| 
16
 | 
38
 | 
 
 | 
 
 | 
  
38
  
 | 
 
 | 
23693
 | 
 use Tie::Handle;  | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
75601
 | 
    | 
| 
 
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1160
 | 
    | 
| 
17
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
20048
 | 
 use Data::Dumper;  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
143118
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2275
 | 
    | 
| 
18
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
9922
 | 
 use Scalar::Util;  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
92
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1566
 | 
    | 
| 
19
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
328
 | 
 use Carp;  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24031
 | 
    | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 require 'Config_heavy.pl';   | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # public API  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 _mk_ro_accessors(qw/reader writer/);  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
28
 | 
33
 | 
 
 | 
 
 | 
  
33
  
 | 
  
1
  
 | 
616
 | 
     my $class = shift;  | 
| 
29
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1855
 | 
     my $self = bless {  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         reader => undef,  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         writer => undef,  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _sent_objects => {},  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _received_objects => {},  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _received_and_destroyed_ids => [],  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _tied_objects_for_tied_refs => {},          | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         @_  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }, $class;  | 
| 
38
 | 
33
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1616
 | 
     if (my $p = delete $self->{allow_packages}) {  | 
| 
39
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
         $self->{allow_packages} = { map { $_ => 1 } @$p };  | 
| 
 
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
    | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
41
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1197
 | 
     for my $p (@RMI::Node::properties) {  | 
| 
42
 | 
152
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1217
 | 
         unless (exists $self->{$p}) {  | 
| 
43
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
             die "no $p on object!"  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
46
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
661
 | 
     return $self;  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub close {  | 
| 
50
 | 
21
 | 
 
 | 
 
 | 
  
16
  
 | 
  
1
  
 | 
3803
 | 
     my $self = $_[0];  | 
| 
51
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
162
 | 
     $self->{writer}->close unless $self->{reader} == $self->{writer};  | 
| 
52
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14803
 | 
     $self->{reader}->close;  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub send_request_and_receive_response {  | 
| 
56
 | 
249
 | 
 
 | 
 
 | 
  
249
  
 | 
  
0
  
 | 
514
 | 
     my $self = shift;  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
58
 | 
249
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
694
 | 
     if ($RMI::DEBUG) {  | 
| 
59
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
322
 | 
         print "$RMI::DEBUG_MSG_PREFIX N: $$ calling via $self: @_\n";  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
62
 | 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
501
 | 
     my $wantarray = wantarray;  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Specs to get control of the serialization process are optional,    | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # and may be at the beginning of the parameter list.    | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # The remainder of the params are only analyzed on the caller's side.  | 
| 
67
 | 
249
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
715
 | 
     my $opts = shift(@_) if ref($_[0]) eq 'HASH';  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
249
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
3051
 | 
     $self->_send('query',[$wantarray, @_],$opts) or die "failed to send! $!";  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
71
 | 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
99694
 | 
     for (1) {  | 
| 
72
 | 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1956
 | 
         my ($message_type, $message_data) = $self->_receive();  | 
| 
73
 | 
257
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1079
 | 
         if ($message_type eq 'result') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
74
 | 
246
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
934
 | 
             if ($wantarray) {  | 
| 
75
 | 
58
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
144
 | 
                 print "$RMI::DEBUG_MSG_PREFIX N: $$ returning list @$message_data\n" if $RMI::DEBUG;  | 
| 
76
 | 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
887
 | 
                 return @$message_data;  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
79
 | 
196
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
488
 | 
                 print "$RMI::DEBUG_MSG_PREFIX N: $$ returning scalar $message_data->[0]\n" if $RMI::DEBUG;  | 
| 
80
 | 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2383
 | 
                 return $message_data->[0];  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif ($message_type eq 'close') {  | 
| 
84
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
291
 | 
             return;  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif ($message_type eq 'query') {  | 
| 
87
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
141
 | 
             $self->_process_query($message_data);              | 
| 
88
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
             redo;  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif ($message_type eq 'exception') {  | 
| 
91
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
378
 | 
             die $message_data->[0];  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
94
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
             die "unexpected message type from RMI message: $message_type";  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }      | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub receive_request_and_send_response {  | 
| 
100
 | 
245
 | 
 
 | 
 
 | 
  
245
  
 | 
  
1
  
 | 
405
 | 
     my ($self) = @_;  | 
| 
101
 | 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1828
 | 
     my ($message_type, $message_data) = $self->_receive();  | 
| 
102
 | 
245
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
756
 | 
     if ($message_type eq 'query') {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
103
 | 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1542
 | 
         my ($response_type, $response_data) = $self->_process_query($message_data);  | 
| 
104
 | 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1579
 | 
         return ($message_type, $message_data, $response_type, $response_data);  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($message_type eq 'close') {  | 
| 
107
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
128
 | 
         return;  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
110
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
65
 | 
         die "Unexpected message type $message_type!  message_data was:" . Dumper::Dumper($message_data);  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }          | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # private API  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 _mk_ro_accessors(qw/_sent_objects _received_objects _received_and_destroyed_ids _tied_objects_for_tied_refs/);  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _send {  | 
| 
119
 | 
488
 | 
 
 | 
 
 | 
  
489
  
 | 
 
 | 
1395
 | 
     my ($self, $message_type, $message_data, $opts) = @_;  | 
| 
120
 | 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2919
 | 
     my $s = $self->_serialize($message_type,$message_data, $opts);      | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
122
 | 
484
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1480
 | 
     print "$RMI::DEBUG_MSG_PREFIX N: $$ sending: $s\n" if $RMI::DEBUG;  | 
| 
123
 | 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3405
 | 
     return $self->{writer}->print($s,"\n");                  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _receive {  | 
| 
127
 | 
498
 | 
 
 | 
 
 | 
  
498
  
 | 
 
 | 
922
 | 
     my ($self) = @_;  | 
| 
128
 | 
498
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1250
 | 
     print "$RMI::DEBUG_MSG_PREFIX N: $$ receiving\n" if $RMI::DEBUG;  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
130
 | 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20818
 | 
     my $serialized_blob = $self->{reader}->getline;  | 
| 
131
 | 
499
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
3542683
 | 
     if (not defined $serialized_blob) {  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # a failure to get data returns a message type of 'close', and undefined message_data  | 
| 
133
 | 
23
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
117
 | 
         print "$RMI::DEBUG_MSG_PREFIX N: $$ connection closed\n" if $RMI::DEBUG;  | 
| 
134
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1028
 | 
         $self->{is_closed} = 1;  | 
| 
135
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7942
 | 
         return ('close',undef);  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
137
 | 
485
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1587
 | 
     print "$RMI::DEBUG_MSG_PREFIX N: $$ got $serialized_blob" if $RMI::DEBUG;  | 
| 
138
 | 
485
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
1848
 | 
     print "\n" if $RMI::DEBUG and not defined $serialized_blob;  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
140
 | 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4135
 | 
     my ($message_type,$message_data) = $self->_deserialize($serialized_blob);  | 
| 
141
 | 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1503
 | 
     return ($message_type, $message_data);  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _process_query {  | 
| 
145
 | 
248
 | 
 
 | 
 
 | 
  
249
  
 | 
 
 | 
894
 | 
     my ($self, $message_data) = @_;  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
147
 | 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
571
 | 
     my $wantarray = shift @$message_data;  | 
| 
148
 | 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
472
 | 
     my $call_type = shift @$message_data;  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
150
 | 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
823
 | 
     do {      | 
| 
151
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
244
 | 
         no warnings;  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
98
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10581
 | 
    | 
| 
152
 | 
248
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
657
 | 
         print "$RMI::DEBUG_MSG_PREFIX N: $$ processing query $call_type in wantarray context $wantarray with : @$message_data\n" if $RMI::DEBUG;  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # swap call_ for _respond_to_  | 
| 
157
 | 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
748
 | 
     my $method = '_respond_to_' . substr($call_type,5);  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
159
 | 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
625
 | 
     my @result;  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
161
 | 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
653
 | 
     push @RMI::executing_nodes, $self;  | 
| 
162
 | 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
354
 | 
     eval {  | 
| 
163
 | 
246
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1158
 | 
         if (not defined $wantarray) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
164
 | 
23
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
106
 | 
             print "$RMI::DEBUG_MSG_PREFIX N: $$ object call with undef wantarray\n" if $RMI::DEBUG;  | 
| 
165
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
125
 | 
             $self->$method(@$message_data);  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif ($wantarray) {  | 
| 
168
 | 
60
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
390
 | 
             print "$RMI::DEBUG_MSG_PREFIX N: $$ object call with true wantarray\n" if $RMI::DEBUG;  | 
| 
169
 | 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
427
 | 
             @result = $self->$method(@$message_data);  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
172
 | 
179
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
450
 | 
             print "$RMI::DEBUG_MSG_PREFIX N: $$ object call with false wantarray\n" if $RMI::DEBUG;  | 
| 
173
 | 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1451
 | 
             my $result = $self->$method(@$message_data);  | 
| 
174
 | 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2292
 | 
             @result = ($result);  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
177
 | 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1201
 | 
     pop @RMI::executing_nodes;  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # we MUST undef these in case they are the only references to remote objects which need to be destroyed  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # the DESTROY handler will queue them for deletion, and _send() will include them in the message to the other side  | 
| 
181
 | 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1001
 | 
     @$message_data = ();  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
183
 | 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
400
 | 
     my ($return_type, $return_data);  | 
| 
184
 | 
245
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
500
 | 
     if ($@) {  | 
| 
185
 | 
12
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
280
 | 
         print "$RMI::DEBUG_MSG_PREFIX N: $$ executed with EXCEPTION (unserialized): $@\n" if $RMI::DEBUG;  | 
| 
186
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
         ($return_type, $return_data) = ('exception',[$@]);  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
189
 | 
243
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
592
 | 
         print "$RMI::DEBUG_MSG_PREFIX N: $$ executed with result (unserialized): @result\n" if $RMI::DEBUG;  | 
| 
190
 | 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
908
 | 
         ($return_type, $return_data) =  ('result',\@result);  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
193
 | 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1534
 | 
     $self->_send($return_type, $return_data);      | 
| 
194
 | 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8346
 | 
     return ($return_type, $return_data);  | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # private API for the server-ish role  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _respond_to_function {  | 
| 
200
 | 
81
 | 
 
 | 
 
 | 
  
83
  
 | 
 
 | 
434
 | 
     my ($self, $fname, @params) = @_;  | 
| 
201
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
218
 | 
     no strict 'refs';  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
68
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3843
 | 
    | 
| 
202
 | 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
992
 | 
     $fname->(@params);  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _respond_to_class_method {  | 
| 
206
 | 
23
 | 
 
 | 
 
 | 
  
25
  
 | 
 
 | 
208
 | 
     my ($self, $class, $method, @params) = @_;  | 
| 
207
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
541
 | 
     $class->$method(@params);  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _respond_to_object_method {  | 
| 
211
 | 
54
 | 
 
 | 
 
 | 
  
52
  
 | 
 
 | 
235
 | 
     my ($self, $object, $method, @params) = @_;  | 
| 
212
 | 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
445
 | 
     $object->$method(@params);  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _respond_to_use {  | 
| 
216
 | 
13
 | 
 
 | 
 
 | 
  
15
  
 | 
 
 | 
260
 | 
     my ($self,$class,$module,$has_args,@use_args) = @_;  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
218
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
177
 | 
     no strict 'refs';  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37882
 | 
    | 
| 
219
 | 
13
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
133
 | 
     if ($class and not $module) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
220
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
         $module = $class;  | 
| 
221
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
305
 | 
         $module =~ s/::/\//g;  | 
| 
222
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
         $module .= '.pm';  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif ($module and not $class) {  | 
| 
225
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
         $class = $module;  | 
| 
226
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
247
 | 
         $class =~ s/\//::/g;  | 
| 
227
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
         $class =~ s/.pm$//;   | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
230
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
     my $n = $RMI::Exported::count++;  | 
| 
231
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
239
 | 
     my $tmp_package_to_catch_exports = 'RMI::Exported::P' . $n;  | 
| 
232
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
103
 | 
     my $src = "  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         package $tmp_package_to_catch_exports;  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         require $class;  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my \@exports = ();  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if (\$has_args) {  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             if (\@use_args) {  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $class->import(\@use_args);  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 \@exports = grep { ${tmp_package_to_catch_exports}->can(\$_) } keys \%${tmp_package_to_catch_exports}::;  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # print qq/no import because of empty list!/;  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $class->import();  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             \@exports = grep { ${tmp_package_to_catch_exports}->can(\$_) } keys \%${tmp_package_to_catch_exports}::;  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return (\$INC{'$module'}, \@exports);  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ";  | 
| 
251
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2336
 | 
     my ($path, @exported) = eval($src);  | 
| 
252
 | 
13
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
446
 | 
     die $@ if $@;  | 
| 
253
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
99
 | 
     return ($class,$module,$path,@exported);  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _respond_to_use_lib {  | 
| 
257
 | 
6
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
14
 | 
     my $self = shift;   | 
| 
258
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
244
 | 
     my $lib = shift;  | 
| 
259
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
     require lib;  | 
| 
260
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     return lib->import($lib);  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _respond_to_eval {  | 
| 
264
 | 
100
 | 
 
 | 
 
 | 
  
102
  
 | 
 
 | 
414
 | 
     my $self = shift;  | 
| 
265
 | 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
194
 | 
     my $src = shift;  | 
| 
266
 | 
100
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
274
 | 
     if (wantarray) {  | 
| 
267
 | 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2716
 | 
         my @result = eval $src;  | 
| 
268
 | 
41
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
181
 | 
         die $@ if $@;  | 
| 
269
 | 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
143
 | 
         return @result;          | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
272
 | 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4216
 | 
         my $result = eval $src;  | 
| 
273
 | 
64
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
415
 | 
         die $@ if $@;  | 
| 
274
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
235
 | 
         return $result;  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _respond_to_coderef {  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # This is used when a CODE ref is proxied, since you can't tie CODE refs.  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # It does not have a matching caller in RMI::Client.  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # The other reference types are handled by "tie" to RMI::ProxyReferecnce.  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # NOTE: It's important to shift these two parameters off since goto must   | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # pass the remainder of @_ to the subroutine.  | 
| 
285
 | 
13
 | 
 
 | 
 
 | 
  
15
  
 | 
 
 | 
263
 | 
     my $self = shift;  | 
| 
286
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
     my $sub_id = shift;  | 
| 
287
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     my $sub = $self->{_sent_objects}{$sub_id};  | 
| 
288
 | 
13
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
319
 | 
     die "$sub is not a CODE ref.  came from $sub_id\n" unless $sub and ref($sub) eq 'CODE';  | 
| 
289
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
162
 | 
     goto $sub;  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # The private API for the client-ish role of the RMI::Node is still in the RMI::Client module,  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # where it is documented.  All of that API is a thin wrapper for methods here.  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # serialize params when sending a query, or results when sending a response  | 
| 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _serialize {  | 
| 
298
 | 
482
 | 
 
 | 
 
 | 
  
484
  
 | 
 
 | 
949
 | 
     my ($self, $message_type, $message_data, $opts) = @_;      | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # TODO: we previously had no knowledge in the client of the type of call being made,   | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # but to support overrides we now need it.  Refactor this conditional logic!!  | 
| 
302
 | 
482
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1499
 | 
     if ($message_type eq 'query') {  | 
| 
303
 | 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
486
 | 
         my $call_type = $message_data->[1];  | 
| 
304
 | 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
466
 | 
         my $pkg;  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $sub;  | 
| 
306
 | 
251
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1800
 | 
         if ($call_type eq 'call_object_method') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
307
 | 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
142
 | 
             $pkg = ref($message_data->[2]);  | 
| 
308
 | 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
248
 | 
             $pkg =~ s/RMI::Proxy:://;  | 
| 
309
 | 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
354
 | 
             $sub = $message_data->[3];  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif ($call_type eq 'call_class_method') {  | 
| 
312
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
72
 | 
             $pkg = $message_data->[2];  | 
| 
313
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
             $sub = $message_data->[3];  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif ($call_type eq 'call_function') {  | 
| 
316
 | 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
824
 | 
             ($pkg,$sub) = ($message_data->[2] =~ /^(.*)::([^\:]*)$/);  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif (  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $call_type eq 'call_eval'  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             or $call_type eq 'call_coderef'  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             or $call_type eq 'call_use'  | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             or $call_type eq 'call_use_lib'  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ) {  | 
| 
324
 | 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
272
 | 
             $pkg = '-' . $call_type;  | 
| 
325
 | 
115
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
292
 | 
             if ($call_type eq 'call_use') {  | 
| 
326
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
235
 | 
                 $sub = $message_data->[2];  | 
| 
327
 | 
13
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
70
 | 
                 if (!$sub) {  | 
| 
328
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
                     $sub = $message_data->[3];  | 
| 
329
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
469
 | 
                     $sub =~ s/.pm$//;  | 
| 
330
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
                     $sub =~ s/\//\::/g;  | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
332
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
                 $sub .= '';  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
335
 | 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
528
 | 
                 $sub = $message_data->[2] . '';  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
339
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
             die "no handling for CALL TYPE $call_type?";  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
342
 | 
247
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
643
 | 
         unless ($pkg) {  | 
| 
343
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
253
 | 
             die "Failed to resolve a pkg/sub pair for query @$message_data!";  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
346
 | 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1000
 | 
         my $default_opts = $RMI::ProxyObject::DEFAULT_OPTS{$pkg}{$sub};  | 
| 
347
 | 
247
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
595
 | 
         print "$RMI::DEBUG_MSG_PREFIX N: $$ $message_type $call_type on $pkg $sub has default opts " . Data::Dumper::Dumper($default_opts) . "\n" if $RMI::DEBUG;  | 
| 
348
 | 
247
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
914
 | 
         if ($default_opts) {  | 
| 
349
 | 
7
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
43
 | 
             if ($opts) {  | 
| 
350
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
                 $opts = { %$default_opts, %$opts };  | 
| 
351
 | 
6
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
243
 | 
                 print "$RMI::DEBUG_MSG_PREFIX N: $$ $message_type $call_type on $pkg $sub merged with specified opts for combined set: " . Data::Dumper::Dumper($opts) . "\n" if $RMI::DEBUG;  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
354
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
                 $opts = $default_opts;  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
360
 | 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1849
 | 
     my $sent_objects = $self->{_sent_objects};  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # there is currently only one option to serialize: a global "copy" flag.  | 
| 
363
 | 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
818
 | 
     my $copy;  | 
| 
364
 | 
482
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1083
 | 
     if ($opts) {  | 
| 
365
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
         $copy = delete $opts->{copy};  | 
| 
366
 | 
11
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
311
 | 
         if (%$opts) {  | 
| 
367
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
             Carp::confess("Uknown options!  The only supported option is the 'copy' flag.");  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
371
 | 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
581
 | 
     my @serialized;  | 
| 
372
 | 
482
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1652
 | 
     Carp::confess("expected message_type, message_data_arrayref, optional_opts_hashref as params") unless ref($message_data);  | 
| 
373
 | 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1133
 | 
     for my $o (@$message_data) {  | 
| 
374
 | 
1387
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
2937
 | 
         if (my $type = ref($o)) {  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # sending some sort of reference  | 
| 
376
 | 
202
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1309
 | 
             if (my $key = $RMI::Node::remote_id_for_object{$o}) {   | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # this is a proxy object on THIS side: the real object will be used on the remote side  | 
| 
378
 | 
124
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
332
 | 
                 print "$RMI::DEBUG_MSG_PREFIX N: $$ proxy $o references remote $key:\n" if $RMI::DEBUG;  | 
| 
379
 | 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
246
 | 
                 push @serialized, 3, $key;  | 
| 
380
 | 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
767
 | 
                 next;  | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             elsif($copy) {  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # a reference on this side which should be copied on the other side instead of proxied  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # this never happens by default in the RMI modules, only when specially requested for performance  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # or to get around known bugs in the C<->Perl interaction in some modules (DBI).  | 
| 
386
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
                 push @serialized, 4, $o;  | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # a reference originating on this side: send info so the remote side can create a proxy  | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # TODO: use something better than stringification since this can be overridden!!!  | 
| 
392
 | 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
248
 | 
                 my $key = "$o";  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # TODO: handle extracting the base type for tying for regular objects which does not involve parsing  | 
| 
395
 | 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
512
 | 
                 my $base_type = substr($key,index($key,'=')+1);  | 
| 
396
 | 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
371
 | 
                 $base_type = substr($base_type,0,index($base_type,'('));  | 
| 
397
 | 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
138
 | 
                 my $code;  | 
| 
398
 | 
81
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
391
 | 
                 if ($base_type ne $type) {  | 
| 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # blessed reference  | 
| 
400
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9188
 | 
                     $code = 1;  | 
| 
401
 | 
22
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
99
 | 
                     if (my $allowed = $self->{allow_packages}) {  | 
| 
402
 | 
4
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
370
 | 
                         unless ($allowed->{ref($o)}) {  | 
| 
403
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
                             die "objects of type " . ref($o) . " cannot be passed from this RMI node!";  | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         }  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 else {  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # regular reference  | 
| 
409
 | 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
246
 | 
                     $code = 2;  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                   | 
| 
412
 | 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
469
 | 
                 push @serialized, $code, $key;  | 
| 
413
 | 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
420
 | 
                 $sent_objects->{$key} = $o;  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # sending a non-reference value  | 
| 
418
 | 
1189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2645
 | 
             push @serialized, 0, $o;  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
421
 | 
480
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1408
 | 
     print "$RMI::DEBUG_MSG_PREFIX N: $$ $message_type translated for serialization to @serialized\n" if $RMI::DEBUG;  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
423
 | 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
983
 | 
     @$message_data = (); # essential to get the DESTROY handler to fire for proxies we're not holding on-to  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Do this after emptying the $message_data array, so the list will be expanded to include objects which  | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # were sent from the other side, and are only referenced in the data we're returning.  | 
| 
427
 | 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1014
 | 
     my $received_and_destroyed_ids = $self->{_received_and_destroyed_ids};  | 
| 
428
 | 
484
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1394
 | 
     print "$RMI::DEBUG_MSG_PREFIX N: $$ destroyed proxies: @$received_and_destroyed_ids\n" if $RMI::DEBUG;      | 
| 
429
 | 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1368
 | 
     unshift @serialized, [@$received_and_destroyed_ids];  | 
| 
430
 | 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
873
 | 
     @$received_and_destroyed_ids = ();  | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # TODO: the use of Data::Dumper here is pure laziness.  The @serialized list contains no references,   | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # and could be turned into a string with something simpler than data dumper.  It could also be parsed with   | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # something simpler than eval() on the other side.  The only thing to be careful of is that parsing   | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # currently expects the records are divided by newlines (instead of sending a message length or other   | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # terminator) and Dumper conveniently escapes newlines in any strings we pass.  | 
| 
437
 | 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4628
 | 
     my $serialized_blob = Data::Dumper->new([[$message_type, @serialized]])->Terse(1)->Indent(0)->Useqq(1)->Dump;  | 
| 
438
 | 
484
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
58222
 | 
     print "$RMI::DEBUG_MSG_PREFIX N: $$ $message_type serialized as $serialized_blob\n" if $RMI::DEBUG;  | 
| 
439
 | 
484
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
2826
 | 
     if ($serialized_blob =~ s/\n/ /gms) {  | 
| 
440
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
252
 | 
         die "newline found in message data!";  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
443
 | 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2935
 | 
     return $serialized_blob;  | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # deserialize params when receiving a query, or results when receiving a response  | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _deserialize {  | 
| 
449
 | 
484
 | 
 
 | 
 
 | 
  
488
  
 | 
 
 | 
985
 | 
     my ($self, $serialized_blob) = @_;  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # see TODO above for switching from Dumper/eval to something simpler.  | 
| 
452
 | 
33
 | 
 
 | 
 
 | 
  
33
  
 | 
 
 | 
895
 | 
     my $serialized = eval "no strict; no warnings; $serialized_blob";  | 
| 
 
 | 
33
 | 
 
 | 
 
 | 
  
31
  
 | 
 
 | 
3214
 | 
    | 
| 
 
 | 
33
 | 
 
 | 
 
 | 
  
30
  
 | 
 
 | 
2833
 | 
    | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
  
29
  
 | 
 
 | 
226
 | 
    | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
  
28
  
 | 
 
 | 
97
 | 
    | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
  
28
  
 | 
 
 | 
3972
 | 
    | 
| 
 
 | 
30
 | 
 
 | 
 
 | 
  
26
  
 | 
 
 | 
1104
 | 
    | 
| 
 
 | 
29
 | 
 
 | 
 
 | 
  
26
  
 | 
 
 | 
64
 | 
    | 
| 
 
 | 
29
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
1767
 | 
    | 
| 
 
 | 
29
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
4137
 | 
    | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
51
 | 
    | 
| 
 
 | 
23
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
1342
 | 
    | 
| 
 
 | 
28
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
218
 | 
    | 
| 
 
 | 
28
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
90
 | 
    | 
| 
 
 | 
28
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
1221
 | 
    | 
| 
 
 | 
28
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
174
 | 
    | 
| 
 
 | 
28
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
207
 | 
    | 
| 
 
 | 
28
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
1241
 | 
    | 
| 
 
 | 
26
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
183
 | 
    | 
| 
 
 | 
26
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
59
 | 
    | 
| 
 
 | 
26
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
4324
 | 
    | 
| 
 
 | 
26
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
177
 | 
    | 
| 
 
 | 
26
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
56
 | 
    | 
| 
 
 | 
26
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
1109
 | 
    | 
| 
 
 | 
480
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
52965
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
9747
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
2824
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
123
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
 
 | 
    | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
454
 | 
484
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
3485
 | 
     if ($@) {  | 
| 
455
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
         die "Exception de-serializing message: $@";  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }          | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
458
 | 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2016
 | 
     my $message_type = shift @$serialized;  | 
| 
459
 | 
484
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1330
 | 
     if (! defined $message_type) {  | 
| 
460
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
         die "unexpected undef type from incoming message:" . Data::Dumper::Dumper($serialized);  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }      | 
| 
462
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
463
 | 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
814
 | 
     do {  | 
| 
464
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
247
 | 
         no warnings;      | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
100
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15224
 | 
    | 
| 
465
 | 
484
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4604
 | 
         print "$RMI::DEBUG_MSG_PREFIX N: $$ processing (serialized): @$serialized\n" if $RMI::DEBUG;  | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
468
 | 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1711
 | 
     my @message_data;  | 
| 
469
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
470
 | 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1354
 | 
     my $sent_objects = $self->{_sent_objects};  | 
| 
471
 | 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
878
 | 
     my $received_objects = $self->{_received_objects};  | 
| 
472
 | 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
894
 | 
     my $received_and_destroyed_ids = shift @$serialized;  | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
474
 | 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1428
 | 
     while (@$serialized) {   | 
| 
475
 | 
1371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1774
 | 
         my $type = shift @$serialized;  | 
| 
476
 | 
1371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2283
 | 
         my $value = shift @$serialized;  | 
| 
477
 | 
1371
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
4141
 | 
         if ($type == 0) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # primitive value  | 
| 
479
 | 
1191
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
2391
 | 
             print "$RMI::DEBUG_MSG_PREFIX N: $$ - primitive " . (defined($value) ? $value : "") . "\n" if $RMI::DEBUG;  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
480
 | 
1191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3387
 | 
             push @message_data, $value;  | 
| 
481
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif ($type == 1 or $type == 2) {  | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # exists on the other side: make a proxy  | 
| 
484
 | 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10856
 | 
             my $o = $received_objects->{$value};  | 
| 
485
 | 
89
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
303
 | 
             unless ($o) {  | 
| 
486
 | 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
830
 | 
                 my ($remote_class,$remote_shape) = ($value =~ /^(.*?=|)(.*?)\(/);  | 
| 
487
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
385
 | 
                 chop $remote_class;  | 
| 
488
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
160
 | 
                 my $t;  | 
| 
489
 | 
78
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
594
 | 
                 if ($remote_shape eq 'ARRAY') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
490
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
231
 | 
                     $o = [];  | 
| 
491
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
126
 | 
                     $t = tie @$o, 'RMI::ProxyReference', $self, $value, "$o", 'Tie::StdArray';                          | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif ($remote_shape eq 'HASH') {  | 
| 
494
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
                     $o = {};  | 
| 
495
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
626
 | 
                     $t = tie %$o, 'RMI::ProxyReference', $self, $value, "$o", 'Tie::StdHash';                          | 
| 
496
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
497
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif ($remote_shape eq 'SCALAR') {  | 
| 
498
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
                     my $anonymous_scalar;  | 
| 
499
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
                     $o = \$anonymous_scalar;  | 
| 
500
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
270
 | 
                     $t = tie $$o, 'RMI::ProxyReference', $self, $value, "$o", 'Tie::StdScalar';                          | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
502
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif ($remote_shape eq 'CODE') {  | 
| 
503
 | 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
                     my $sub_id = $value;  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     $o = sub {  | 
| 
505
 | 
11
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
1943
 | 
                         $self->send_request_and_receive_response('call_coderef', $sub_id, @_);  | 
| 
506
 | 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
459
 | 
                     };  | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # TODO: ensure this cleans up on the other side when it is destroyed  | 
| 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 elsif ($remote_shape eq 'GLOB' or $remote_shape eq 'IO') {  | 
| 
510
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
                     $o = \do { local *HANDLE };  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
    | 
| 
511
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
245
 | 
                     $t = tie *$o, 'RMI::ProxyReference', $self, $value, "$o", 'Tie::StdHandle';  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
513
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 else {  | 
| 
514
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
                     die "unknown reference type for $remote_shape for $value!!";  | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
516
 | 
74
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
247
 | 
                 if ($type == 1) {  | 
| 
517
 | 
20
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
265
 | 
                     if ($RMI::proxied_classes{$remote_class}) {  | 
| 
518
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
                         bless $o, $remote_class;  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }  | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     else {  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         # Put the object into a custom subclass of RMI::ProxyObject  | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         # this allows class-wide customization of how proxying should  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         # occur.  It also makes Data::Dumper results more readable.  | 
| 
524
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
                         my $target_class = 'RMI::Proxy::' . $remote_class;  | 
| 
525
 | 
19
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
218
 | 
                         unless ($RMI::classes_with_proxied_objects{$remote_class}) {  | 
| 
526
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
226
 | 
                             no strict 'refs';  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1398
 | 
    | 
| 
527
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
                             @{$target_class . '::ISA'} = ('RMI::ProxyObject');  | 
| 
 
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
611
 | 
    | 
| 
528
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
743
 | 
                             no strict;  | 
| 
 
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
248
 | 
    | 
| 
 
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1341
 | 
    | 
| 
529
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
172
 | 
                             no warnings;  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21489
 | 
    | 
| 
530
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
258
 | 
                             local $SIG{__DIE__} = undef;  | 
| 
531
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
107
 | 
                             local $SIG{__WARN__} = undef;  | 
| 
532
 | 
12
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
739
 | 
                             eval "use $target_class";  | 
| 
533
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
237
 | 
                             $RMI::classes_with_proxied_objects{$remote_class} = 1;  | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         }  | 
| 
535
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
                         bless $o, $target_class;      | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }  | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
538
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
345
 | 
                 $received_objects->{$value} = $o;  | 
| 
539
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
782
 | 
                 Scalar::Util::weaken($received_objects->{$value});  | 
| 
540
 | 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
277
 | 
                 my $o_id = "$o";  | 
| 
541
 | 
78
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
325
 | 
                 my $t_id = "$t" if defined $t;  | 
| 
542
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
528
 | 
                 $RMI::Node::node_for_object{$o_id} = $self;  | 
| 
543
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
277
 | 
                 $RMI::Node::remote_id_for_object{$o_id} = $value;  | 
| 
544
 | 
78
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
395
 | 
                 if ($t) {  | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # ensure calls to work with the "tie-buddy" to the reference  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # result in using the orinigla reference on the "real" side  | 
| 
547
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
536
 | 
                     $RMI::Node::node_for_object{$t_id} = $self;  | 
| 
548
 | 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
158
 | 
                     $RMI::Node::remote_id_for_object{$t_id} = $value;  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
               | 
| 
552
 | 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
165
 | 
             push @message_data, $o;  | 
| 
553
 | 
80
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
461
 | 
             print "$RMI::DEBUG_MSG_PREFIX N: $$ - made proxy for $value\n" if $RMI::DEBUG;  | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
555
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif ($type == 3) {  | 
| 
556
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # exists on this side, and was a proxy on the other side: get the real reference by id  | 
| 
557
 | 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
290
 | 
             my $o = $sent_objects->{$value};  | 
| 
558
 | 
125
 | 
  
 50
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
333
 | 
             print "$RMI::DEBUG_MSG_PREFIX N: $$ reconstituting local object $value, but not found in my sent objects!\n" and die unless $o;  | 
| 
559
 | 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
338
 | 
             push @message_data, $o;  | 
| 
560
 | 
120
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1848
 | 
             print "$RMI::DEBUG_MSG_PREFIX N: $$ - resolved local object for $value\n" if $RMI::DEBUG;  | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         elsif ($type == 4) {  | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # fully serialized blob  | 
| 
564
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # this is never done by default, but is part of shortcut/optimization on a per-class basis  | 
| 
565
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
             push @message_data, $value;  | 
| 
566
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
568
 | 
478
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1398
 | 
     print "$RMI::DEBUG_MSG_PREFIX N: $$ remote side destroyed: @$received_and_destroyed_ids\n" if $RMI::DEBUG;  | 
| 
569
 | 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1207
 | 
     my @done = grep { defined $_ } delete @$sent_objects{@$received_and_destroyed_ids};  | 
| 
 
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
    | 
| 
570
 | 
482
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1789
 | 
     unless (@done == @$received_and_destroyed_ids) {  | 
| 
571
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
         print "Some IDS not found in the sent list: done: @done, expected: @$received_and_destroyed_ids\n";  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
574
 | 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2380
 | 
     return ($message_type,\@message_data);  | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # this proxies a single variable  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub bind_local_var_to_remote {  | 
| 
580
 | 
48
 | 
 
 | 
 
 | 
  
50
  
 | 
  
0
  
 | 
2027
 | 
     my $self = shift;  | 
| 
581
 | 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
107
 | 
     my $local_var = shift;  | 
| 
582
 | 
48
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
168
 | 
     my $remote_var = (@_ ? shift : $local_var);  | 
| 
583
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
584
 | 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
187
 | 
     my $type = substr($local_var,0,1);  | 
| 
585
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
133
 | 
     if (index($local_var,'::')) {  | 
| 
586
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
         $local_var = substr($local_var,1);  | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
589
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $caller = caller();  | 
| 
590
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $local_var = $caller . '::' . substr($local_var,1);  | 
| 
591
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
592
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
593
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
141
 | 
     unless ($type eq substr($remote_var,0,1)) {  | 
| 
594
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         die "type mismatch: local var $local_var has type $type, while remote is $remote_var!";  | 
| 
595
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
596
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
97
 | 
     if (index($remote_var,'::')) {  | 
| 
597
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
95
 | 
         $remote_var = substr($remote_var,1);  | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
600
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $caller = caller();  | 
| 
601
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $remote_var = $caller . '::' . substr($remote_var,1);  | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
603
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
604
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
106
 | 
     my $src = '\\' . $type . $remote_var . ";\n";  | 
| 
605
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
267
 | 
     my $r = $self->call_eval($src);  | 
| 
606
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
149
 | 
     die $@ if $@;  | 
| 
607
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
122
 | 
     $src = '*' . $local_var . ' = $r' . ";\n";  | 
| 
608
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12402
 | 
     eval $src;  | 
| 
609
 | 
42
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
199
 | 
     die $@ if $@;  | 
| 
610
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
182
 | 
     return 1;  | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
613
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # this proxies an entire class instead of just a single object  | 
| 
614
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
615
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub bind_local_class_to_remote {  | 
| 
616
 | 
7
 | 
 
 | 
 
 | 
  
15
  
 | 
  
0
  
 | 
17
 | 
     my $self = shift;  | 
| 
617
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
101
 | 
     my ($class,$module,$path,@exported) = $self->call_use(@_);  | 
| 
618
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     my $re_bind = 0;  | 
| 
619
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
113
 | 
     if (my $prior = $RMI::proxied_classes{$class}) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
620
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
39
 | 
         if ($prior != $self) {  | 
| 
621
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             die "class $class has already been proxied by another RMI client: $prior!";  | 
| 
622
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # re-binding a class to the same remote side doesn't hurt,  | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # and allowing it allows the effect of export to occur  | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # in multiple places on the client side.  | 
| 
627
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
629
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif (my $path = $INC{$module}) {  | 
| 
630
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
         die "module $module has already been used locally from path: $path";  | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
632
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
225
 | 
     no strict 'refs';  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
68
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10106
 | 
    | 
| 
633
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
     for my $sub (qw/AUTOLOAD DESTROY can isa/) {  | 
| 
634
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
         *{$class . '::' . $sub} = \&{ 'RMI::ProxyObject::' . $sub }  | 
| 
 
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
206
 | 
    | 
| 
 
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
324
 | 
    | 
| 
635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
636
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     if (@exported) {  | 
| 
637
 | 
3
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
44
 | 
         my $caller ||= caller(0);  | 
| 
638
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
         if (substr($caller,0,5) eq 'RMI::') { $caller = caller(1) }  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
    | 
| 
639
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         for my $sub (@exported) {  | 
| 
640
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
168
 | 
             my @pair = ('&' . $caller . '::' . $sub => '&' . $class . '::' . $sub);  | 
| 
641
 | 
36
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
87
 | 
             print "$RMI::DEBUG_MSG_PREFIX N: $$ bind pair $pair[0] $pair[1]\n" if $RMI::DEBUG;  | 
| 
642
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
233
 | 
             $self->bind_local_var_to_remote(@pair);  | 
| 
643
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
644
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
645
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     $RMI::proxied_classes{$class} = $self;  | 
| 
646
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     $INC{$module} = $self;  | 
| 
647
 | 
6
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     print "$class used remotely via $self.  Module $module found at $path remotely.\n" if $RMI::DEBUG;      | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
649
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
650
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # used for testing  | 
| 
651
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _remote_has_ref {  | 
| 
653
 | 
3
 | 
 
 | 
 
 | 
  
11
  
 | 
 
 | 
7
 | 
     my ($self,$obj) = @_;  | 
| 
654
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     my $id = "$obj";  | 
| 
655
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     my $has_sent = $self->send_request_and_receive_response('call_eval', 'exists $RMI::executing_nodes[-1]->{_received_objects}{"' . $id . '"}');  | 
| 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _remote_has_sent {  | 
| 
659
 | 
0
 | 
 
 | 
 
 | 
  
6
  
 | 
 
 | 
0
 | 
     my ($self,$obj) = @_;  | 
| 
660
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $id = "$obj";  | 
| 
661
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $has_sent = $self->send_request_and_receive_response('call_eval', 'exists $RMI::executing_nodes[-1]->{_sent_objects}{"' . $id . '"}');  | 
| 
662
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # this generate basic accessors w/o using any other Perl modules which might have proxy effects  | 
| 
665
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
666
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _mk_ro_accessors {  | 
| 
667
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
194
 | 
     no strict 'refs';  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4190
 | 
    | 
| 
668
 | 
94
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
267
 | 
     my $class = caller();  | 
| 
669
 | 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
257
 | 
     for my $p (@_) {  | 
| 
670
 | 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
411
 | 
         my $pname = $p;  | 
| 
671
 | 
262
 | 
  
 50
  
 | 
 
 | 
  
155
  
 | 
 
 | 
989
 | 
         *{$class . '::' . $pname} = sub { die "$pname is read-only!" if @_ > 1; $_[0]->{$pname} };  | 
| 
 
 | 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1970
 | 
    | 
| 
 
 | 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7796
 | 
    | 
| 
 
 | 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1094
 | 
    | 
| 
672
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
673
 | 
34
 | 
 
 | 
 
 | 
  
34
  
 | 
 
 | 
217
 | 
     no warnings;  | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
    | 
| 
 
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3824
 | 
    | 
| 
674
 | 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
282
 | 
     push @{ $class . '::properties'}, @_;  | 
| 
 
 | 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
706
 | 
    | 
| 
675
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
677
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =pod  | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
679
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
680
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
681
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 RMI::Node - base class for RMI::Client and RMI::Server   | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
683
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 VERSION  | 
| 
684
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
685
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This document describes RMI::Node v0.10.  | 
| 
686
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
687
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
688
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
689
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # applications should use B and B  | 
| 
690
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # this example is for new client/server implementors  | 
| 
691
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
692
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     pipe($client_reader, $server_writer);    | 
| 
693
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     pipe($server_reader,  $client_writer);       | 
| 
694
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $server_writer->autoflush(1);  | 
| 
695
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $client_writer->autoflush(1);  | 
| 
696
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
697
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $c = RMI::Node->new(  | 
| 
698
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         reader => $client_reader,  | 
| 
699
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         writer => $client_writer,  | 
| 
700
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
701
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
702
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $s = RMI::Node->new(  | 
| 
703
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         writer => $server_reader,  | 
| 
704
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         reader => $server_writer,  | 
| 
705
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
706
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
707
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     sub main::add { return $_[0] + $_[1] }  | 
| 
708
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
709
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if (fork()) {  | 
| 
710
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # service one request and exit  | 
| 
711
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         require IO::File;  | 
| 
712
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $s->receive_request_and_send_response();  | 
| 
713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         exit;  | 
| 
714
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
715
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
716
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # send one request and get the result  | 
| 
717
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $sum = $c->send_request_and_receive_response('call_function', 'main::add', 5, 6);  | 
| 
718
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
719
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # we might have also done..  | 
| 
720
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $robj = $c->send_request_and_receive_response('call_class_method', 'IO::File', 'new', '/my/file');  | 
| 
721
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
722
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # this only works on objects which are remote proxies:  | 
| 
723
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $txt = $c->send_request_and_receive_response('call_object_method', $robj, 'getline');  | 
| 
724
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       | 
| 
725
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
726
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
727
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is the base class for RMI::Client and RMI::Server.  RMI::Client and RMI::Server  | 
| 
728
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 both implement a wrapper around the RMI::Node interface, with convenience methods  | 
| 
729
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 around initiating the sending or receiving of messages.  | 
| 
730
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
731
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 An RMI::Node object embeds the core methods for bi-directional communication.  | 
| 
732
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Because the server often has to make counter requests of the client, the pair  | 
| 
733
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 will often switch functional roles several times in the process of servicing a  | 
| 
734
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 particular call. This class is not technically abstract, as it is fully functional in  | 
| 
735
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 either the client or server role without subclassing.  Most direct coding against  | 
| 
736
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 this API, however, should be done by implementors of new types of clients/servers.  | 
| 
737
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
738
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See B and B for the API against which application code  | 
| 
739
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 should be written.  See B for an overview of how clients and servers interact.  | 
| 
740
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The documentation in this module will describe the general piping system between  | 
| 
741
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 clients and servers.  | 
| 
742
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
743
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 An RMI::Node requires that the reader/writer handles be explicitly specified at  | 
| 
744
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 construction time.  It also requires and that the code which uses it is be wise  | 
| 
745
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 about calling methods to send and recieve data which do not cause it to block  | 
| 
746
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 indefinitely. :)  | 
| 
747
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
748
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 METHODS  | 
| 
749
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
750
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 new()  | 
| 
751
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     | 
| 
752
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $n = RMI::Node->new(reader => $fh1, writer => $fh2);  | 
| 
753
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
754
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The constructor for RMI::Node objects requires that a reader and writer handle be provided.  They  | 
| 
755
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 can be the same handle if the handle is bi-directional (as with TCP sockets, see L).  | 
| 
756
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
757
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 close()  | 
| 
758
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
759
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $n->close();  | 
| 
760
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
761
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Closes handles, and does any additional required bookeeping.  | 
| 
762
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
763
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 send_request_and_recieve_response()  | 
| 
764
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
765
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  @result = $n->send_request_and_recieve_response($call_type,@data);  | 
| 
766
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
767
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  @result = $n->send_request_and_recieve_response($opts_hashref, $call_type, @data);  | 
| 
768
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
769
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  This is the method behind all of the call_* methods on RMI::Client objects.  | 
| 
770
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  It is also the method behind the proxied objects themselves (in AUTOLOAD).  | 
| 
771
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
772
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  The optional initial hashref allows special serialization control.  It is currently  | 
| 
773
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  only used to force serializing instead of proxying in some cases where this is  | 
| 
774
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  helpful and safe.  | 
| 
775
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
776
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  The call_type maps to the client request, and is one of:  | 
| 
777
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     call_function  | 
| 
778
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     call_class_method  | 
| 
779
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     call_object_method  | 
| 
780
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     call_eval  | 
| 
781
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     call_use  | 
| 
782
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     call_use_lib  | 
| 
783
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
784
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The interpretation of the @data parameters is dependent on the particular call_type, and  | 
| 
785
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 is handled entirely on the remote side.    | 
| 
786
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
787
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 receive_request_and_send_response()  | 
| 
788
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
789
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This method waits for a single request to be received from its reader handle, services  | 
| 
790
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the request, and sends the results through the writer handle.  | 
| 
791
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
792
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 It is possible that, while servicing the request, it will make counter requests, and those  | 
| 
793
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 counter requests, may yield counter-counter-requests which call this method recursively.  | 
| 
794
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
795
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 virtual_lib()  | 
| 
796
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
797
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This method returns an anonymous subroutine which can be used in a "use lib $mysub"  | 
| 
798
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 call, to cause subsequent "use" statements to go through this node to its partner.  | 
| 
799
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
800
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  e.x.:  | 
| 
801
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     use lib RMI::Client::Tcp->new(host=>'myserver',port=>1234)->virtual_lib;  | 
| 
802
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
803
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If a client is constructed for other purposes in the application, the above  | 
| 
804
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 can also be accomplished with: $client->use_lib_remote().  (See L)  | 
| 
805
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
806
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 INTERNALS: MESSAGE TYPES  | 
| 
807
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
808
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The RMI internals are built around sending a "message", which has a type, and an  | 
| 
809
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 array of data. The interpretation of the message data array is based on the message  | 
| 
810
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 type.  | 
| 
811
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
812
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The following message types are passed within the current implementation:  | 
| 
813
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
814
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 query  | 
| 
815
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
816
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 A request that logic execute on the remote side on behalf of the sender.  | 
| 
817
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This includes object method calls, class method calls, function calls,  | 
| 
818
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 remote calls to eval(), and requests that the remote side load modules,  | 
| 
819
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 add library paths, etc.  | 
| 
820
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     | 
| 
821
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is the type for standard remote method invocatons.  | 
| 
822
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     | 
| 
823
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The message data contains, in order:  | 
| 
824
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
825
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  - wantarray    1, '', or undef, depending on the requestor's calling context.  | 
| 
826
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 This is passed to the remote side, and also used on the  | 
| 
827
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 local side to control how results are returned.  | 
| 
828
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
829
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  - object/class A class name, or an object which is a proxy for something on the remote side.  | 
| 
830
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 This value is not present for plain function calls, or evals.  | 
| 
831
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
832
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  - method_name  This is the name of the method to call.  | 
| 
833
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 This is a fully-qualified function name for plain function calls.  | 
| 
834
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
835
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  - param1       The first parameter to the function/method call.  | 
| 
836
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 Note that parameters are "passed" to eval as well by exposing @_.  | 
| 
837
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
838
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  - ...          The next parameter to the function/method call, etc.  | 
| 
839
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
840
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
841
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 result  | 
| 
842
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
843
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The return value from a succesful "query" which does not result in an  | 
| 
844
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 exception being thrown on the remote side.  | 
| 
845
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     | 
| 
846
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The message data contains the return value or values of that query.  | 
| 
847
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     | 
| 
848
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 exception  | 
| 
849
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
850
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The response to a query which resulted in an exception on the remote side.  | 
| 
851
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     | 
| 
852
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The message data contains the value thrown via die() on the remote side.  | 
| 
853
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     | 
| 
854
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 close  | 
| 
855
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
856
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Indicatees that the remote side has closed the connection.  This is actually  | 
| 
857
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 constructed on the receiver end when it fails to read from the input stream.  | 
| 
858
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     | 
| 
859
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The message data is undefined in this case.  | 
| 
860
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
861
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 INTERNALS: WIRE PROTOCOL  | 
| 
862
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
863
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The _send() and _receive() methods are symmetrical.  These two methods are used  | 
| 
864
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 by the public API to encapsulate message transmission and reception.  The _send()  | 
| 
865
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 method takes a message_type and a message_data arrayref, and transmits them to  | 
| 
866
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the other side of the RMI connection. The _receive() method returns a message  | 
| 
867
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 type and message data array.  | 
| 
868
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
869
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Internal to _send() and _receive() the message type and data are passed through  | 
| 
870
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 _serialize and _deserialize and then transmitted along the writer and reader handles.  | 
| 
871
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
872
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The _serialize method turns a message_type and message_data into a string value  | 
| 
873
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 suitable for transmission.  Conversely, the _deserialize method turns a string  | 
| 
874
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 value in the same format into a message_type and message_data array.  | 
| 
875
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
876
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The serialization process has two stages:  | 
| 
877
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
878
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 replacing references with identifiers used for remoting  | 
| 
879
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
880
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 An array of message_data of length n to is converted to have a length of n*2.  | 
| 
881
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Each value is preceded by an integer which categorizes the value.  | 
| 
882
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
883
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   0    a primitive, non-reference value  | 
| 
884
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          | 
| 
885
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        The value itself follows, it is not a reference, and it is passed by-copy.  | 
| 
886
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          | 
| 
887
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   1    an object reference originating on the sender's side  | 
| 
888
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
889
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        A unique identifier for the object follows instead of the object.  | 
| 
890
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        The remote side should construct a transparent proxy which uses that ID.  | 
| 
891
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          | 
| 
892
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   2    a non-object (unblessed) reference originating on the sender's side  | 
| 
893
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          | 
| 
894
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        A unique identifier for the reference follows, instead of the reference.  | 
| 
895
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        The remote side should construct a transparent proxy which uses that ID.  | 
| 
896
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          | 
| 
897
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   3    passing-back a proxy: a reference which originated on the receiver's side  | 
| 
898
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          | 
| 
899
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        The following value is the identifier the remote side sent previously.  | 
| 
900
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        The remote side should substitue the original object when deserializing  | 
| 
901
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
902
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   4    a serialized object  | 
| 
903
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
904
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        This is the result of serializing the reference.  This happens only  | 
| 
905
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        when explicitly requested.  (DBI has some issues with proxies, for instance  | 
| 
906
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        and has customizations in RMI::Proxy::DBI::db to force serialization of  | 
| 
907
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        some connection attributes.)  | 
| 
908
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
909
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        See B for more details on forcing serialization.  | 
| 
910
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
911
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        Note that, because the current wire protocol is to use newline as a record   | 
| 
912
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        separator, we use double-quoted strings to ensure all newlines are escaped.  | 
| 
913
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
914
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Note that all references are turned into primitives by the above process.  | 
| 
915
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
916
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 stringification  | 
| 
917
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
918
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The "wire protocol" for sending and receiving messages is to pass an array via Data::Dumper  | 
| 
919
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 in such a way that it does not contain newlines.  The receiving side uses eval to reconstruct  | 
| 
920
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the original message.  This is terribly inefficient because the structure does not contain  | 
| 
921
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 objects of arbitrary depth, and is parsable without tremendous complexity.  | 
| 
922
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
923
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Details on how proxy objects and references function, and pose as the real item  | 
| 
924
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 in question, are in B, and B and B  | 
| 
925
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
926
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 BUGS AND CAVEATS  | 
| 
927
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
928
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See general bugs in B for general system limitations  | 
| 
929
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
930
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 the serialization mechanism needs to be made more robust and efficient  | 
| 
931
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
932
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 It's really just enough to "work".  | 
| 
933
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
934
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The current implementation uses Data::Dumper with options which should remove  | 
| 
935
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 newlines.  Since we do not flatten arbitrary data structures, a simpler parser  | 
| 
936
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 would be more efficient.  | 
| 
937
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
938
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The message type is currently a text string.  This could be made smaller.  | 
| 
939
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
940
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The data type before each paramter or return value is an integer, which could  | 
| 
941
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 also be abbreviated futher, or we could go the other way and be more clear. :)  | 
| 
942
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
943
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This should switch to sysread and pass the message length instead of relying on  | 
| 
944
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 buffers, since the non-blocking IO might not have issues.  | 
| 
945
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
946
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SEE ALSO  | 
| 
947
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
948
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 B, B, B, B, B  | 
| 
949
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
950
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 B, B, B, B, B  | 
| 
951
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
952
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHORS  | 
| 
953
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
954
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Scott Smith   | 
| 
955
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
956
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT  | 
| 
957
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
958
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Copyright (c) 2008 - 2009 Scott Smith   All rights reserved.  | 
| 
959
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
960
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 LICENSE  | 
| 
961
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
962
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This program is free software; you can redistribute it and/or modify it under  | 
| 
963
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the same terms as Perl itself.  | 
| 
964
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
965
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The full text of the license can be found in the LICENSE file included with this  | 
| 
966
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 module.  | 
| 
967
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
968
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
969
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
970
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
971
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    |