home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / Extrefs.pm < prev    next >
Encoding:
Perl POD Document  |  2003-11-22  |  4.6 KB  |  185 lines

  1. # $Id: Extrefs.pm,v 1.9 2003/11/22 05:05:10 rcaputo Exp $
  2.  
  3. # The data necessary to manage tagged extra/external reference counts
  4. # on sessions, and the accessors to get at them sanely from other
  5. # files.
  6.  
  7. package POE::Resources::Extrefs;
  8.  
  9. use vars qw($VERSION);
  10. $VERSION = do {my@r=(q$Revision: 1.9 $=~/\d+/g);sprintf"%d."."%04d"x$#r,@r};
  11.  
  12. # These methods are folded into POE::Kernel;
  13. package POE::Kernel;
  14.  
  15. use strict;
  16.  
  17. ### The count of all extra references used in the system.
  18.  
  19. my %kr_extra_refs;
  20. #  ( $session =>
  21. #    { $tag => $count,
  22. #       ...,
  23. #     },
  24. #     ...,
  25. #   );
  26.  
  27. ### End-run leak checking.
  28.  
  29. sub _data_extref_finalize {
  30.   my $finalized_ok = 1;
  31.   foreach my $session (keys %kr_extra_refs) {
  32.     $finalized_ok = 0;
  33.     _warn "!!! Leaked extref: $session\n";
  34.     foreach my $tag (keys %{$kr_extra_refs{$session}}) {
  35.       _warn "!!!\t`$tag' = $kr_extra_refs{$session}->{$tag}\n";
  36.     }
  37.   }
  38.   return $finalized_ok;
  39. }
  40.  
  41. # Increment a session's tagged reference count.  If this is the first
  42. # time the tag is used in the session, then increment the session's
  43. # reference count as well.  Returns the tag's new reference count.
  44. #
  45. # -><- Allows incrementing reference counts on sessions that don't
  46. # exist, but the public interface catches that.
  47.  
  48. sub _data_extref_inc {
  49.   my ($self, $session, $tag) = @_;
  50.   my $refcount = ++$kr_extra_refs{$session}->{$tag};
  51.  
  52.   $self->_data_ses_refcount_inc($session) if $refcount == 1;
  53.  
  54.   if (TRACE_REFCNT) {
  55.     _warn(
  56.       "<rc> incremented extref ``$tag'' (now $refcount) for ",
  57.       $self->_data_alias_loggable($session)
  58.     );
  59.   }
  60.  
  61.   return $refcount;
  62. }
  63.  
  64. # Decrement a session's tagged reference count, removing it outright
  65. # if the count reaches zero.  Return the new reference count or undef
  66. # if the tag doesn't exist.
  67. #
  68. # -><- Allows negative reference counts, and the resulting hilarity.
  69. # Hopefully the public interface won't allow it.
  70.  
  71. sub _data_extref_dec {
  72.   my ($self, $session, $tag) = @_;
  73.  
  74.   if (ASSERT_DATA) {
  75.     unless (exists $kr_extra_refs{$session}->{$tag}) {
  76.       _trap(
  77.         "<dt> decrementing extref for nonexistent tag ``$tag'' in ",
  78.         $self->_data_alias_loggable($session)
  79.       );
  80.     }
  81.   }
  82.  
  83.   my $refcount = --$kr_extra_refs{$session}->{$tag};
  84.  
  85.   if (TRACE_REFCNT) {
  86.     _warn(
  87.       "<rc> decremented extref ``$tag'' (now $refcount) for ",
  88.       $self->_data_alias_loggable($session)
  89.     );
  90.   }
  91.  
  92.   $self->_data_extref_remove($session, $tag) unless $refcount;
  93.   return $refcount;
  94. }
  95.  
  96. ### Remove an extra reference from a session, regardless of its count.
  97.  
  98. sub _data_extref_remove {
  99.   my ($self, $session, $tag) = @_;
  100.  
  101.   if (ASSERT_DATA) {
  102.     unless (exists $kr_extra_refs{$session}->{$tag}) {
  103.       _trap(
  104.         "<dt> decrementing extref for nonexistent tag ``$tag'' in ",
  105.         $self->_data_alias_loggable($session)
  106.       );
  107.     }
  108.   }
  109.  
  110.   delete $kr_extra_refs{$session}->{$tag};
  111.   delete $kr_extra_refs{$session}
  112.     unless scalar keys %{$kr_extra_refs{$session}};
  113.   $self->_data_ses_refcount_dec($session);
  114. }
  115.  
  116. ### Clear all the extra references from a session.
  117.  
  118. sub _data_extref_clear_session {
  119.   my ($self, $session) = @_;
  120.   return unless exists $kr_extra_refs{$session}; # avoid autoviv
  121.   foreach (keys %{$kr_extra_refs{$session}}) {
  122.     $self->_data_extref_remove($session, $_);
  123.   }
  124.  
  125.   if (ASSERT_DATA) {
  126.     if (keys %{$kr_extra_refs{$session}}) {
  127.       _trap(
  128.         "<dt> extref clear did not remove session ",
  129.         $self->_data_alias_loggable($session)
  130.       );
  131.     }
  132.   }
  133. }
  134.  
  135. # Fetch the number of sessions with extra references held in the
  136. # entire system.
  137.  
  138. sub _data_extref_count {
  139.   return scalar keys %kr_extra_refs;
  140. }
  141.  
  142. # Fetch whether a session has extra references.
  143.  
  144. sub _data_extref_count_ses {
  145.   my ($self, $session) = @_;
  146.   return 0 unless exists $kr_extra_refs{$session};
  147.   return scalar keys %{$kr_extra_refs{$session}};
  148. }
  149.  
  150. 1;
  151.  
  152. __END__
  153.  
  154. =head1 NAME
  155.  
  156. POE::Resources::Extrefs - tagged "extra" ref. count management for POE::Kernel
  157.  
  158. =head1 SYNOPSIS
  159.  
  160. Used internally by POE::Kernel.  Better documentation will be
  161. forthcoming.
  162.  
  163. =head1 DESCRIPTION
  164.  
  165. This module encapsulates and provides accessors for POE::Kernel's data
  166. structures that manage tagged reference counts.  It is used internally
  167. by POE::Kernel and has no public interface.
  168.  
  169. =head1 SEE ALSO
  170.  
  171. See L<POE::Kernel> for documentation on tagged reference counts.
  172.  
  173. =head1 BUGS
  174.  
  175. There is no mechanism in place to prevent extra reference count names
  176. from clashing.
  177.  
  178. Probably others.
  179.  
  180. =head1 AUTHORS & COPYRIGHTS
  181.  
  182. Please see L<POE> for more information about authors and contributors.
  183.  
  184. =cut
  185.