Re: Destructor Order
by tilly (Archbishop) on Apr 03, 2004 at 03:26 UTC
|
There is no easy way to guarantee that the COM port object is still there when you destroy the Reader object if the destruction happens during global destruction (which it sounds like it may be in your case). The reason is that global destruction goes by force, and nobody is safe (necessary to be sure that circular references get cleaned up). I believe that 5.8 has a hack to make sure that things often get cleaned up in a convenient order, but there are cases where that fails.
Instead arrange to have the object cleaned up in an END block. END blocks are processed before global destruction, and so you can safely rely on things that you expect to still find alive, not being destroyed out of order. | [reply] |
|
|
Yes, the problem is happening during global destruction.
I tried an END block, and it works, with some caveats. It seems END blocks don't fire if the script exits from an uncaught signal, which is how the script is exiting, at least while I'm testing. Adding signal handlers that just call exit(1) seems to work fine, though, although it feels kludgey.
Thanks!
| [reply] [d/l] [select] |
|
|
Just switching to use lexicals instead of package variables should avoid global destruction and let your objects be destroyed as their refcounts dictate, e.g.:
$ perl -w
sub DESTROY { warn $_[0]->{name} }
my $inner = bless {name => "inner"};
my $outer = bless {name => "outer", inner => $inner};
__END__
outer at - line 1.
inner at - line 1.
| [reply] [d/l] |
Re: Destructor Order
by Zaxo (Archbishop) on Apr 03, 2004 at 02:08 UTC
|
The first replies you have are excellent technical ways to enforce a destruct order. They will work fine for you. You may want to use OO principles to get a more direct and self-contained solution.
Since the "Thanks, stop now" command is for the serial port connection, you can make it part of that object's destructor by including it in a sub DESTROY for the COM port object.
| [reply] [d/l] |
|
|
Will they really influencing the order destructors are called during global destruction? There doesn't seem to be general agreement that they will. They seem to involve holding refernces, but my Reader object is holding a reference to the COM port object, but is nonetheless destroyed before it. Maybe I'm missing something...
Regardless, subclassing the COM port object is a clever idea. Thanks!
| [reply] [d/l] |
Re: Destructor Order
by BrowserUk (Patriarch) on Apr 03, 2004 at 06:07 UTC
|
If the main cause of uncontrolled termination is interuption via sigint, then installing a signal handler $SIG{INT} = sub{ #Stop now }};and perfroming your clean up there may be in order.
END{} blocks aren't run when programs are interupted by sigint(2) (under win32 at least).
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
| [reply] [d/l] [select] |
Re: Destructor Order
by TomDLux (Vicar) on Apr 03, 2004 at 00:54 UTC
|
Develop a subclass which takes and saves a reference to the COM port ... should take five or ten lines of code. That way, you're guaranteed that the port exists until the reader is gone.
--
TTTATCGGTCGTTATATAGATGTTTGCA
| [reply] |
|
|
| [reply] |
Re: Destructor Order
by cormac (Acolyte) on Apr 03, 2004 at 01:21 UTC
|
You could create an object class that inherits from your RFID::Matrics::Reader class, additionally implementing a tied element using perltie and BSD::Resource to deal with these events accordingly.
| [reply] |