=cut
sub on_drain {
my ($self, $cb) = @_;
$self->{on_drain} = $cb;
$cb->($self)
if $cb && $self->{low_water_mark} >= length $self->{wbuf};
}
=item $handle->push_write ($data)
Queues the given scalar to be written. You can push as much data as you
want (only limited by the available memory), as C<AnyEvent::Handle>
buffers it independently of the kernel.
=cut
sub _drain_wbuf {
my ($self) = @_;
if (!$self->{_ww} && length $self->{wbuf}) {
Scalar::Util::weaken $self;
my $cb = sub {
my $len = syswrite $self->{fh}, $self->{wbuf};
if ($len >= 0) {
substr $self->{wbuf}, 0, $len, "";
$self->{_activity} = AnyEvent->now;
$self->{on_drain}($self)
if $self->{low_water_mark} >= length $self->{wbuf}
&& $self->{on_drain};
delete $self->{_ww} unless length $self->{wbuf};
} elsif ($! != EAGAIN && $! != EINTR && $! != WSAEWOULDBLOCK) {
$self->_error ($!, 1);
}
};
# try to write data immediately
$cb->();
# if still data left in wbuf, we need to poll
$self->{_ww} = AnyEvent->io (fh => $self->{fh}, poll => "w", cb => $cb)
if length $self->{wbuf};
};
}
our %WH;
sub register_write_type($$) {
$WH{$_[0]} = $_[1];
}
sub push_write {
my $self = shift;
if (@_ > 1) {
my $type = shift;
@_ = ($WH{$type} or Carp::croak "unsupported type passed to AnyEvent::Handle::push_write")
->($self, @_);
}
if ($self->{filter_w}) {
$self->{filter_w}($self, \$_[0]);
} else {
$self->{wbuf} .= $_[0];
$self->_drain_wbuf;
}
}
=item $handle->push_write (type => @args)
Instead of formatting your data yourself, you can also let this module do
the job by specifying a type and type-specific arguments.
Predefined types are (if you have ideas for additional types, feel free to
drop by and tell us):
=over 4
=item netstring => $string
Formats the given value as netstring
(http://cr.yp.to/proto/netstrings.txt, this is not a recommendation to use them).
=cut
register_write_type netstring => sub {
my ($self, $string) = @_;
sprintf "%d:%s,", (length $string), $string
};
=5= |