From: Graham B. <gb...@us...> - 2003-06-06 22:47:17
|
Update of /cvsroot/perl-ldap/ldap/lib/Net In directory sc8-pr-cvs1:/tmp/cvs-serv22500/lib/Net Modified Files: LDAP.pm Log Message: Fix reference loop problem by hiding the real object behind a tied hash and only using the inner hash internally and the outer hash externally Index: LDAP.pm =================================================================== RCS file: /cvsroot/perl-ldap/ldap/lib/Net/LDAP.pm,v retrieving revision 1.53 retrieving revision 1.54 diff -u -d -r1.53 -r1.54 --- LDAP.pm 19 May 2003 22:36:10 -0000 1.53 +++ LDAP.pm 6 Jun 2003 22:47:13 -0000 1.54 @@ -7,6 +7,7 @@ use strict; use IO::Socket; use IO::Select; +use Tie::Hash; use vars qw($VERSION $LDAP_VERSION @ISA); use Convert::ASN1 qw(asn_read); use Net::LDAP::Message; @@ -23,10 +24,11 @@ LDAP_SERVER_DOWN LDAP_USER_CANCELED LDAP_EXTENSION_START_TLS + LDAP_UNAVAILABLE ); -$VERSION = "0.28"; -@ISA = qw(Net::LDAP::Extra); +$VERSION = "0.28_01"; +@ISA = qw(Tie::StdHash Net::LDAP::Extra); $LDAP_VERSION = 3; # default LDAP protocol version # Net::LDAP::Extra will only exist is someone use's the module. But we need @@ -124,7 +126,7 @@ $obj->debug($arg->{debug} || 0 ); - $obj; + $obj->outer; } sub connect_ldap { @@ -802,7 +804,9 @@ sub _drop_conn { my ($self, $err, $etxt) = @_; - delete $self->{net_ldap_socket}; + my $sock = delete $self->{net_ldap_socket}; + close($sock) if $sock; + if (my $msgs = delete $self->{net_ldap_mesg}) { foreach my $mesg (values %$msgs) { $mesg->set_error($err, $etxt); @@ -964,6 +968,30 @@ @_ ? ($ldap->{net_ldap_version},$ldap->{net_ldap_version} = shift)[0] : $ldap->{net_ldap_version}; +} + +sub outer { + my $self = shift; + return $self if tied(%$self); + my %outer; + tie %outer, ref($self), $self; + ++$self->{net_ldap_refcnt}; + bless \%outer, ref($self); +} + +sub inner { + tied(%{$_[0]}) || $_[0]; +} + +sub TIEHASH { + $_[1]; +} + +sub DESTROY { + my $ldap = shift; + my $inner = tied(%$ldap) or return; + _drop_conn($inner, LDAP_UNAVAILABLE, "Implicit disconnect") + unless --$inner->{net_ldap_refcnt}; } 1; |