--- AnyEvent/lib/AnyEvent/Handle.pm 2009/09/08 00:01:12 1.187 +++ AnyEvent/lib/AnyEvent/Handle.pm 2010/03/15 18:51:30 1.193 @@ -16,7 +16,7 @@ warn "got error $msg\n"; $hdl->destroy; $cv->send; - ); + }; # send some request line $hdl->push_write ("getinfo\015\012"); @@ -81,7 +81,7 @@ =over 4 -=item $handle = B AnyEvent::TLS fh => $filehandle, key => value... +=item $handle = B AnyEvent::Handle fh => $filehandle, key => value... The constructor supports these arguments (all as C<< key => value >> pairs). @@ -712,7 +712,7 @@ =cut -sub on_starttls { +sub on_stoptls { $_[0]{on_stoptls} = $_[1]; } @@ -834,6 +834,9 @@ Sets the C callback or clears it (see the description of C in the constructor). +This method may invoke callbacks (and therefore the handle might be +destroyed after it returns). + =cut sub on_drain { @@ -851,6 +854,9 @@ want (only limited by the available memory), as C buffers it independently of the kernel. +This method may invoke callbacks (and therefore the handle might be +destroyed after it returns). + =cut sub _drain_wbuf { @@ -905,11 +911,14 @@ ->($self, @_); } + # we downgrade here to avoid hard-to-track-down bugs, + # and diagnose the problem earlier and better. + if ($self->{tls}) { - $self->{_tls_wbuf} .= $_[0]; + utf8::downgrade $self->{_tls_wbuf} .= $_[0]; &_dotls ($self) if $self->{fh}; } else { - $self->{wbuf} .= $_[0]; + utf8::downgrade $self->{wbuf} .= $_[0]; $self->_drain_wbuf if $self->{fh}; } } @@ -1033,6 +1042,9 @@ You can rely on the normal read queue and C handling afterwards. This is the cleanest way to close a connection. +This method may invoke callbacks (and therefore the handle might be +destroyed after it returns). + =cut sub push_shutdown { @@ -1238,6 +1250,9 @@ the new callback is C). See the description of C in the constructor. +This method may invoke callbacks (and therefore the handle might be +destroyed after it returns). + =cut sub on_read { @@ -1286,6 +1301,9 @@ interested in (which can be none at all) and return a true value. After returning true, it will be removed from the queue. +These methods may invoke callbacks (and therefore the handle might be +destroyed after it returns). + =cut our %RH; @@ -1713,7 +1731,7 @@ sub start_read { my ($self) = @_; - unless ($self->{_rw} || $self->{_eof}) { + unless ($self->{_rw} || $self->{_eof} || !$self->{fh}) { Scalar::Util::weaken $self; $self->{_rw} = AE::io $self->{fh}, 0, sub { @@ -1816,6 +1834,7 @@ while (length ($tmp = Net::SSLeay::BIO_read ($self->{_wbio}))) { $self->{wbuf} .= $tmp; $self->_drain_wbuf; + $self->{tls} or return; # tls session might have gone away in callback } $self->{_on_starttls} @@ -1850,6 +1869,9 @@ handshakes on the same stream. Best do not attempt to use the stream after stopping TLS. +This method may invoke callbacks (and therefore the handle might be +destroyed after it returns). + =cut our %TLS_CACHE; #TODO not yet documented, should we? @@ -1924,15 +1946,18 @@ Shuts down the SSL connection - this makes a proper EOF handshake by sending a close notify to the other side, but since OpenSSL doesn't -support non-blocking shut downs, it is not guarenteed that you can re-use +support non-blocking shut downs, it is not guaranteed that you can re-use the stream afterwards. +This method may invoke callbacks (and therefore the handle might be +destroyed after it returns). + =cut sub stoptls { my ($self) = @_; - if ($self->{tls}) { + if ($self->{tls} && $self->{fh}) { Net::SSLeay::shutdown ($self->{tls}); &_dotls; @@ -2019,6 +2044,29 @@ #nop } +=item $handle->destroyed + +Returns false as long as the handle hasn't been destroyed by a call to C<< +->destroy >>, true otherwise. + +Can be useful to decide whether the handle is still valid after some +callback possibly destroyed the handle. For example, C<< ->push_write >>, +C<< ->starttls >> and other methods can call user callbacks, which in turn +can destroy the handle, so work can be avoided by checking sometimes: + + $hdl->starttls ("accept"); + return if $hdl->destroyed; + $hdl->push_write (... + +Note that the call to C will silently be ignored if the handle +has been destroyed, so often you can just ignore the possibility of the +handle being destroyed. + +=cut + +sub destroyed { 0 } +sub AnyEvent::Handle::destroyed::destroyed { 1 } + =item AnyEvent::Handle::TLS_CTX This function creates and returns the AnyEvent::TLS object used by default