| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package POE::Wheel::ReadWrite; |
|
2
|
|
|
|
|
|
|
|
|
3
|
26
|
|
|
26
|
|
7415
|
use strict; |
|
|
26
|
|
|
|
|
172
|
|
|
|
26
|
|
|
|
|
892
|
|
|
4
|
|
|
|
|
|
|
|
|
5
|
26
|
|
|
26
|
|
115
|
use vars qw($VERSION @ISA); |
|
|
26
|
|
|
|
|
36
|
|
|
|
26
|
|
|
|
|
1301
|
|
|
6
|
|
|
|
|
|
|
$VERSION = '1.365'; # NOTE - Should be #.### (three decimal places) |
|
7
|
|
|
|
|
|
|
|
|
8
|
26
|
|
|
26
|
|
135
|
use Carp qw( croak carp ); |
|
|
26
|
|
|
|
|
39
|
|
|
|
26
|
|
|
|
|
1234
|
|
|
9
|
26
|
|
|
26
|
|
120
|
use POE qw(Wheel Driver::SysRW Filter::Line); |
|
|
26
|
|
|
|
|
31
|
|
|
|
26
|
|
|
|
|
208
|
|
|
10
|
|
|
|
|
|
|
push @ISA, qw(POE::Wheel); |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# Offsets into $self. |
|
13
|
|
|
|
|
|
|
sub HANDLE_INPUT () { 0 } |
|
14
|
|
|
|
|
|
|
sub HANDLE_OUTPUT () { 1 } |
|
15
|
|
|
|
|
|
|
sub FILTER_INPUT () { 2 } |
|
16
|
|
|
|
|
|
|
sub FILTER_OUTPUT () { 3 } |
|
17
|
|
|
|
|
|
|
sub DRIVER_BOTH () { 4 } |
|
18
|
|
|
|
|
|
|
sub EVENT_INPUT () { 5 } |
|
19
|
|
|
|
|
|
|
sub EVENT_ERROR () { 6 } |
|
20
|
|
|
|
|
|
|
sub EVENT_FLUSHED () { 7 } |
|
21
|
|
|
|
|
|
|
sub WATERMARK_WRITE_MARK_HIGH () { 8 } |
|
22
|
|
|
|
|
|
|
sub WATERMARK_WRITE_MARK_LOW () { 9 } |
|
23
|
|
|
|
|
|
|
sub WATERMARK_WRITE_EVENT_HIGH () { 10 } |
|
24
|
|
|
|
|
|
|
sub WATERMARK_WRITE_EVENT_LOW () { 11 } |
|
25
|
|
|
|
|
|
|
sub WATERMARK_WRITE_STATE () { 12 } |
|
26
|
|
|
|
|
|
|
sub DRIVER_BUFFERED_OUT_OCTETS () { 13 } |
|
27
|
|
|
|
|
|
|
sub STATE_WRITE () { 14 } |
|
28
|
|
|
|
|
|
|
sub STATE_READ () { 15 } |
|
29
|
|
|
|
|
|
|
sub UNIQUE_ID () { 16 } |
|
30
|
|
|
|
|
|
|
sub AUTOFLUSH () { 17 } |
|
31
|
|
|
|
|
|
|
|
|
32
|
0
|
|
|
0
|
0
|
0
|
sub CRIMSON_SCOPE_HACK ($) { 0 } |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub new { |
|
37
|
158
|
|
|
158
|
1
|
9195
|
my $type = shift; |
|
38
|
158
|
|
|
|
|
636
|
my %params = @_; |
|
39
|
|
|
|
|
|
|
|
|
40
|
158
|
100
|
100
|
|
|
945
|
croak "wheels no longer require a kernel reference as their first parameter" |
|
41
|
|
|
|
|
|
|
if (@_ && (ref($_[0]) eq 'POE::Kernel')); |
|
42
|
|
|
|
|
|
|
|
|
43
|
156
|
50
|
|
|
|
315
|
croak "$type requires a working Kernel" unless defined $poe_kernel; |
|
44
|
|
|
|
|
|
|
|
|
45
|
156
|
|
|
|
|
161
|
my ($in_handle, $out_handle); |
|
46
|
156
|
100
|
|
|
|
327
|
if (defined $params{Handle}) { |
|
47
|
148
|
50
|
|
|
|
292
|
carp "Ignoring InputHandle parameter (Handle parameter takes precedence)" |
|
48
|
|
|
|
|
|
|
if defined $params{InputHandle}; |
|
49
|
148
|
50
|
|
|
|
254
|
carp "Ignoring OutputHandle parameter (Handle parameter takes precedence)" |
|
50
|
|
|
|
|
|
|
if defined $params{OutputHandle}; |
|
51
|
148
|
|
|
|
|
285
|
$in_handle = $out_handle = delete $params{Handle}; |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
else { |
|
54
|
8
|
100
|
|
|
|
271
|
croak "Handle or InputHandle required" |
|
55
|
|
|
|
|
|
|
unless defined $params{InputHandle}; |
|
56
|
6
|
100
|
|
|
|
278
|
croak "Handle or OutputHandle required" |
|
57
|
|
|
|
|
|
|
unless defined $params{OutputHandle}; |
|
58
|
4
|
|
|
|
|
7
|
$in_handle = delete $params{InputHandle}; |
|
59
|
4
|
|
|
|
|
8
|
$out_handle = delete $params{OutputHandle}; |
|
60
|
|
|
|
|
|
|
} |
|
61
|
|
|
|
|
|
|
|
|
62
|
152
|
|
|
|
|
151
|
my ($in_filter, $out_filter); |
|
63
|
152
|
100
|
|
|
|
296
|
if (defined $params{Filter}) { |
|
64
|
109
|
50
|
|
|
|
214
|
carp "Ignoring InputFilter parameter (Filter parameter takes precedence)" |
|
65
|
|
|
|
|
|
|
if (defined $params{InputFilter}); |
|
66
|
109
|
50
|
|
|
|
216
|
carp "Ignoring OutputFilter parameter (Filter parameter takes precedence)" |
|
67
|
|
|
|
|
|
|
if (defined $params{OutputFilter}); |
|
68
|
109
|
|
|
|
|
160
|
$in_filter = $out_filter = delete $params{Filter}; |
|
69
|
|
|
|
|
|
|
} |
|
70
|
|
|
|
|
|
|
else { |
|
71
|
43
|
|
|
|
|
52
|
$in_filter = delete $params{InputFilter}; |
|
72
|
43
|
|
|
|
|
65
|
$out_filter = delete $params{OutputFilter}; |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# If neither Filter, InputFilter or OutputFilter is defined, then |
|
75
|
|
|
|
|
|
|
# they default to POE::Filter::Line. |
|
76
|
43
|
50
|
33
|
|
|
119
|
unless (defined $in_filter and defined $out_filter) { |
|
77
|
43
|
|
|
|
|
182
|
my $new_filter = POE::Filter::Line->new(); |
|
78
|
43
|
50
|
|
|
|
90
|
$in_filter = $new_filter unless defined $in_filter; |
|
79
|
43
|
50
|
|
|
|
95
|
$out_filter = $new_filter unless defined $out_filter; |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
} |
|
82
|
|
|
|
|
|
|
|
|
83
|
152
|
|
|
|
|
238
|
my $driver = delete $params{Driver}; |
|
84
|
152
|
100
|
|
|
|
390
|
$driver = POE::Driver::SysRW->new() unless defined $driver; |
|
85
|
|
|
|
|
|
|
|
|
86
|
152
|
|
|
|
|
153
|
{ my $mark_errors = 0; |
|
|
152
|
|
|
|
|
177
|
|
|
87
|
152
|
100
|
100
|
|
|
806
|
if (defined($params{HighMark}) xor defined($params{LowMark})) { |
|
|
|
100
|
|
|
|
|
|
|
88
|
4
|
|
|
|
|
450
|
carp "HighMark and LowMark parameters require each-other"; |
|
89
|
4
|
|
|
|
|
196
|
$mark_errors++; |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
# Then they both exist, and they must be checked. |
|
92
|
|
|
|
|
|
|
elsif (defined $params{HighMark}) { |
|
93
|
12
|
50
|
33
|
|
|
53
|
unless (defined($params{HighMark}) and defined($params{LowMark})) { |
|
94
|
0
|
|
|
|
|
0
|
carp "HighMark and LowMark parameters must both be defined"; |
|
95
|
0
|
|
|
|
|
0
|
$mark_errors++; |
|
96
|
|
|
|
|
|
|
} |
|
97
|
12
|
100
|
100
|
|
|
45
|
unless (($params{HighMark} > 0) and ($params{LowMark} > 0)) { |
|
98
|
6
|
|
|
|
|
665
|
carp "HighMark and LowMark parameters must be above 0"; |
|
99
|
6
|
|
|
|
|
261
|
$mark_errors++; |
|
100
|
|
|
|
|
|
|
} |
|
101
|
|
|
|
|
|
|
} |
|
102
|
152
|
100
|
100
|
|
|
428
|
if (defined $params{HighEvent} and not defined $params{HighMark}) { |
|
103
|
6
|
|
|
|
|
714
|
carp "HighEvent requires a corresponding HighMark"; |
|
104
|
6
|
|
|
|
|
246
|
$mark_errors++; |
|
105
|
|
|
|
|
|
|
} |
|
106
|
152
|
100
|
100
|
|
|
600
|
if (defined($params{LowMark}) xor defined($params{LowEvent})) { |
|
107
|
8
|
|
|
|
|
826
|
carp "LowMark and LowEvent parameters require each-other"; |
|
108
|
8
|
|
|
|
|
297
|
$mark_errors++; |
|
109
|
|
|
|
|
|
|
} |
|
110
|
152
|
100
|
|
|
|
2738
|
croak "Water mark errors" if $mark_errors; |
|
111
|
|
|
|
|
|
|
} |
|
112
|
|
|
|
|
|
|
|
|
113
|
134
|
|
|
|
|
650
|
my $self = bless [ |
|
114
|
|
|
|
|
|
|
$in_handle, # HANDLE_INPUT |
|
115
|
|
|
|
|
|
|
$out_handle, # HANDLE_OUTPUT |
|
116
|
|
|
|
|
|
|
$in_filter, # FILTER_INPUT |
|
117
|
|
|
|
|
|
|
$out_filter, # FILTER_OUTPUT |
|
118
|
|
|
|
|
|
|
$driver, # DRIVER_BOTH |
|
119
|
|
|
|
|
|
|
delete $params{InputEvent}, # EVENT_INPUT |
|
120
|
|
|
|
|
|
|
delete $params{ErrorEvent}, # EVENT_ERROR |
|
121
|
|
|
|
|
|
|
delete $params{FlushedEvent}, # EVENT_FLUSHED |
|
122
|
|
|
|
|
|
|
# Water marks. |
|
123
|
|
|
|
|
|
|
delete $params{HighMark}, # WATERMARK_WRITE_MARK_HIGH |
|
124
|
|
|
|
|
|
|
delete $params{LowMark}, # WATERMARK_WRITE_MARK_LOW |
|
125
|
|
|
|
|
|
|
delete $params{HighEvent}, # WATERMARK_WRITE_EVENT_HIGH |
|
126
|
|
|
|
|
|
|
delete $params{LowEvent}, # WATERMARK_WRITE_EVENT_LOW |
|
127
|
|
|
|
|
|
|
0, # WATERMARK_WRITE_STATE |
|
128
|
|
|
|
|
|
|
# Driver statistics. |
|
129
|
|
|
|
|
|
|
0, # DRIVER_BUFFERED_OUT_OCTETS |
|
130
|
|
|
|
|
|
|
# Dynamic state names. |
|
131
|
|
|
|
|
|
|
undef, # STATE_WRITE |
|
132
|
|
|
|
|
|
|
undef, # STATE_READ |
|
133
|
|
|
|
|
|
|
# Unique ID. |
|
134
|
|
|
|
|
|
|
&POE::Wheel::allocate_wheel_id(), # UNIQUE_ID |
|
135
|
|
|
|
|
|
|
delete $params{AutoFlush}, # AUTOFLUSH |
|
136
|
|
|
|
|
|
|
], $type; |
|
137
|
|
|
|
|
|
|
|
|
138
|
134
|
50
|
|
|
|
347
|
if (scalar keys %params) { |
|
139
|
0
|
|
|
|
|
0
|
carp( |
|
140
|
|
|
|
|
|
|
"unknown parameters in $type constructor call: ", |
|
141
|
|
|
|
|
|
|
join(', ', keys %params) |
|
142
|
|
|
|
|
|
|
); |
|
143
|
|
|
|
|
|
|
} |
|
144
|
|
|
|
|
|
|
|
|
145
|
134
|
|
|
|
|
330
|
$self->_define_read_state(); |
|
146
|
132
|
|
|
|
|
304
|
$self->_define_write_state(); |
|
147
|
|
|
|
|
|
|
|
|
148
|
132
|
|
|
|
|
495
|
return $self; |
|
149
|
|
|
|
|
|
|
} |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
152
|
|
|
|
|
|
|
# Redefine the select-write handler. This uses stupid closure tricks |
|
153
|
|
|
|
|
|
|
# to prevent keeping extra references to $self around. |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub _define_write_state { |
|
156
|
136
|
|
|
136
|
|
176
|
my $self = shift; |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Read-only members. If any of these change, then the write state |
|
159
|
|
|
|
|
|
|
# is invalidated and needs to be redefined. |
|
160
|
136
|
|
|
|
|
180
|
my $driver = $self->[DRIVER_BOTH]; |
|
161
|
136
|
|
|
|
|
878
|
my $high_mark = $self->[WATERMARK_WRITE_MARK_HIGH]; |
|
162
|
136
|
|
|
|
|
156
|
my $low_mark = $self->[WATERMARK_WRITE_MARK_LOW]; |
|
163
|
136
|
|
|
|
|
172
|
my $event_error = \$self->[EVENT_ERROR]; |
|
164
|
136
|
|
|
|
|
162
|
my $event_flushed = \$self->[EVENT_FLUSHED]; |
|
165
|
136
|
|
|
|
|
165
|
my $event_high = \$self->[WATERMARK_WRITE_EVENT_HIGH]; |
|
166
|
136
|
|
|
|
|
182
|
my $event_low = \$self->[WATERMARK_WRITE_EVENT_LOW]; |
|
167
|
136
|
|
|
|
|
204
|
my $unique_id = $self->[UNIQUE_ID]; |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# Read/write members. These are done by reference, to avoid pushing |
|
170
|
|
|
|
|
|
|
# $self into the anonymous sub. Extra copies of $self are bad and |
|
171
|
|
|
|
|
|
|
# can prevent wheels from destructing properly. |
|
172
|
136
|
|
|
|
|
143
|
my $is_in_high_water_state = \$self->[WATERMARK_WRITE_STATE]; |
|
173
|
136
|
|
|
|
|
163
|
my $driver_buffered_out_octets = \$self->[DRIVER_BUFFERED_OUT_OCTETS]; |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
# Register the select-write handler. |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
$poe_kernel->state( |
|
178
|
|
|
|
|
|
|
$self->[STATE_WRITE] = ref($self) . "($unique_id) -> select write", |
|
179
|
|
|
|
|
|
|
sub { # prevents SEGV |
|
180
|
217
|
|
|
217
|
|
228
|
0 && CRIMSON_SCOPE_HACK('<'); |
|
181
|
|
|
|
|
|
|
# subroutine starts here |
|
182
|
217
|
|
|
|
|
441
|
my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0]; |
|
183
|
|
|
|
|
|
|
|
|
184
|
217
|
|
|
|
|
714
|
$$driver_buffered_out_octets = $driver->flush($handle); |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
# When you can't write, nothing else matters. |
|
187
|
217
|
50
|
|
|
|
586
|
if ($!) { |
|
188
|
0
|
0
|
|
|
|
0
|
$$event_error && $k->call( |
|
189
|
|
|
|
|
|
|
$me, $$event_error, 'write', ($!+0), $!, $unique_id |
|
190
|
|
|
|
|
|
|
); |
|
191
|
0
|
|
|
|
|
0
|
$k->select_write($handle); |
|
192
|
|
|
|
|
|
|
} |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
# Could write, or perhaps couldn't but only because the |
|
195
|
|
|
|
|
|
|
# filehandle's buffer is choked. |
|
196
|
|
|
|
|
|
|
else { |
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
# In high water state? Check for low water. High water |
|
199
|
|
|
|
|
|
|
# state will never be set if $event_low is undef, so don't |
|
200
|
|
|
|
|
|
|
# bother checking its definedness here. |
|
201
|
217
|
100
|
66
|
|
|
901
|
if ($$is_in_high_water_state) { |
|
|
|
50
|
|
|
|
|
|
|
202
|
4
|
50
|
|
|
|
11
|
if ( $$driver_buffered_out_octets <= $low_mark ) { |
|
203
|
4
|
|
|
|
|
11
|
$$is_in_high_water_state = 0; |
|
204
|
4
|
50
|
|
|
|
18
|
$k->call( $me, $$event_low, $unique_id ) if defined $$event_low; |
|
205
|
|
|
|
|
|
|
} |
|
206
|
|
|
|
|
|
|
} |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# Not in high water state. Check for high water. Needs to |
|
209
|
|
|
|
|
|
|
# also check definedness of $$driver_buffered_out_octets. |
|
210
|
|
|
|
|
|
|
# Although we know this ahead of time and could probably |
|
211
|
|
|
|
|
|
|
# optimize it away with a second state definition, it would |
|
212
|
|
|
|
|
|
|
# be best to wait until ReadWrite stabilizes. That way |
|
213
|
|
|
|
|
|
|
# there will be only half as much code to maintain. |
|
214
|
|
|
|
|
|
|
elsif ( |
|
215
|
|
|
|
|
|
|
$high_mark and |
|
216
|
|
|
|
|
|
|
( $$driver_buffered_out_octets >= $high_mark ) |
|
217
|
|
|
|
|
|
|
) { |
|
218
|
0
|
|
|
|
|
0
|
$$is_in_high_water_state = 1; |
|
219
|
0
|
0
|
|
|
|
0
|
$k->call( $me, $$event_high, $unique_id ) if defined $$event_high; |
|
220
|
|
|
|
|
|
|
} |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
# All chunks written; fire off a "flushed" event. This |
|
224
|
|
|
|
|
|
|
# occurs independently, so it's possible to get a low-water |
|
225
|
|
|
|
|
|
|
# call and a flushed call at the same time (if the low mark |
|
226
|
|
|
|
|
|
|
# is 1). |
|
227
|
217
|
50
|
|
|
|
480
|
unless ($$driver_buffered_out_octets) { |
|
228
|
217
|
|
|
|
|
669
|
$k->select_pause_write($handle); |
|
229
|
217
|
100
|
|
|
|
947
|
$$event_flushed && $k->call($me, $$event_flushed, $unique_id); |
|
230
|
|
|
|
|
|
|
} |
|
231
|
|
|
|
|
|
|
} |
|
232
|
136
|
|
|
|
|
1177
|
); |
|
233
|
|
|
|
|
|
|
|
|
234
|
136
|
|
|
|
|
403
|
$poe_kernel->select_write($self->[HANDLE_OUTPUT], $self->[STATE_WRITE]); |
|
235
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
# Pause the write select immediately, unless output is pending. |
|
237
|
136
|
50
|
|
|
|
561
|
$poe_kernel->select_pause_write($self->[HANDLE_OUTPUT]) |
|
238
|
|
|
|
|
|
|
unless ($self->[DRIVER_BUFFERED_OUT_OCTETS]); |
|
239
|
|
|
|
|
|
|
} |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
242
|
|
|
|
|
|
|
# Redefine the select-read handler. This uses stupid closure tricks |
|
243
|
|
|
|
|
|
|
# to prevent keeping extra references to $self around. |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
sub _define_read_state { |
|
246
|
138
|
|
|
138
|
|
166
|
my $self = shift; |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# Register the select-read handler. |
|
249
|
|
|
|
|
|
|
|
|
250
|
138
|
100
|
|
|
|
404
|
if (defined $self->[EVENT_INPUT]) { |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
# If any of these change, then the read state is invalidated and |
|
253
|
|
|
|
|
|
|
# needs to be redefined. |
|
254
|
|
|
|
|
|
|
|
|
255
|
132
|
|
|
|
|
158
|
my $driver = $self->[DRIVER_BOTH]; |
|
256
|
132
|
|
|
|
|
176
|
my $input_filter = \$self->[FILTER_INPUT]; |
|
257
|
132
|
|
|
|
|
177
|
my $event_input = \$self->[EVENT_INPUT]; |
|
258
|
132
|
|
|
|
|
160
|
my $event_error = \$self->[EVENT_ERROR]; |
|
259
|
132
|
|
|
|
|
181
|
my $unique_id = $self->[UNIQUE_ID]; |
|
260
|
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
# If the filter can get_one, then define the input state in terms |
|
262
|
|
|
|
|
|
|
# of get_one_start() and get_one(). |
|
263
|
|
|
|
|
|
|
|
|
264
|
132
|
50
|
33
|
|
|
1004
|
if ( |
|
265
|
|
|
|
|
|
|
$$input_filter->can('get_one') and |
|
266
|
|
|
|
|
|
|
$$input_filter->can('get_one_start') |
|
267
|
|
|
|
|
|
|
) { |
|
268
|
|
|
|
|
|
|
$poe_kernel->state( |
|
269
|
|
|
|
|
|
|
$self->[STATE_READ] = ref($self) . "($unique_id) -> select read", |
|
270
|
|
|
|
|
|
|
sub { |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
# Protects against coredump on older perls. |
|
273
|
285
|
|
|
285
|
|
315
|
0 && CRIMSON_SCOPE_HACK('<'); |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
# The actual code starts here. |
|
276
|
285
|
|
|
|
|
632
|
my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0]; |
|
277
|
285
|
100
|
|
|
|
874
|
if (defined(my $raw_input = $driver->get($handle))) { |
|
278
|
221
|
|
|
|
|
730
|
$$input_filter->get_one_start($raw_input); |
|
279
|
221
|
|
|
|
|
212
|
while (1) { |
|
280
|
434
|
|
|
|
|
1157
|
my $next_rec = $$input_filter->get_one(); |
|
281
|
434
|
100
|
|
|
|
1457
|
last unless @$next_rec; |
|
282
|
213
|
|
|
|
|
354
|
foreach my $cooked_input (@$next_rec) { |
|
283
|
213
|
|
|
|
|
688
|
$k->call($me, $$event_input, $cooked_input, $unique_id); |
|
284
|
|
|
|
|
|
|
} |
|
285
|
|
|
|
|
|
|
} |
|
286
|
|
|
|
|
|
|
} |
|
287
|
|
|
|
|
|
|
else { |
|
288
|
64
|
50
|
|
|
|
368
|
$$event_error and $k->call( |
|
289
|
|
|
|
|
|
|
$me, $$event_error, 'read', ($!+0), $!, $unique_id |
|
290
|
|
|
|
|
|
|
); |
|
291
|
64
|
|
|
|
|
181
|
$k->select_read($handle); |
|
292
|
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
} |
|
294
|
132
|
|
|
|
|
1225
|
); |
|
295
|
|
|
|
|
|
|
} |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
# Otherwise define the input state in terms of the older, less |
|
298
|
|
|
|
|
|
|
# robust, yet faster get(). |
|
299
|
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
else { |
|
301
|
|
|
|
|
|
|
$poe_kernel->state( |
|
302
|
|
|
|
|
|
|
$self->[STATE_READ] = ref($self) . "($unique_id) -> select read", |
|
303
|
|
|
|
|
|
|
sub { |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
# Protects against coredump on older perls. |
|
306
|
0
|
|
|
0
|
|
0
|
0 && CRIMSON_SCOPE_HACK('<'); |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
# The actual code starts here. |
|
309
|
0
|
|
|
|
|
0
|
my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0]; |
|
310
|
0
|
0
|
|
|
|
0
|
if (defined(my $raw_input = $driver->get($handle))) { |
|
311
|
0
|
|
|
|
|
0
|
foreach my $cooked_input (@{$$input_filter->get($raw_input)}) { |
|
|
0
|
|
|
|
|
0
|
|
|
312
|
0
|
|
|
|
|
0
|
$k->call($me, $$event_input, $cooked_input, $unique_id); |
|
313
|
|
|
|
|
|
|
} |
|
314
|
|
|
|
|
|
|
} |
|
315
|
|
|
|
|
|
|
else { |
|
316
|
0
|
0
|
|
|
|
0
|
$$event_error and $k->call( |
|
317
|
|
|
|
|
|
|
$me, $$event_error, 'read', ($!+0), $!, $unique_id |
|
318
|
|
|
|
|
|
|
); |
|
319
|
0
|
|
|
|
|
0
|
$k->select_read($handle); |
|
320
|
|
|
|
|
|
|
} |
|
321
|
|
|
|
|
|
|
} |
|
322
|
0
|
|
|
|
|
0
|
); |
|
323
|
|
|
|
|
|
|
} |
|
324
|
|
|
|
|
|
|
# register the state's select |
|
325
|
132
|
|
|
|
|
449
|
$poe_kernel->select_read($self->[HANDLE_INPUT], $self->[STATE_READ]); |
|
326
|
|
|
|
|
|
|
} |
|
327
|
|
|
|
|
|
|
# undefine the select, just in case |
|
328
|
|
|
|
|
|
|
else { |
|
329
|
6
|
|
|
|
|
26
|
$poe_kernel->select_read($self->[HANDLE_INPUT]) |
|
330
|
|
|
|
|
|
|
} |
|
331
|
|
|
|
|
|
|
} |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
334
|
|
|
|
|
|
|
# Redefine events. |
|
335
|
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
sub event { |
|
337
|
4
|
|
|
4
|
1
|
30
|
my $self = shift; |
|
338
|
4
|
50
|
|
|
|
15
|
push(@_, undef) if (scalar(@_) & 1); |
|
339
|
|
|
|
|
|
|
|
|
340
|
4
|
|
|
|
|
9
|
my ($redefine_read, $redefine_write) = (0, 0); |
|
341
|
|
|
|
|
|
|
|
|
342
|
4
|
|
|
|
|
13
|
while (@_) { |
|
343
|
14
|
|
|
|
|
887
|
my ($name, $event) = splice(@_, 0, 2); |
|
344
|
|
|
|
|
|
|
|
|
345
|
14
|
100
|
|
|
|
51
|
if ($name eq 'InputEvent') { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
346
|
2
|
|
|
|
|
4
|
$self->[EVENT_INPUT] = $event; |
|
347
|
2
|
|
|
|
|
5
|
$redefine_read = 1; |
|
348
|
|
|
|
|
|
|
} |
|
349
|
|
|
|
|
|
|
elsif ($name eq 'ErrorEvent') { |
|
350
|
4
|
|
|
|
|
6
|
$self->[EVENT_ERROR] = $event; |
|
351
|
4
|
|
|
|
|
9
|
$redefine_read = $redefine_write = 1; |
|
352
|
|
|
|
|
|
|
} |
|
353
|
|
|
|
|
|
|
elsif ($name eq 'FlushedEvent') { |
|
354
|
4
|
|
|
|
|
8
|
$self->[EVENT_FLUSHED] = $event; |
|
355
|
4
|
|
|
|
|
9
|
$redefine_write = 1; |
|
356
|
|
|
|
|
|
|
} |
|
357
|
|
|
|
|
|
|
elsif ($name eq 'HighEvent') { |
|
358
|
2
|
50
|
|
|
|
781
|
if (defined $self->[WATERMARK_WRITE_MARK_HIGH]) { |
|
359
|
2
|
|
|
|
|
4
|
$self->[WATERMARK_WRITE_EVENT_HIGH] = $event; |
|
360
|
2
|
|
|
|
|
5
|
$redefine_write = 1; |
|
361
|
|
|
|
|
|
|
} |
|
362
|
|
|
|
|
|
|
else { |
|
363
|
0
|
|
|
|
|
0
|
carp "Ignoring HighEvent (there is no high watermark set)"; |
|
364
|
|
|
|
|
|
|
} |
|
365
|
|
|
|
|
|
|
} |
|
366
|
|
|
|
|
|
|
elsif ($name eq 'LowEvent') { |
|
367
|
2
|
50
|
|
|
|
5
|
if (defined $self->[WATERMARK_WRITE_MARK_LOW]) { |
|
368
|
2
|
|
|
|
|
3
|
$self->[WATERMARK_WRITE_EVENT_LOW] = $event; |
|
369
|
2
|
|
|
|
|
5
|
$redefine_write = 1; |
|
370
|
|
|
|
|
|
|
} |
|
371
|
|
|
|
|
|
|
else { |
|
372
|
0
|
|
|
|
|
0
|
carp "Ignoring LowEvent (there is no high watermark set)"; |
|
373
|
|
|
|
|
|
|
} |
|
374
|
|
|
|
|
|
|
} |
|
375
|
|
|
|
|
|
|
else { |
|
376
|
0
|
|
|
|
|
0
|
carp "ignoring unknown ReadWrite parameter '$name'"; |
|
377
|
|
|
|
|
|
|
} |
|
378
|
|
|
|
|
|
|
} |
|
379
|
|
|
|
|
|
|
|
|
380
|
4
|
50
|
|
|
|
16
|
$self->_define_read_state() if $redefine_read; |
|
381
|
4
|
50
|
|
|
|
49
|
$self->_define_write_state() if $redefine_write; |
|
382
|
|
|
|
|
|
|
} |
|
383
|
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
385
|
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
sub DESTROY { |
|
387
|
134
|
|
|
134
|
|
4720
|
my $self = shift; |
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
# Turn off the select. This is a problem if a wheel is being |
|
390
|
|
|
|
|
|
|
# swapped, since it will turn off selects for the other wheel. |
|
391
|
134
|
50
|
|
|
|
353
|
if ($self->[HANDLE_INPUT]) { |
|
392
|
134
|
|
|
|
|
476
|
$poe_kernel->select_read($self->[HANDLE_INPUT]); |
|
393
|
132
|
|
|
|
|
216
|
$self->[HANDLE_INPUT] = undef; |
|
394
|
|
|
|
|
|
|
} |
|
395
|
|
|
|
|
|
|
|
|
396
|
132
|
50
|
|
|
|
332
|
if ($self->[HANDLE_OUTPUT]) { |
|
397
|
132
|
|
|
|
|
416
|
$poe_kernel->select_write($self->[HANDLE_OUTPUT]); |
|
398
|
132
|
|
|
|
|
240
|
$self->[HANDLE_OUTPUT] = undef; |
|
399
|
|
|
|
|
|
|
} |
|
400
|
|
|
|
|
|
|
|
|
401
|
132
|
100
|
|
|
|
3619
|
if ($self->[STATE_READ]) { |
|
402
|
130
|
|
|
|
|
455
|
$poe_kernel->state($self->[STATE_READ]); |
|
403
|
130
|
|
|
|
|
196
|
$self->[STATE_READ] = undef; |
|
404
|
|
|
|
|
|
|
} |
|
405
|
|
|
|
|
|
|
|
|
406
|
132
|
50
|
|
|
|
301
|
if ($self->[STATE_WRITE]) { |
|
407
|
132
|
|
|
|
|
699
|
$poe_kernel->state($self->[STATE_WRITE]); |
|
408
|
132
|
|
|
|
|
180
|
$self->[STATE_WRITE] = undef; |
|
409
|
|
|
|
|
|
|
} |
|
410
|
|
|
|
|
|
|
|
|
411
|
132
|
|
|
|
|
431
|
&POE::Wheel::free_wheel_id($self->[UNIQUE_ID]); |
|
412
|
|
|
|
|
|
|
} |
|
413
|
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
415
|
|
|
|
|
|
|
# TODO - We set the high/low watermark state here, but we don't fire |
|
416
|
|
|
|
|
|
|
# events for it. My assumption is that the return value tells us |
|
417
|
|
|
|
|
|
|
# all we want to know. |
|
418
|
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
sub put { |
|
420
|
247
|
|
|
247
|
1
|
6907
|
my ($self, @chunks) = @_; |
|
421
|
|
|
|
|
|
|
|
|
422
|
247
|
|
|
|
|
373
|
my $old_buffered_out_octets = $self->[DRIVER_BUFFERED_OUT_OCTETS]; |
|
423
|
247
|
|
|
|
|
878
|
my $new_buffered_out_octets = |
|
424
|
|
|
|
|
|
|
$self->[DRIVER_BUFFERED_OUT_OCTETS] = |
|
425
|
|
|
|
|
|
|
$self->[DRIVER_BOTH]->put($self->[FILTER_OUTPUT]->put(\@chunks)); |
|
426
|
|
|
|
|
|
|
|
|
427
|
247
|
0
|
33
|
|
|
1497
|
if ( |
|
|
|
|
33
|
|
|
|
|
|
428
|
|
|
|
|
|
|
$self->[AUTOFLUSH] && |
|
429
|
|
|
|
|
|
|
$new_buffered_out_octets and !$old_buffered_out_octets |
|
430
|
|
|
|
|
|
|
) { |
|
431
|
0
|
|
|
|
|
0
|
$old_buffered_out_octets = $new_buffered_out_octets; |
|
432
|
0
|
|
|
|
|
0
|
$self->flush(); |
|
433
|
0
|
|
|
|
|
0
|
$new_buffered_out_octets = $self->[DRIVER_BUFFERED_OUT_OCTETS]; |
|
434
|
|
|
|
|
|
|
} |
|
435
|
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
# Resume write-ok if the output buffer gets data. This avoids |
|
437
|
|
|
|
|
|
|
# redundant calls to select_resume_write(), which is probably a good |
|
438
|
|
|
|
|
|
|
# thing. |
|
439
|
247
|
100
|
66
|
|
|
981
|
if ($new_buffered_out_octets and !$old_buffered_out_octets) { |
|
440
|
219
|
|
|
|
|
801
|
$poe_kernel->select_resume_write($self->[HANDLE_OUTPUT]); |
|
441
|
|
|
|
|
|
|
} |
|
442
|
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
# If the high watermark has been reached, return true. |
|
444
|
247
|
100
|
100
|
|
|
720
|
if ( |
|
445
|
|
|
|
|
|
|
$self->[WATERMARK_WRITE_MARK_HIGH] and |
|
446
|
|
|
|
|
|
|
$new_buffered_out_octets >= $self->[WATERMARK_WRITE_MARK_HIGH] |
|
447
|
|
|
|
|
|
|
) { |
|
448
|
8
|
|
|
|
|
22
|
return $self->[WATERMARK_WRITE_STATE] = 1; |
|
449
|
|
|
|
|
|
|
} |
|
450
|
|
|
|
|
|
|
|
|
451
|
239
|
|
|
|
|
705
|
return $self->[WATERMARK_WRITE_STATE] = 0; |
|
452
|
|
|
|
|
|
|
} |
|
453
|
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
455
|
|
|
|
|
|
|
# Redefine filter. -PG / Now that there are two filters internally, |
|
456
|
|
|
|
|
|
|
# one input and one output, make this set both of them at the same |
|
457
|
|
|
|
|
|
|
# time. -RCC |
|
458
|
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
sub _transfer_input_buffer { |
|
460
|
41
|
|
|
41
|
|
52
|
my ($self, $buf) = @_; |
|
461
|
|
|
|
|
|
|
|
|
462
|
41
|
|
|
|
|
57
|
my $old_input_filter = $self->[FILTER_INPUT]; |
|
463
|
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
# If the new filter implements "get_one", use that. |
|
465
|
41
|
50
|
33
|
|
|
312
|
if ( |
|
466
|
|
|
|
|
|
|
$old_input_filter->can('get_one') and |
|
467
|
|
|
|
|
|
|
$old_input_filter->can('get_one_start') |
|
468
|
|
|
|
|
|
|
) { |
|
469
|
41
|
100
|
|
|
|
124
|
if (defined $buf) { |
|
470
|
9
|
|
|
|
|
17
|
$self->[FILTER_INPUT]->get_one_start($buf); |
|
471
|
9
|
|
|
|
|
21
|
while ($self->[FILTER_INPUT] == $old_input_filter) { |
|
472
|
19
|
|
|
|
|
46
|
my $next_rec = $self->[FILTER_INPUT]->get_one(); |
|
473
|
19
|
100
|
|
|
|
28
|
last unless @$next_rec; |
|
474
|
18
|
|
|
|
|
29
|
foreach my $cooked_input (@$next_rec) { |
|
475
|
18
|
|
|
|
|
41
|
$poe_kernel->call( |
|
476
|
|
|
|
|
|
|
$poe_kernel->get_active_session(), |
|
477
|
|
|
|
|
|
|
$self->[EVENT_INPUT], |
|
478
|
|
|
|
|
|
|
$cooked_input, $self->[UNIQUE_ID] |
|
479
|
|
|
|
|
|
|
); |
|
480
|
|
|
|
|
|
|
} |
|
481
|
|
|
|
|
|
|
} |
|
482
|
|
|
|
|
|
|
} |
|
483
|
|
|
|
|
|
|
} |
|
484
|
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
# Otherwise use the old behavior. |
|
486
|
|
|
|
|
|
|
else { |
|
487
|
0
|
0
|
|
|
|
0
|
if (defined $buf) { |
|
488
|
0
|
|
|
|
|
0
|
foreach my $cooked_input (@{$self->[FILTER_INPUT]->get($buf)}) { |
|
|
0
|
|
|
|
|
0
|
|
|
489
|
0
|
|
|
|
|
0
|
$poe_kernel->call( |
|
490
|
|
|
|
|
|
|
$poe_kernel->get_active_session(), |
|
491
|
|
|
|
|
|
|
$self->[EVENT_INPUT], |
|
492
|
|
|
|
|
|
|
$cooked_input, $self->[UNIQUE_ID] |
|
493
|
|
|
|
|
|
|
); |
|
494
|
|
|
|
|
|
|
} |
|
495
|
|
|
|
|
|
|
} |
|
496
|
|
|
|
|
|
|
} |
|
497
|
|
|
|
|
|
|
} |
|
498
|
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
# Set input and output filters. |
|
500
|
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
sub set_filter { |
|
502
|
32
|
|
|
32
|
1
|
62
|
my ($self, $new_filter) = @_; |
|
503
|
32
|
|
|
|
|
122
|
my $buf = $self->[FILTER_INPUT]->get_pending(); |
|
504
|
32
|
|
|
|
|
67
|
$self->[FILTER_INPUT] = $self->[FILTER_OUTPUT] = $new_filter; |
|
505
|
|
|
|
|
|
|
|
|
506
|
32
|
|
|
|
|
121
|
$self->_transfer_input_buffer($buf); |
|
507
|
|
|
|
|
|
|
} |
|
508
|
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
# Redefine input and/or output filters separately. |
|
510
|
|
|
|
|
|
|
sub set_input_filter { |
|
511
|
9
|
|
|
9
|
1
|
10
|
my ($self, $new_filter) = @_; |
|
512
|
9
|
|
|
|
|
24
|
my $buf = $self->[FILTER_INPUT]->get_pending(); |
|
513
|
9
|
|
|
|
|
11
|
$self->[FILTER_INPUT] = $new_filter; |
|
514
|
|
|
|
|
|
|
|
|
515
|
9
|
|
|
|
|
41
|
$self->_transfer_input_buffer($buf); |
|
516
|
|
|
|
|
|
|
} |
|
517
|
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
# No closures need to be redefined or anything. All the previously |
|
519
|
|
|
|
|
|
|
# put stuff has been serialized already. |
|
520
|
|
|
|
|
|
|
sub set_output_filter { |
|
521
|
9
|
|
|
9
|
1
|
8
|
my ($self, $new_filter) = @_; |
|
522
|
9
|
|
|
|
|
36
|
$self->[FILTER_OUTPUT] = $new_filter; |
|
523
|
|
|
|
|
|
|
} |
|
524
|
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
# Get the current input filter; used for accessing the filter's custom |
|
526
|
|
|
|
|
|
|
# methods, as in: $wheel->get_input_filter()->filter_method(); |
|
527
|
|
|
|
|
|
|
sub get_input_filter { |
|
528
|
2
|
|
|
2
|
1
|
37
|
my $self = shift; |
|
529
|
2
|
|
|
|
|
13
|
return $self->[FILTER_INPUT]; |
|
530
|
|
|
|
|
|
|
} |
|
531
|
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
# Get the current input filter; used for accessing the filter's custom |
|
533
|
|
|
|
|
|
|
# methods, as in: $wheel->get_input_filter()->filter_method(); |
|
534
|
|
|
|
|
|
|
sub get_output_filter { |
|
535
|
2
|
|
|
2
|
1
|
4
|
my $self = shift; |
|
536
|
2
|
|
|
|
|
8
|
return $self->[FILTER_OUTPUT]; |
|
537
|
|
|
|
|
|
|
} |
|
538
|
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
# Set the high water mark. |
|
540
|
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
sub set_high_mark { |
|
542
|
0
|
|
|
0
|
1
|
0
|
my ($self, $new_high_mark) = @_; |
|
543
|
|
|
|
|
|
|
|
|
544
|
0
|
0
|
|
|
|
0
|
unless (defined $self->[WATERMARK_WRITE_MARK_HIGH]) { |
|
545
|
0
|
|
|
|
|
0
|
carp "Ignoring high mark (must be initialized in constructor first)"; |
|
546
|
0
|
|
|
|
|
0
|
return; |
|
547
|
|
|
|
|
|
|
} |
|
548
|
|
|
|
|
|
|
|
|
549
|
0
|
0
|
|
|
|
0
|
unless (defined $new_high_mark) { |
|
550
|
0
|
|
|
|
|
0
|
carp "New high mark is undefined. Ignored"; |
|
551
|
0
|
|
|
|
|
0
|
return; |
|
552
|
|
|
|
|
|
|
} |
|
553
|
|
|
|
|
|
|
|
|
554
|
0
|
0
|
|
|
|
0
|
unless ($new_high_mark > $self->[WATERMARK_WRITE_MARK_LOW]) { |
|
555
|
0
|
|
|
|
|
0
|
carp "New high mark would not be greater than low mark. Ignored"; |
|
556
|
0
|
|
|
|
|
0
|
return; |
|
557
|
|
|
|
|
|
|
} |
|
558
|
|
|
|
|
|
|
|
|
559
|
0
|
|
|
|
|
0
|
$self->[WATERMARK_WRITE_MARK_HIGH] = $new_high_mark; |
|
560
|
0
|
|
|
|
|
0
|
$self->_define_write_state(); |
|
561
|
|
|
|
|
|
|
} |
|
562
|
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
sub set_low_mark { |
|
564
|
0
|
|
|
0
|
1
|
0
|
my ($self, $new_low_mark) = @_; |
|
565
|
|
|
|
|
|
|
|
|
566
|
0
|
0
|
|
|
|
0
|
unless (defined $self->[WATERMARK_WRITE_MARK_LOW]) { |
|
567
|
0
|
|
|
|
|
0
|
carp "Ignoring low mark (must be initialized in constructor first)"; |
|
568
|
0
|
|
|
|
|
0
|
return; |
|
569
|
|
|
|
|
|
|
} |
|
570
|
|
|
|
|
|
|
|
|
571
|
0
|
0
|
|
|
|
0
|
unless (defined $new_low_mark) { |
|
572
|
0
|
|
|
|
|
0
|
carp "New low mark is undefined. Ignored"; |
|
573
|
0
|
|
|
|
|
0
|
return; |
|
574
|
|
|
|
|
|
|
} |
|
575
|
|
|
|
|
|
|
|
|
576
|
0
|
0
|
|
|
|
0
|
unless ($new_low_mark > 0) { |
|
577
|
0
|
|
|
|
|
0
|
carp "New low mark would be less than one. Ignored"; |
|
578
|
0
|
|
|
|
|
0
|
return; |
|
579
|
|
|
|
|
|
|
} |
|
580
|
|
|
|
|
|
|
|
|
581
|
0
|
0
|
|
|
|
0
|
unless ($new_low_mark < $self->[WATERMARK_WRITE_MARK_HIGH]) { |
|
582
|
0
|
|
|
|
|
0
|
carp "New low mark would not be less than high high mark. Ignored"; |
|
583
|
0
|
|
|
|
|
0
|
return; |
|
584
|
|
|
|
|
|
|
} |
|
585
|
|
|
|
|
|
|
|
|
586
|
0
|
|
|
|
|
0
|
$self->[WATERMARK_WRITE_MARK_LOW] = $new_low_mark; |
|
587
|
0
|
|
|
|
|
0
|
$self->_define_write_state(); |
|
588
|
|
|
|
|
|
|
} |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
# Return driver statistics. |
|
591
|
|
|
|
|
|
|
sub get_driver_out_octets { |
|
592
|
56
|
|
|
56
|
1
|
359
|
$_[0]->[DRIVER_BUFFERED_OUT_OCTETS]; |
|
593
|
|
|
|
|
|
|
} |
|
594
|
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
sub get_driver_out_messages { |
|
596
|
4
|
|
|
4
|
1
|
26
|
$_[0]->[DRIVER_BOTH]->get_out_messages_buffered(); |
|
597
|
|
|
|
|
|
|
} |
|
598
|
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
# Get the wheel's ID. |
|
600
|
|
|
|
|
|
|
sub ID { |
|
601
|
12
|
|
|
12
|
1
|
94
|
return $_[0]->[UNIQUE_ID]; |
|
602
|
|
|
|
|
|
|
} |
|
603
|
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
# Pause the wheel's input watcher. |
|
605
|
|
|
|
|
|
|
sub pause_input { |
|
606
|
2
|
|
|
2
|
1
|
717
|
my $self = shift; |
|
607
|
2
|
50
|
|
|
|
10
|
return unless defined $self->[HANDLE_INPUT]; |
|
608
|
2
|
|
|
|
|
11
|
$poe_kernel->select_pause_read( $self->[HANDLE_INPUT] ); |
|
609
|
|
|
|
|
|
|
} |
|
610
|
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
# Resume the wheel's input watcher. |
|
612
|
|
|
|
|
|
|
sub resume_input { |
|
613
|
2
|
|
|
2
|
1
|
21
|
my $self = shift; |
|
614
|
2
|
50
|
|
|
|
9
|
return unless defined $self->[HANDLE_INPUT]; |
|
615
|
2
|
|
|
|
|
15
|
$poe_kernel->select_resume_read( $self->[HANDLE_INPUT] ); |
|
616
|
|
|
|
|
|
|
} |
|
617
|
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
# Return the wheel's input handle |
|
619
|
|
|
|
|
|
|
sub get_input_handle { |
|
620
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
621
|
0
|
|
|
|
|
0
|
return $self->[HANDLE_INPUT]; |
|
622
|
|
|
|
|
|
|
} |
|
623
|
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
# Return the wheel's output handle |
|
625
|
|
|
|
|
|
|
sub get_output_handle { |
|
626
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
627
|
0
|
|
|
|
|
0
|
return $self->[HANDLE_OUTPUT]; |
|
628
|
|
|
|
|
|
|
} |
|
629
|
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
# Shutdown the socket for reading. |
|
631
|
|
|
|
|
|
|
sub shutdown_input { |
|
632
|
2
|
|
|
2
|
1
|
29
|
my $self = shift; |
|
633
|
2
|
50
|
|
|
|
8
|
return unless defined $self->[HANDLE_INPUT]; |
|
634
|
2
|
|
|
|
|
4
|
eval { local $^W = 0; shutdown($self->[HANDLE_INPUT], 0) }; |
|
|
2
|
|
|
|
|
8
|
|
|
|
2
|
|
|
|
|
33
|
|
|
635
|
2
|
|
|
|
|
9
|
$poe_kernel->select_read($self->[HANDLE_INPUT], undef); |
|
636
|
|
|
|
|
|
|
} |
|
637
|
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
# Shutdown the socket for writing. |
|
639
|
|
|
|
|
|
|
sub shutdown_output { |
|
640
|
2
|
|
|
2
|
1
|
13
|
my $self = shift; |
|
641
|
2
|
50
|
|
|
|
9
|
return unless defined $self->[HANDLE_OUTPUT]; |
|
642
|
2
|
|
|
|
|
5
|
eval { local $^W=0; shutdown($self->[HANDLE_OUTPUT], 1) }; |
|
|
2
|
|
|
|
|
6
|
|
|
|
2
|
|
|
|
|
8
|
|
|
643
|
2
|
|
|
|
|
14
|
$poe_kernel->select_write($self->[HANDLE_OUTPUT], undef); |
|
644
|
|
|
|
|
|
|
} |
|
645
|
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
# Flush the output handle |
|
647
|
|
|
|
|
|
|
sub flush { |
|
648
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
649
|
0
|
0
|
|
|
|
|
return unless defined $self->[HANDLE_OUTPUT]; |
|
650
|
0
|
|
|
|
|
|
$poe_kernel->call($poe_kernel->get_active_session(), |
|
651
|
|
|
|
|
|
|
$self->[STATE_WRITE], $self->[HANDLE_OUTPUT]); |
|
652
|
|
|
|
|
|
|
} |
|
653
|
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
1; |
|
655
|
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
__END__ |