line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=head1 NAME |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
AnyEvent::SNMP - adaptor to integrate Net::SNMP into AnyEvent. |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 SYNOPSIS |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
use AnyEvent::SNMP; |
8
|
|
|
|
|
|
|
use Net::SNMP; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# just use Net::SNMP and AnyEvent as you like: |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# use a condvar to transfer results, this is |
13
|
|
|
|
|
|
|
# just an example, you can use a naked callback as well. |
14
|
|
|
|
|
|
|
my $cv = AnyEvent->condvar; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
# ... start non-blocking snmp request(s)... |
17
|
|
|
|
|
|
|
Net::SNMP->session (-hostname => "127.0.0.1", |
18
|
|
|
|
|
|
|
-community => "public", |
19
|
|
|
|
|
|
|
-nonblocking => 1) |
20
|
|
|
|
|
|
|
->get_request (-callback => sub { $cv->send (@_) }); |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# ... do something else until the result is required |
23
|
|
|
|
|
|
|
my @result = $cv->wait; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 DESCRIPTION |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
This module implements an alternative "event dispatcher" for Net::SNMP, |
28
|
|
|
|
|
|
|
using AnyEvent as a backend. This integrates Net::SNMP into AnyEvent. That |
29
|
|
|
|
|
|
|
means you can make non-blocking Net::SNMP calls and as long as other |
30
|
|
|
|
|
|
|
parts of your program also use AnyEvent (or some event loop supported by |
31
|
|
|
|
|
|
|
AnyEvent), they will run in parallel. |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
Also, the Net::SNMP scheduler is very inefficient with respect to both CPU |
34
|
|
|
|
|
|
|
and memory usage. Most AnyEvent backends (including the pure-perl backend) |
35
|
|
|
|
|
|
|
fare much better than the Net::SNMP dispatcher. |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
Another major added feature of this module over Net::SNMP is automatic |
38
|
|
|
|
|
|
|
rate-adjustments: Net::SNMP is so slow that firing a few thousand |
39
|
|
|
|
|
|
|
requests can cause many timeouts simply because Net::SNMP cannot process |
40
|
|
|
|
|
|
|
the replies in time. This module automatically adapts the send rate to |
41
|
|
|
|
|
|
|
avoid false timeouts caused by slow reply processing. |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
A potential disadvantage of this module is that replacing the dispatcher |
44
|
|
|
|
|
|
|
is not at all a documented thing to do, so future changes in Net::SNMP |
45
|
|
|
|
|
|
|
might break this module (or the many similar ones). |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
This module does not export anything and does not require you to do |
48
|
|
|
|
|
|
|
anything special apart from loading it I
|
49
|
|
|
|
|
|
|
requests with Net::SNMP>. It is recommended but not required to load this |
50
|
|
|
|
|
|
|
module before C. |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
=head1 GLOBAL VARIABLES |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=over 4 |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=item $AnyEvent::SNMP::MAX_OUTSTANDING (default: C<50>, dynamic) |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=item AnyEvent::SNMP::set_max_outstanding $new_value |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
Use this package variable to restrict the number of outstanding SNMP |
61
|
|
|
|
|
|
|
requests at any point in time. |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
Net::SNMP is very fast at creating and sending SNMP requests, but much |
64
|
|
|
|
|
|
|
slower at parsing (big, bulk) responses. This makes it easy to request a |
65
|
|
|
|
|
|
|
lot of data that can take many seconds to parse. |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
In the best case, this can lead to unnecessary delays (and even time-outs, |
68
|
|
|
|
|
|
|
as the data has been received but not yet processed) and in the worst |
69
|
|
|
|
|
|
|
case, this can lead to packet loss, when the receive queue overflows and |
70
|
|
|
|
|
|
|
the kernel can no longer accept new packets. |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
To avoid this, you can (and should) limit the number of outstanding |
73
|
|
|
|
|
|
|
requests to a number low enough so that parsing time doesn't introduce |
74
|
|
|
|
|
|
|
noticeable delays. |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
Unfortunately, this number depends not only on processing speed and load |
77
|
|
|
|
|
|
|
of the machine running Net::SNMP, but also on the network latency and the |
78
|
|
|
|
|
|
|
speed of your SNMP agents. |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
AnyEvent::SNMP tries to dynamically adjust this number upwards and |
81
|
|
|
|
|
|
|
downwards. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
Increasing C<$MAX_OUTSTANDING> will not automatically use the |
84
|
|
|
|
|
|
|
extra request slots. To increase C<$MAX_OUTSTANDING> and make |
85
|
|
|
|
|
|
|
C make use of the extra parallelity, call |
86
|
|
|
|
|
|
|
C with the new value, e.g.: |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
AnyEvent::SNMP::set_max_outstanding 500; |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
Although due to the dynamic adjustment, this might have little lasting |
91
|
|
|
|
|
|
|
effect. |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
Note that you can use L to speed up parsing of responses |
94
|
|
|
|
|
|
|
considerably. |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=item $AnyEvent::SNMP::MIN_RECVQUEUE (default: C<8>) |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=item $AnyEvent::SNMP::MAX_RECVQUEUE (default: C<64>) |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
These values specify the minimum and maximum receive queue length (in |
101
|
|
|
|
|
|
|
units of one response packet). |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
When AnyEvent::SNMP handles $MAX_RECVQUEUE or more packets per iteration |
104
|
|
|
|
|
|
|
it will reduce $MAX_OUTSTANDING. If it handles less than $MIN_RECVQUEUE, |
105
|
|
|
|
|
|
|
it increases $MAX_OUTSTANDING. |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
This has the result of adjusting the number of outstanding requests so that |
108
|
|
|
|
|
|
|
the recv queue is between the minimum and maximum, usually. |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
This algorithm works reasonably well as long as the responses, response |
111
|
|
|
|
|
|
|
latencies and processing times are the same per packet on average. |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=back |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=head1 COMPATIBILITY |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
This module may be used as a drop in replacement for the |
118
|
|
|
|
|
|
|
Net::SNMP::Dispatcher in existing programs. You can still call |
119
|
|
|
|
|
|
|
C to start the event-loop, but then you loose the benefit |
120
|
|
|
|
|
|
|
of mixing Net::SNMP events with other events. |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
use AnyEvent::SNMP; |
123
|
|
|
|
|
|
|
use Net::SNMP; |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
# just use Net::SNMP as before |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# ... start non-blocking snmp request(s)... |
128
|
|
|
|
|
|
|
Net::SNMP->session ( |
129
|
|
|
|
|
|
|
-hostname => "127.0.0.1", |
130
|
|
|
|
|
|
|
-community => "public", |
131
|
|
|
|
|
|
|
-nonblocking => 1, |
132
|
|
|
|
|
|
|
)->get_request (-callback => sub { ... }); |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
snmp_dispatcher; |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=cut |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
package AnyEvent::SNMP; |
139
|
|
|
|
|
|
|
|
140
|
1
|
|
|
1
|
|
855
|
use common::sense; |
|
1
|
|
|
|
|
10
|
|
|
1
|
|
|
|
|
5
|
|
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# it is possible to do this without loading |
143
|
|
|
|
|
|
|
# Net::SNMP::Dispatcher, but much more awkward. |
144
|
1
|
|
|
1
|
|
468
|
use Net::SNMP::Dispatcher; |
|
1
|
|
|
|
|
52301
|
|
|
1
|
|
|
|
|
66
|
|
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
# we could inherit fro Net:SNMP::Dispatcher, but since this is undocumented, |
147
|
|
|
|
|
|
|
# I'd rather see it die (and reported) than silenty and subtly fail. |
148
|
|
|
|
|
|
|
*msg_handle_alloc = \&Net::SNMP::Dispatcher::msg_handle_alloc; |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub Net::SNMP::Dispatcher::instance { |
151
|
2
|
|
|
2
|
0
|
2596
|
AnyEvent::SNMP:: |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
1
|
|
|
1
|
|
709
|
use Net::SNMP (); |
|
1
|
|
|
|
|
7942
|
|
|
1
|
|
|
|
|
21
|
|
155
|
1
|
|
|
1
|
|
840
|
use AnyEvent (); |
|
1
|
|
|
|
|
4335
|
|
|
1
|
|
|
|
|
1387
|
|
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
our $VERSION = '6.02'; |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
$Net::SNMP::DISPATCHER = instance Net::SNMP::Dispatcher; |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
our $MESSAGE_PROCESSING = $Net::SNMP::Dispatcher::MESSAGE_PROCESSING; |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
our $BUSY; |
164
|
|
|
|
|
|
|
our $DONE; # finished all jobs |
165
|
|
|
|
|
|
|
our @TRANSPORT; # fileno => [count, watcher] |
166
|
|
|
|
|
|
|
our @QUEUE; |
167
|
|
|
|
|
|
|
our $MAX_OUTSTANDING = 50; |
168
|
|
|
|
|
|
|
our $MIN_RECVQUEUE = 8; |
169
|
|
|
|
|
|
|
our $MAX_RECVQUEUE = 64; |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub kick_job; |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub _send_pdu { |
174
|
0
|
|
|
0
|
|
|
my ($pdu, $retries) = @_; |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
# mostly copied from Net::SNMP::Dispatch |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
# Pass the PDU to Message Processing so that it can |
179
|
|
|
|
|
|
|
# create the new outgoing message. |
180
|
0
|
|
|
|
|
|
my $msg = $MESSAGE_PROCESSING->prepare_outgoing_msg ($pdu); |
181
|
|
|
|
|
|
|
|
182
|
0
|
0
|
|
|
|
|
if (!defined $msg) { |
183
|
0
|
|
|
|
|
|
--$BUSY; |
184
|
0
|
|
|
|
|
|
kick_job; |
185
|
|
|
|
|
|
|
# Inform the command generator about the Message Processing error. |
186
|
0
|
|
|
|
|
|
$pdu->status_information ($MESSAGE_PROCESSING->error); |
187
|
0
|
|
|
|
|
|
return; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# Actually send the message. |
191
|
0
|
0
|
|
|
|
|
if (!defined $msg->send) { |
192
|
0
|
0
|
|
|
|
|
$MESSAGE_PROCESSING->msg_handle_delete ($pdu->msg_id) |
193
|
|
|
|
|
|
|
if $pdu->expect_response; |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
# A crude attempt to recover from temporary failures. |
196
|
0
|
0
|
0
|
|
|
|
if ($retries-- > 0 && ($!{EAGAIN} || $!{EWOULDBLOCK} || $!{ENOSPC})) { |
|
|
|
0
|
|
|
|
|
197
|
0
|
|
|
|
|
|
my $retry_w; $retry_w = AE::timer $pdu->timeout, 0, sub { |
198
|
0
|
|
|
0
|
|
|
undef $retry_w; |
199
|
0
|
|
|
|
|
|
_send_pdu ($pdu, $retries); |
200
|
0
|
|
|
|
|
|
}; |
201
|
|
|
|
|
|
|
} else { |
202
|
0
|
|
|
|
|
|
--$BUSY; |
203
|
0
|
|
|
|
|
|
kick_job; |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
# Inform the command generator about the send() error. |
207
|
0
|
|
|
|
|
|
$pdu->status_information ($msg->error); |
208
|
0
|
|
|
|
|
|
return; |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
# Schedule the timeout handler if the message expects a response. |
212
|
0
|
0
|
|
|
|
|
if ($pdu->expect_response) { |
213
|
0
|
|
|
|
|
|
my $transport = $msg->transport; |
214
|
0
|
|
|
|
|
|
my $fileno = $transport->fileno; |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
# register the transport |
217
|
0
|
0
|
|
|
|
|
unless ($TRANSPORT[$fileno][0]++) { |
218
|
|
|
|
|
|
|
$TRANSPORT[$fileno][1] = AE::io $transport->socket, 0, sub { |
219
|
0
|
|
|
0
|
|
|
for my $count (1..$MAX_RECVQUEUE) { # handle up to this many requests in one go |
220
|
|
|
|
|
|
|
# Create a new Message object to receive the response |
221
|
0
|
|
|
|
|
|
my ($msg, $error) = Net::SNMP::Message->new (-transport => $transport); |
222
|
|
|
|
|
|
|
|
223
|
0
|
0
|
|
|
|
|
if (!defined $msg) { |
224
|
0
|
|
|
|
|
|
die sprintf 'Failed to create Message object [%s]', $error; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# Read the message from the Transport Layer |
228
|
0
|
0
|
|
|
|
|
if (!defined $msg->recv) { |
229
|
0
|
0
|
|
|
|
|
if ($transport->connectionless) { |
230
|
|
|
|
|
|
|
# if we handled very few replies and we have queued work, try |
231
|
|
|
|
|
|
|
# to increase the parallelity as we probably can handle more. |
232
|
0
|
0
|
0
|
|
|
|
if ($count < $MIN_RECVQUEUE && @QUEUE) { |
233
|
0
|
|
|
|
|
|
++$MAX_OUTSTANDING; |
234
|
0
|
|
|
|
|
|
kick_job; |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
} else { |
237
|
|
|
|
|
|
|
# for some reason, connected-oriented transports seem to need this |
238
|
0
|
0
|
|
|
|
|
delete $TRANSPORT[$fileno] |
239
|
|
|
|
|
|
|
unless --$TRANSPORT[$fileno][0]; |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
0
|
|
|
|
|
|
$msg->error; |
243
|
0
|
|
|
|
|
|
return; |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
# For connection-oriented Transport Domains, it is possible to |
247
|
|
|
|
|
|
|
# "recv" an empty buffer if reassembly is required. |
248
|
0
|
0
|
|
|
|
|
if (!$msg->length) { |
249
|
0
|
|
|
|
|
|
return; |
250
|
|
|
|
|
|
|
} |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
# Hand the message over to Message Processing. |
253
|
0
|
0
|
|
|
|
|
if (!defined $MESSAGE_PROCESSING->prepare_data_elements ($msg)) { |
254
|
0
|
|
|
|
|
|
$MESSAGE_PROCESSING->error; |
255
|
0
|
|
|
|
|
|
return; |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
# Set the error if applicable. |
259
|
0
|
0
|
|
|
|
|
$msg->error ($MESSAGE_PROCESSING->error) if $MESSAGE_PROCESSING->error; |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
# Notify the command generator to process the response. |
262
|
|
|
|
|
|
|
# Net::SNMP calls process_response_pdu, which simply calls callback_execute, |
263
|
|
|
|
|
|
|
# but some errors cause $msg to be of type Net::SNMP::Message, not Net::SMMP::PDU, |
264
|
|
|
|
|
|
|
# so we call the underlying callback_execute method which exists on both and |
265
|
|
|
|
|
|
|
# seems to do the right thing. |
266
|
0
|
|
|
|
|
|
$msg->callback_execute; |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
# Cancel the timeout. |
269
|
0
|
|
|
|
|
|
my $rtimeout_w = $msg->timeout_id; |
270
|
0
|
0
|
|
|
|
|
if ($$rtimeout_w) { |
271
|
0
|
|
|
|
|
|
undef $$rtimeout_w; |
272
|
|
|
|
|
|
|
|
273
|
0
|
|
|
|
|
|
--$BUSY; |
274
|
0
|
|
|
|
|
|
kick_job; |
275
|
|
|
|
|
|
|
|
276
|
0
|
0
|
|
|
|
|
unless (--$TRANSPORT[$fileno][0]) { |
277
|
0
|
|
|
|
|
|
delete $TRANSPORT[$fileno]; |
278
|
0
|
|
|
|
|
|
return; |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
# when we end up here, we successfully handled $MAX_RECVQUEUE |
284
|
|
|
|
|
|
|
# replies in one iteration, so assume we are overloaded |
285
|
|
|
|
|
|
|
# and reduce the amount of parallelity. |
286
|
0
|
|
0
|
|
|
|
$MAX_OUTSTANDING = (int $MAX_OUTSTANDING * 0.95) || 1; |
287
|
0
|
|
|
|
|
|
}; |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
$msg->timeout_id (\(my $rtimeout_w = |
291
|
|
|
|
|
|
|
AE::timer $pdu->timeout, 0, sub { |
292
|
0
|
|
|
0
|
|
|
my $rtimeout_w = $msg->timeout_id; |
293
|
0
|
0
|
|
|
|
|
if ($$rtimeout_w) { |
294
|
0
|
|
|
|
|
|
undef $$rtimeout_w; |
295
|
0
|
0
|
|
|
|
|
delete $TRANSPORT[$fileno] |
296
|
|
|
|
|
|
|
unless --$TRANSPORT[$fileno][0]; |
297
|
|
|
|
|
|
|
} |
298
|
|
|
|
|
|
|
|
299
|
0
|
0
|
|
|
|
|
if ($retries--) { |
300
|
0
|
|
|
|
|
|
_send_pdu ($pdu, $retries); |
301
|
|
|
|
|
|
|
} else { |
302
|
0
|
|
|
|
|
|
$MESSAGE_PROCESSING->msg_handle_delete ($pdu->msg_id); |
303
|
0
|
|
|
|
|
|
$pdu->status_information ("No response from remote host '%s'", $pdu->hostname); |
304
|
|
|
|
|
|
|
|
305
|
0
|
|
|
|
|
|
--$BUSY; |
306
|
0
|
|
|
|
|
|
kick_job; |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
}) |
309
|
0
|
|
|
|
|
|
); |
310
|
|
|
|
|
|
|
} else { |
311
|
0
|
|
|
|
|
|
--$BUSY; |
312
|
0
|
|
|
|
|
|
kick_job; |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
sub kick_job { |
317
|
0
|
|
|
0
|
0
|
|
while ($BUSY < $MAX_OUTSTANDING) { |
318
|
0
|
0
|
|
|
|
|
my $pdu = shift @QUEUE |
319
|
|
|
|
|
|
|
or last; |
320
|
|
|
|
|
|
|
|
321
|
0
|
|
|
|
|
|
++$BUSY; |
322
|
0
|
|
|
|
|
|
_send_pdu $pdu, $pdu->retries; |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
|
325
|
0
|
0
|
0
|
|
|
|
$DONE and $DONE->() unless $BUSY; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
sub send_pdu($$$) { |
329
|
0
|
|
|
0
|
0
|
|
my (undef, $pdu, $delay) = @_; |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
# $delay is not very sensibly implemented by AnyEvent::SNMP, |
332
|
|
|
|
|
|
|
# but apparently it is not a very sensible feature. |
333
|
0
|
0
|
|
|
|
|
if ($delay > 0) { |
334
|
0
|
|
|
|
|
|
++$BUSY; |
335
|
0
|
|
|
|
|
|
my $delay_w; $delay_w = AE::timer $delay, 0, sub { |
336
|
0
|
|
|
0
|
|
|
undef $delay_w; |
337
|
0
|
|
|
|
|
|
push @QUEUE, $pdu; |
338
|
0
|
|
|
|
|
|
--$BUSY; |
339
|
0
|
|
|
|
|
|
kick_job; |
340
|
0
|
|
|
|
|
|
}; |
341
|
0
|
|
|
|
|
|
return 1; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
0
|
|
|
|
|
|
push @QUEUE, $pdu; |
345
|
0
|
|
|
|
|
|
kick_job; |
346
|
|
|
|
|
|
|
|
347
|
0
|
|
|
|
|
|
1 |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
sub loop($) { |
351
|
0
|
|
|
0
|
0
|
|
while ($BUSY) { |
352
|
0
|
|
|
|
|
|
$DONE = AE::cv; |
353
|
0
|
|
|
|
|
|
$DONE->recv; |
354
|
0
|
|
|
|
|
|
undef $DONE; |
355
|
|
|
|
|
|
|
} |
356
|
|
|
|
|
|
|
} |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
*activate = \&loop; # 5.x compatibility? |
359
|
|
|
|
|
|
|
*listen = \&loop; # 5.x compatibility? |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
sub one_event($) { |
362
|
|
|
|
|
|
|
# should not ever be used |
363
|
0
|
|
|
0
|
0
|
|
AnyEvent->one_event; #d# todo |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
sub set_max_outstanding($) { |
367
|
0
|
|
|
0
|
1
|
|
$MAX_OUTSTANDING = $_[0]; |
368
|
0
|
|
|
|
|
|
kick_job; |
369
|
|
|
|
|
|
|
} |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
# not provided yet: |
372
|
|
|
|
|
|
|
# schedule # apparently only used by Net::SNMP::Dispatcher itself |
373
|
|
|
|
|
|
|
# register # apparently only used by Net::SNMP::Dispatcher itself |
374
|
|
|
|
|
|
|
# deregister # apparently only used by Net::SNMP::Dispatcher itself |
375
|
|
|
|
|
|
|
# cancel # apparently only used by Net::SNMP::Dispatcher itself |
376
|
|
|
|
|
|
|
# return_response_pdu # apparently not used at all? |
377
|
|
|
|
|
|
|
# error # only used by Net::SNMP::Dispatcher itself? |
378
|
|
|
|
|
|
|
# debug # only used by Net::SNMP::Dispatcher itself? |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=head1 SEE ALSO |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
L, L, L, L. |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=head1 AUTHOR |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
Marc Lehmann |
387
|
|
|
|
|
|
|
http://home.schmorp.de/ |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=cut |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
1 |
392
|
|
|
|
|
|
|
|