Re: Signal handlers, objects and reference counting.



nospam@xxxxxxxxxxxxx (Jamie) wrote:
Hello Newsgroup,

Say I've got an object that needs to be notified on SIGCONT
(or PIPE or ...)

I can do this:

my($self) = shift;
$SIG{CONT} = sub {
$self->do_whatever();
};

But then.. when the object goes out of scope, it never gets cleaned
up because of the $self in the closure

Isn't this a good thing? As long as the signal handler is set up to
call do_whatever, shouldn't it be able to make that call? How can it do
that other than by keeping the object alive? If you set the SIG{CONT} with
"local", then it would automatically destroy the sub-ref, which would then
lead to the destruction of the $self object, after $self goes out of
lexical scope and the SIG localization goes out of dynamic scope.

But if that isn't what you want, then use Scalar::Util::weaken.


use Scalar::Util qw(weaken);
{
my $self=new foo;
{my $dummy=$self; weaken $dummy; $SIG{CONT}=sub { $dummy->whatever() }};
warn "About to go out of scope in $$"; sleep 5;
};
warn "self just went out of scope";
package foo;
sub new { bless {}};
sub DESTROY {warn "Destroying @_"};
sub whatever {warn "whatever"};
__END__


About to go out of scope in 28684 at - line 6.
Destroying foo=HASH(0x804d41c) at - line 11.
self just went out of scope at - line 8.

Notice that it is destroyed when $self goes out of scope, rather than
during global destruction.


(To say nothing of other things
that might want to be alerted as well)

Saying something about it is not a very good way to say nothing
about it. :) This makes me think the problem is substantially more
complicated than you are describing, which means the answer may be too.


Best I can do is have a global
variable with $self in it, and a cleanup method that determines if it's
the same as global, then undef's it.

If you have to decide in your code when to clean it up, why not just unset
the sig-handler at that point, rather than undef something else?


What is a good, standard way of dealing with this?

On that note, what is a good way of finding memory leaks?


I've got quite a number of modules with circular references (By design,
they need to be that way unfortunately.)

Does each circularity lie entirely within one module, or does the
circularity span modules? If the former, test each module independently,
using weaken to bypass the circularity. If the latter, then good luck to
you and seriously consider redesigning.


What I'd like is a tool that'll show me how many (and ideally where/who)
is holding on to a given object so I know where to free it.

I don't see how the described tool will help you obtain the stated goal.
As the programmer/designer of circular references, only you can know where
they ought to be freed, perl cannot tell you that. It seems you need help
figuring *how* to free it, not where to free it. (Or perhaps you need help
figuring out how to design it so that it is freed automatically, which
still not the same thing as where to free it.)


Know any good tricks for reference tracking and deleting?

sub DESTROY {warn "I'm being destroyed @_"}

Not so much
modules, just handy debugging tricks to track them. (What is the
reference count on variable $foo and ideally, who holds it?)

To find circular refs, you can do something like this:

.....
sub new {
my $foo = bless {}; # or whatever the constructor would be
push @::objects, $foo;
Scalar::Util::weaken $::objects[-1];
return $foo;
};
.....
use Data::Dumper;
END {
warn "Ending with the following un-cleaned up objects:";
print Dumper [grep defined, @::objects];
};

By inspecting the Data::Dumper results, you should be able to figure
where the circularity lies.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
.



Relevant Pages

  • Re: how to remove a variable in SKILL
    ... in SKILL to destroy a symbol once it has been created. ... variables automatically go out of scope when the let which bound them ... (foo c=a+b)) ...
    (comp.cad.cadence)
  • Re: Syntax simplification
    ... >>IMO, the type/behaviour polymorphism of has always ... and that of empty words and empty sentences. ... 'foo bar'", or "take the first word of the sentence 'foo bar'". ... >reason for dynamic scope -- the user should not have to know that there is ...
    (comp.lang.logo)
  • Re: Trouble with variable scoping
    ... You are confusing file scope with global. ... That is possibly the most common misperception about Perl that I've ... fully-qualify any global variables you decide to use. ... a lexical variable $foo exists in the current scope. ...
    (perl.beginners)
  • Re: Automatic variable is not destroyed?
    ... It goes out of scope. ... but I think the end of c's lifetime was more relevant here ... However, the standard says ... doesn't even indicate what the word "destroy" might mean in this ...
    (comp.lang.c)
  • Re: weird bug
    ... package Foo; ... immediately surrounding scope. ... Either you parse the eval string ...
    (comp.lang.perl.misc)