line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::Gnutella;
|
2
|
1
|
|
|
1
|
|
1950
|
use Net::Gnutella::Client;
|
|
1
|
|
|
|
|
8
|
|
|
1
|
|
|
|
|
32
|
|
3
|
1
|
|
|
1
|
|
611
|
use Net::Gnutella::Server;
|
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
30
|
|
4
|
1
|
|
|
1
|
|
6
|
use Net::Gnutella::Event;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
22
|
|
5
|
1
|
|
|
1
|
|
5
|
use IO::Socket;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
4
|
|
6
|
1
|
|
|
1
|
|
24574
|
use IO::Select;
|
|
1
|
|
|
|
|
11034
|
|
|
1
|
|
|
|
|
200
|
|
7
|
1
|
|
|
1
|
|
16
|
use Carp;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
190
|
|
8
|
1
|
|
|
1
|
|
11
|
use strict;
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
53
|
|
9
|
1
|
|
|
1
|
|
7
|
use vars qw/@ISA @EXPORT $VERSION $AUTOLOAD/;
|
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
147
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
$VERSION = $VERSION = "0.1";
|
12
|
|
|
|
|
|
|
|
13
|
1
|
|
|
1
|
|
7
|
use constant GNUTELLA_CONNECT => 1;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
80
|
|
14
|
1
|
|
|
1
|
|
6
|
use constant GNUTELLA_REQUEST => 2;
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
6085
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
require Exporter;
|
17
|
|
|
|
|
|
|
@ISA = qw(Exporter);
|
18
|
|
|
|
|
|
|
@EXPORT = qw(GNUTELLA_CONNECT GNUTELLA_REQUEST);
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# Use AUTOHANDLER to supply generic attribute methods
|
21
|
|
|
|
|
|
|
#
|
22
|
|
|
|
|
|
|
sub AUTOLOAD {
|
23
|
0
|
|
|
0
|
|
|
my $self = shift;
|
24
|
0
|
|
|
|
|
|
my $attr = $AUTOLOAD;
|
25
|
0
|
|
|
|
|
|
$attr =~ s/.*:://;
|
26
|
0
|
0
|
|
|
|
|
return unless $attr =~ /[^A-Z]/; # skip DESTROY and all-cap methods
|
27
|
0
|
0
|
|
|
|
|
croak sprintf "invalid attribute method: %s->%s()", ref($self), $attr unless exists $self->{_attr}->{lc $attr};
|
28
|
0
|
0
|
|
|
|
|
$self->{_attr}->{lc $attr} = shift if @_;
|
29
|
0
|
|
|
|
|
|
return $self->{_attr}->{lc $attr};
|
30
|
|
|
|
|
|
|
}
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub add_handler {
|
33
|
0
|
|
|
0
|
0
|
|
my ($self, $event, $coderef, $replace, @args) = @_;
|
34
|
|
|
|
|
|
|
|
35
|
0
|
|
|
|
|
|
return $self->_add_handler($event, $coderef, $replace, $self->{_handler}, @args);
|
36
|
|
|
|
|
|
|
}
|
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
sub dequeue {
|
39
|
0
|
|
|
0
|
0
|
|
my ($self, $qid) = @_;
|
40
|
|
|
|
|
|
|
|
41
|
0
|
|
|
|
|
|
return delete $self->{_queue}->{$qid};
|
42
|
|
|
|
|
|
|
}
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub do_one_loop {
|
45
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
46
|
|
|
|
|
|
|
|
47
|
0
|
|
|
|
|
|
my $timeout = $self->timeout;
|
48
|
0
|
|
|
|
|
|
my $time = time();
|
49
|
|
|
|
|
|
|
|
50
|
0
|
|
|
|
|
|
foreach my $key ($self->queue) {
|
51
|
0
|
|
|
|
|
|
my $event = $self->queue($key);
|
52
|
|
|
|
|
|
|
|
53
|
0
|
0
|
|
|
|
|
if ($event->[0] <= $time) {
|
54
|
0
|
|
|
|
|
|
$event->[1]->( @{$event}[2..$#{$event}] );
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
|
56
|
0
|
|
|
|
|
|
$self->dequeue($key);
|
57
|
|
|
|
|
|
|
} else {
|
58
|
0
|
|
|
|
|
|
my $nexttimeout = $event->[0] - $time;
|
59
|
|
|
|
|
|
|
|
60
|
0
|
0
|
0
|
|
|
|
$timeout = $nexttimeout if $nexttimeout < $timeout or not $timeout;
|
61
|
|
|
|
|
|
|
}
|
62
|
|
|
|
|
|
|
}
|
63
|
|
|
|
|
|
|
|
64
|
0
|
|
|
|
|
|
my ($rr, $wr, $er) = IO::Select->select(@{$self}{'_read', '_write', '_error'}, $timeout);
|
|
0
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
|
66
|
0
|
|
|
|
|
|
foreach my $sock (@$rr) {
|
67
|
0
|
0
|
|
|
|
|
my $conn = $self->{_connhash}->{read}->{$sock} or next;
|
68
|
|
|
|
|
|
|
|
69
|
0
|
0
|
|
|
|
|
$conn->[0]->($conn->[1] ? ($conn->[1], $sock) : $sock, @{$conn}[2..$#{$conn}]);
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
}
|
71
|
|
|
|
|
|
|
|
72
|
0
|
|
|
|
|
|
foreach my $sock (@$wr) {
|
73
|
0
|
0
|
|
|
|
|
my $conn = $self->{_connhash}->{write}->{$sock} or next;
|
74
|
|
|
|
|
|
|
|
75
|
0
|
0
|
|
|
|
|
$conn->[0]->($conn->[1] ? ($conn->[1], $sock) : $sock, @{$conn}[2..$#{$conn}]);
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
}
|
77
|
|
|
|
|
|
|
}
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# Cache the latest 500 PONG hosts (host:port combinations)
|
80
|
|
|
|
|
|
|
#
|
81
|
|
|
|
|
|
|
sub _host_cache {
|
82
|
0
|
|
|
0
|
|
|
my $self = shift;
|
83
|
|
|
|
|
|
|
|
84
|
0
|
0
|
|
|
|
|
if (@_) {
|
85
|
0
|
|
|
|
|
|
my $time = time();
|
86
|
0
|
|
|
|
|
|
my $count = 500;
|
87
|
0
|
|
|
|
|
|
my $cache = $self->{_host_cache};
|
88
|
0
|
|
|
|
|
|
my $new = {};
|
89
|
0
|
|
|
|
|
|
my $i = 0;
|
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# Add the specified entries
|
92
|
|
|
|
|
|
|
#
|
93
|
0
|
|
|
|
|
|
foreach (@_) {
|
94
|
0
|
|
|
|
|
|
$cache->{$_} = $time;
|
95
|
|
|
|
|
|
|
}
|
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
# Build a new list containing the most recent n elements
|
98
|
|
|
|
|
|
|
#
|
99
|
0
|
|
|
|
|
|
foreach (grep { $i++ < $count } sort { $cache->{$b} <=> $cache->{$a} } keys %{$cache}) {
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
100
|
0
|
|
|
|
|
|
$new->{$_} = $cache->{$_};
|
101
|
|
|
|
|
|
|
}
|
102
|
|
|
|
|
|
|
|
103
|
0
|
|
|
|
|
|
$self->{_host_cache} = $new;
|
104
|
|
|
|
|
|
|
}
|
105
|
|
|
|
|
|
|
|
106
|
0
|
|
|
|
|
|
return keys %{ $self->{_host_cache} };
|
|
0
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
}
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub connections {
|
110
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
111
|
0
|
|
|
|
|
|
my @ret;
|
112
|
|
|
|
|
|
|
|
113
|
0
|
|
|
|
|
|
foreach my $key (keys %{ $self->{_connhash}->{all} }) {
|
|
0
|
|
|
|
|
|
|
114
|
0
|
|
|
|
|
|
my $conn = $self->{_connhash}->{all}->{$key};
|
115
|
|
|
|
|
|
|
|
116
|
0
|
0
|
|
|
|
|
next unless ref $conn eq "Net::Gnutella::Connection";
|
117
|
0
|
0
|
|
|
|
|
next unless $conn->connected;
|
118
|
|
|
|
|
|
|
|
119
|
0
|
|
|
|
|
|
push @ret, $conn;
|
120
|
|
|
|
|
|
|
}
|
121
|
|
|
|
|
|
|
|
122
|
0
|
|
|
|
|
|
return @ret;
|
123
|
|
|
|
|
|
|
}
|
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub new {
|
126
|
0
|
|
|
0
|
0
|
|
my $class = shift;
|
127
|
0
|
|
|
|
|
|
my %args = @_;
|
128
|
|
|
|
|
|
|
|
129
|
0
|
|
|
|
|
|
my $self = {
|
130
|
|
|
|
|
|
|
_connhash => {
|
131
|
|
|
|
|
|
|
read => {},
|
132
|
|
|
|
|
|
|
write => {},
|
133
|
|
|
|
|
|
|
all => {},
|
134
|
|
|
|
|
|
|
},
|
135
|
|
|
|
|
|
|
_read => new IO::Select,
|
136
|
|
|
|
|
|
|
_write => new IO::Select,
|
137
|
|
|
|
|
|
|
_attr => {
|
138
|
|
|
|
|
|
|
timeout => 10,
|
139
|
|
|
|
|
|
|
debug => 0,
|
140
|
0
|
|
|
|
|
|
id => [ map { rand(65535**2) } 0..4 ],
|
141
|
|
|
|
|
|
|
},
|
142
|
|
|
|
|
|
|
_handler => {},
|
143
|
|
|
|
|
|
|
_host_cache => {},
|
144
|
|
|
|
|
|
|
_msgid_source => {},
|
145
|
|
|
|
|
|
|
_qid => 'a',
|
146
|
|
|
|
|
|
|
_queue => {},
|
147
|
|
|
|
|
|
|
};
|
148
|
|
|
|
|
|
|
|
149
|
0
|
|
|
|
|
|
bless $self, $class;
|
150
|
|
|
|
|
|
|
|
151
|
0
|
|
|
|
|
|
foreach my $key (keys %args) {
|
152
|
0
|
|
|
|
|
|
my $lkey = lc $key;
|
153
|
|
|
|
|
|
|
|
154
|
0
|
|
|
|
|
|
$self->$lkey($args{$key});
|
155
|
|
|
|
|
|
|
}
|
156
|
|
|
|
|
|
|
|
157
|
0
|
|
|
|
|
|
return $self;
|
158
|
|
|
|
|
|
|
}
|
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub new_client {
|
161
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
162
|
0
|
|
|
|
|
|
my $conn = Net::Gnutella::Client->new($self, @_);
|
163
|
|
|
|
|
|
|
|
164
|
0
|
0
|
|
|
|
|
return if $conn->error;
|
165
|
0
|
|
|
|
|
|
return $conn;
|
166
|
|
|
|
|
|
|
}
|
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub new_server {
|
169
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
170
|
0
|
|
|
|
|
|
my $conn = Net::Gnutella::Server->new($self, @_);
|
171
|
|
|
|
|
|
|
|
172
|
0
|
0
|
|
|
|
|
return if $conn->error;
|
173
|
0
|
|
|
|
|
|
return $conn;
|
174
|
|
|
|
|
|
|
}
|
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
sub queue {
|
177
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
178
|
|
|
|
|
|
|
|
179
|
0
|
0
|
|
|
|
|
if (@_) {
|
180
|
0
|
|
|
|
|
|
return $self->{_queue}->{$_[0]};
|
181
|
|
|
|
|
|
|
} else {
|
182
|
0
|
|
|
|
|
|
return keys %{ $self->{_queue} };
|
|
0
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
}
|
184
|
|
|
|
|
|
|
}
|
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub schedule {
|
187
|
0
|
|
|
0
|
0
|
|
my ($self, $when, $coderef, @args) = @_;
|
188
|
|
|
|
|
|
|
|
189
|
0
|
0
|
|
|
|
|
unless ($when =~ /^\d+[dhmst]$/i) {
|
190
|
0
|
|
|
|
|
|
croak "First argument must be a number";
|
191
|
|
|
|
|
|
|
}
|
192
|
|
|
|
|
|
|
|
193
|
0
|
0
|
0
|
|
|
|
unless (defined $coderef && ref $coderef eq 'CODE') {
|
194
|
0
|
|
|
|
|
|
croak "Second argument must be a coderef!";
|
195
|
|
|
|
|
|
|
}
|
196
|
|
|
|
|
|
|
|
197
|
0
|
|
|
|
|
|
my $time = time();
|
198
|
|
|
|
|
|
|
|
199
|
0
|
0
|
|
|
|
|
$when *= 24*60*60 if $when =~ s/d$//i;
|
200
|
0
|
0
|
|
|
|
|
$when *= 60*60 if $when =~ s/h$//i;
|
201
|
0
|
0
|
|
|
|
|
$when *= 60 if $when =~ s/m$//i;
|
202
|
0
|
|
|
|
|
|
$when =~ s/s$//i;
|
203
|
|
|
|
|
|
|
|
204
|
0
|
0
|
|
|
|
|
if ($when =~ s/t$//i) {
|
205
|
0
|
|
|
|
|
|
$time = $when;
|
206
|
|
|
|
|
|
|
} else {
|
207
|
0
|
|
|
|
|
|
$time += $when;
|
208
|
|
|
|
|
|
|
}
|
209
|
|
|
|
|
|
|
|
210
|
0
|
0
|
|
|
|
|
$self->{_qid} = 'a' if $self->{_qid} eq 'zzzzzzzz';
|
211
|
|
|
|
|
|
|
|
212
|
0
|
|
|
|
|
|
my $id = $self->{_qid}++;
|
213
|
0
|
|
|
|
|
|
$self->{_queue}->{$id} = [ $time, $coderef, @args ];
|
214
|
0
|
|
|
|
|
|
return $id;
|
215
|
|
|
|
|
|
|
}
|
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
# Returns the connection a msgid originated from if it
|
218
|
|
|
|
|
|
|
# has been seen previously.
|
219
|
|
|
|
|
|
|
#
|
220
|
|
|
|
|
|
|
sub _msgid_source {
|
221
|
0
|
|
|
0
|
|
|
my ($self, $msgid, $conn) = @_;
|
222
|
|
|
|
|
|
|
|
223
|
0
|
0
|
0
|
|
|
|
unless ($msgid && ref($msgid) eq 'ARRAY') {
|
224
|
0
|
|
|
|
|
|
carp "Invalid message ID: $msgid";
|
225
|
|
|
|
|
|
|
}
|
226
|
|
|
|
|
|
|
|
227
|
0
|
0
|
|
|
|
|
if ($conn) {
|
228
|
0
|
|
|
|
|
|
my $i = 0;
|
229
|
0
|
|
|
|
|
|
my $count = 5000;
|
230
|
0
|
|
|
|
|
|
my $source = $self->{_msgid_source};
|
231
|
|
|
|
|
|
|
|
232
|
0
|
|
|
|
|
|
$source->{join(":", @$msgid)} = [ $conn, time() ];
|
233
|
|
|
|
|
|
|
|
234
|
0
|
|
|
|
|
|
foreach (grep { $i++ > $count } sort { $source->{$b}->[1] <=> $source->{$a}->[1] } keys %{$source}) {
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
235
|
0
|
|
|
|
|
|
delete $source->{$_};
|
236
|
|
|
|
|
|
|
}
|
237
|
|
|
|
|
|
|
}
|
238
|
|
|
|
|
|
|
|
239
|
0
|
0
|
|
|
|
|
return unless $self->{_msgid_source}->{join(":", @$msgid)};
|
240
|
0
|
|
|
|
|
|
return $self->{_msgid_source}->{join(":", @$msgid)}->[0];
|
241
|
|
|
|
|
|
|
}
|
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
sub start {
|
244
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
245
|
|
|
|
|
|
|
|
246
|
0
|
|
|
|
|
|
$self->do_one_loop while 1;
|
247
|
|
|
|
|
|
|
}
|
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
sub _add_fh {
|
250
|
0
|
|
|
0
|
|
|
my ($self, $fh, $coderef, $flags, $obj, @args) = @_;
|
251
|
|
|
|
|
|
|
|
252
|
0
|
0
|
|
|
|
|
unless (ref $coderef eq "CODE") {
|
253
|
0
|
|
|
|
|
|
croak "Second argument to ->_add_fh not a coderef";
|
254
|
|
|
|
|
|
|
}
|
255
|
|
|
|
|
|
|
|
256
|
0
|
|
0
|
|
|
|
$flags ||= 'r';
|
257
|
|
|
|
|
|
|
|
258
|
0
|
0
|
|
|
|
|
if ($flags =~ /r/i) {
|
259
|
0
|
|
|
|
|
|
$self->{_read}->add($fh);
|
260
|
0
|
|
|
|
|
|
$self->{_connhash}->{read}->{$fh} = [ $coderef, $obj, @args ];
|
261
|
|
|
|
|
|
|
}
|
262
|
|
|
|
|
|
|
|
263
|
0
|
0
|
|
|
|
|
if ($flags =~ /w/i) {
|
264
|
0
|
|
|
|
|
|
$self->{_write}->add($fh);
|
265
|
0
|
|
|
|
|
|
$self->{_connhash}->{write}->{$fh} = [ $coderef, $obj, @args ];
|
266
|
|
|
|
|
|
|
}
|
267
|
|
|
|
|
|
|
|
268
|
0
|
|
|
|
|
|
$self->{_connhash}->{all}->{$fh} = $obj;
|
269
|
|
|
|
|
|
|
}
|
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
sub _add_handler {
|
272
|
0
|
|
|
0
|
|
|
my ($self, $event, $coderef, $replace, $hashref, @args) = @_;
|
273
|
|
|
|
|
|
|
|
274
|
0
|
0
|
|
|
|
|
unless (ref $coderef eq "CODE") {
|
275
|
0
|
|
|
|
|
|
croak "Second argument to ->_add_handler not a coderef";
|
276
|
|
|
|
|
|
|
}
|
277
|
|
|
|
|
|
|
|
278
|
0
|
|
|
|
|
|
my %define = ( replace=>0, before=>1, after=>2 );
|
279
|
|
|
|
|
|
|
|
280
|
0
|
0
|
|
|
|
|
if (not defined $replace) {
|
|
|
0
|
|
|
|
|
|
281
|
0
|
|
|
|
|
|
$replace = 2;
|
282
|
|
|
|
|
|
|
} elsif ($replace =~ /^\D/) {
|
283
|
0
|
|
0
|
|
|
|
$replace = $define{lc $replace} || 2;
|
284
|
|
|
|
|
|
|
}
|
285
|
|
|
|
|
|
|
|
286
|
0
|
0
|
|
|
|
|
foreach my $ev (ref $event eq "ARRAY" ? @{$event} : $event) {
|
|
0
|
|
|
|
|
|
|
287
|
0
|
0
|
|
|
|
|
if ($ev =~ /^\d/) {
|
288
|
0
|
|
|
|
|
|
$ev = Net::Gnutella::Event->trans($ev);
|
289
|
|
|
|
|
|
|
|
290
|
0
|
0
|
|
|
|
|
unless ($ev) {
|
291
|
0
|
|
|
|
|
|
carp "Unknown event type in ->add_handler";
|
292
|
0
|
|
|
|
|
|
return;
|
293
|
|
|
|
|
|
|
}
|
294
|
|
|
|
|
|
|
}
|
295
|
|
|
|
|
|
|
|
296
|
0
|
|
|
|
|
|
$hashref->{lc $ev} = [ $coderef, $replace, @args ];
|
297
|
|
|
|
|
|
|
}
|
298
|
|
|
|
|
|
|
}
|
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
sub _handler {
|
301
|
0
|
|
|
0
|
|
|
my ($self, $event) = @_;
|
302
|
0
|
|
|
|
|
|
my $handler;
|
303
|
|
|
|
|
|
|
|
304
|
0
|
0
|
|
|
|
|
unless ($event) {
|
305
|
0
|
|
|
|
|
|
confess "I messed up";
|
306
|
|
|
|
|
|
|
}
|
307
|
|
|
|
|
|
|
|
308
|
0
|
|
|
|
|
|
my $type = $event->type;
|
309
|
0
|
|
|
|
|
|
my $conn = $event->from;
|
310
|
0
|
0
|
|
|
|
|
my $default = $conn->can('_default') if $conn;
|
311
|
|
|
|
|
|
|
|
312
|
0
|
0
|
0
|
|
|
|
if ($conn && exists $conn->{_handler}->{$type}) {
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
313
|
0
|
0
|
|
|
|
|
printf STDERR " - Connection wide handler exists\n" if $self->debug >= 2;
|
314
|
0
|
|
|
|
|
|
$handler = $conn->{_handler}->{$type};
|
315
|
|
|
|
|
|
|
} elsif (exists $self->{_handler}->{$type}) {
|
316
|
0
|
0
|
|
|
|
|
printf STDERR " - Global handler exists\n" if $self->debug >= 2;
|
317
|
0
|
|
|
|
|
|
$handler = $self->{_handler}->{$type};
|
318
|
|
|
|
|
|
|
} elsif ($default) {
|
319
|
0
|
0
|
|
|
|
|
printf STDERR " - Calling default handler on connection\n" if $self->debug >= 2;
|
320
|
0
|
|
|
|
|
|
return $conn->_default($event);
|
321
|
|
|
|
|
|
|
} else {
|
322
|
0
|
0
|
|
|
|
|
printf STDERR " - Calling default global handler\n" if $self->debug >= 2;
|
323
|
0
|
|
|
|
|
|
return $self->_default($event);
|
324
|
|
|
|
|
|
|
}
|
325
|
|
|
|
|
|
|
|
326
|
0
|
|
|
|
|
|
my ($coderef, $replace, @args) = @$handler;
|
327
|
|
|
|
|
|
|
|
328
|
0
|
0
|
|
|
|
|
if ($replace == 0) { # REPLACE
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
329
|
0
|
|
|
|
|
|
$coderef->($conn, $event, @args);
|
330
|
|
|
|
|
|
|
} elsif ($replace == 1) { # BEFORE
|
331
|
0
|
0
|
|
|
|
|
$coderef->($conn, $event, @args) or return;
|
332
|
|
|
|
|
|
|
|
333
|
0
|
0
|
|
|
|
|
if ($default) {
|
334
|
0
|
|
|
|
|
|
$conn->_default($event, @args);
|
335
|
|
|
|
|
|
|
} else {
|
336
|
0
|
|
|
|
|
|
$self->_default($event, @args);
|
337
|
|
|
|
|
|
|
}
|
338
|
|
|
|
|
|
|
} elsif ($replace == 2) { # AFTER
|
339
|
0
|
0
|
|
|
|
|
if ($default) {
|
340
|
0
|
0
|
|
|
|
|
$conn->_default($event, @args) or return;
|
341
|
|
|
|
|
|
|
} else {
|
342
|
0
|
0
|
|
|
|
|
$self->_default($event, @args) or return;
|
343
|
|
|
|
|
|
|
}
|
344
|
|
|
|
|
|
|
|
345
|
0
|
|
|
|
|
|
$coderef->($conn, $event, @args);
|
346
|
|
|
|
|
|
|
}
|
347
|
|
|
|
|
|
|
}
|
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
sub _remove_fh {
|
350
|
0
|
|
|
0
|
|
|
my ($self, $fh, $flags) = @_;
|
351
|
|
|
|
|
|
|
|
352
|
0
|
|
0
|
|
|
|
$flags ||= 'r';
|
353
|
|
|
|
|
|
|
|
354
|
0
|
0
|
|
|
|
|
if ($flags =~ /r/i) {
|
355
|
0
|
|
|
|
|
|
$self->{_read}->remove($fh);
|
356
|
0
|
|
|
|
|
|
delete $self->{_connhash}->{read}->{$fh};
|
357
|
|
|
|
|
|
|
}
|
358
|
|
|
|
|
|
|
|
359
|
0
|
0
|
|
|
|
|
if ($flags =~ /w/i) {
|
360
|
0
|
|
|
|
|
|
$self->{_write}->remove($fh);
|
361
|
0
|
|
|
|
|
|
delete $self->{_connhash}->{write}->{$fh};
|
362
|
|
|
|
|
|
|
}
|
363
|
|
|
|
|
|
|
}
|
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
1;
|