comparison Lib/IMPL/Profiler/Memory.pm @ 194:4d0e1962161c

Replaced tabs with spaces IMPL::Web::View - fixed document model, new features (control classes, document constructor parameters)
author cin
date Tue, 10 Apr 2012 20:08:29 +0400
parents cd1ff7029a63
children
comparison
equal deleted inserted replaced
193:8e8401c0aea4 194:4d0e1962161c
6 6
7 my %listeners; 7 my %listeners;
8 my $trapped; 8 my $trapped;
9 9
10 BEGIN { 10 BEGIN {
11 $trapped = 0; 11 $trapped = 0;
12 } 12 }
13 13
14 sub import { 14 sub import {
15 if (not $trapped) { 15 if (not $trapped) {
16 *CORE::GLOBAL::bless = sub { 16 *CORE::GLOBAL::bless = sub {
17 $_[1] |= caller unless $_[1]; 17 $_[1] |= caller unless $_[1];
18 my $ref = CORE::bless $_[0],$_[1]; 18 my $ref = CORE::bless $_[0],$_[1];
19 19
20 $_->track($ref) foreach values %listeners; 20 $_->track($ref) foreach values %listeners;
21 21
22 return $ref; 22 return $ref;
23 }; 23 };
24 $trapped = 1; 24 $trapped = 1;
25 } 25 }
26 } 26 }
27 27
28 sub _ConnectListener { 28 sub _ConnectListener {
29 my ($self,$listener) = @_; 29 my ($self,$listener) = @_;
30 30
31 die "Invalid listener" unless ref $listener; 31 die "Invalid listener" unless ref $listener;
32 32
33 $listeners{refaddr($listener)} = $listener; 33 $listeners{refaddr($listener)} = $listener;
34 } 34 }
35 35
36 sub _RemoveListener { 36 sub _RemoveListener {
37 my ($self,$listener) = @_; 37 my ($self,$listener) = @_;
38 38
39 die "Invalid listener" unless ref $listener; 39 die "Invalid listener" unless ref $listener;
40 40
41 delete $listeners{refaddr($listener)}; 41 delete $listeners{refaddr($listener)};
42 } 42 }
43 43
44 sub Monitor { 44 sub Monitor {
45 my ($self,$code) = @_; 45 my ($self,$code) = @_;
46 46
47 my $data = IMPL::Profiler::Memory::Data->new(); 47 my $data = IMPL::Profiler::Memory::Data->new();
48 48
49 $data->Monitor($code); 49 $data->Monitor($code);
50 50
51 return $data; 51 return $data;
52 } 52 }
53 53
54 package IMPL::Profiler::Memory::Data; 54 package IMPL::Profiler::Memory::Data;
55 use parent qw(IMPL::Object::Fields); 55 use parent qw(IMPL::Object::Fields);
56 56
58 use Scalar::Util qw(refaddr weaken isweak); 58 use Scalar::Util qw(refaddr weaken isweak);
59 59
60 use fields qw( objects counter); 60 use fields qw( objects counter);
61 61
62 sub CTOR { 62 sub CTOR {
63 my $this = shift; 63 my $this = shift;
64 $this->{objects} = []; 64 $this->{objects} = [];
65 $this->{counter} = 0; 65 $this->{counter} = 0;
66 } 66 }
67 67
68 sub track { 68 sub track {
69 my $i = scalar @{$_[0]->{objects}}; 69 my $i = scalar @{$_[0]->{objects}};
70 $_[0]->{objects}[$i] = $_[1]; 70 $_[0]->{objects}[$i] = $_[1];
71 weaken($_[0]->{objects}[$i]); 71 weaken($_[0]->{objects}[$i]);
72 $_[0]->{counter} ++; 72 $_[0]->{counter} ++;
73 } 73 }
74 74
75 sub Purge { 75 sub Purge {
76 my $this = shift; 76 my $this = shift;
77 77
78 return $this->{objects} = [ grep defined($_), @{$this->{objects}}]; 78 return $this->{objects} = [ grep defined($_), @{$this->{objects}}];
79 } 79 }
80 80
81 sub Dump { 81 sub Dump {
82 my $this = shift; 82 my $this = shift;
83 return Data::Dumper->Dump([$this->{objects}]); 83 return Data::Dumper->Dump([$this->{objects}]);
84 } 84 }
85 85
86 sub isLeak { 86 sub isLeak {
87 my ($this) = @_; 87 my ($this) = @_;
88 $this->Purge(); 88 $this->Purge();
89 return ( scalar(@{$this->{objects}}) > 0); 89 return ( scalar(@{$this->{objects}}) > 0);
90 } 90 }
91 91
92 sub Monitor { 92 sub Monitor {
93 my ($this,$code) = @_; 93 my ($this,$code) = @_;
94 94
95 die "A reference to a subroutine is required" unless ref $code; 95 die "A reference to a subroutine is required" unless ref $code;
96 96
97 IMPL::Profiler::Memory->_ConnectListener($this); 97 IMPL::Profiler::Memory->_ConnectListener($this);
98 eval { 98 eval {
99 $code->(); 99 $code->();
100 }; 100 };
101 my $err = $@; 101 my $err = $@;
102 IMPL::Profiler::Memory->_RemoveListener($this); 102 IMPL::Profiler::Memory->_RemoveListener($this);
103 103
104 die $err if $err; 104 die $err if $err;
105 105
106 return; 106 return;
107 } 107 }
108 108
109 109
110 110
111 1; 111 1;