Re: [MacPerl] MacPerl Beta
[email protected] (Philippe Wiede)
| Newsgroups | perl.macperl.porters |
|---|---|
| Organization | Megapublic Inc. |
| Message-ID | <[email protected]> |
Chris
It's difficult to provide you a "short, complete, "working" test case"
since the application in question is rather large. However, I managed to
backtrace the crashes to one of my modules, which handles Berkeley DBM
managing tasks. The culprit was found in the DESTROY sub of this module,
where the DESTROY function would first close any open DBMS including
their ref pointers and release lock files. While using the beta, I
always had MacPerl crash on me after any application utilizing this
module finished its task. Below you will find the relevant subs of this module:
# Object explanation:
# $me: blessed hash object
# $me->{_db}: holds the file path
# $me->{_fs}->{$me->{_db}}->{dbopen}: hash element, set to 1 if DBM tied
# $me->{_fs}->{$me->{_db}}->{locked}: hash element, set to 1 if DBM locked
# $me->{_fs}->{$me->{_db}}->{fh}: hash element, stores lock file handle
# $me->{curr_pids}->{$$}: hash element, stores current pid
# $me->{tied_ref}->{$me->{_db}}: ref pointer to its DBM file
# %{$me->{DBM}}: the tied DBM hash
# The commented untie line in CLOSE_DB cause MacPerl beta to crash
# during clean-up via DESTROY when an application using this module
# exits normally.
# "Normally" meaning that any tied database already has been closed
# explicitly by the application.
# Crash cause: DBM hash ref already undefined (closed) while trying to untie
# Crash fix: check if the ref and hash still exist before doing untie
sub CLOSE_DB {
my $me = shift;
if ( $me->{tied_ref}->{$me->{_db}} ) {
$me->{tied_ref}->{$me->{_db}}->sync(); # flush buffer to disk
}
undef $me->{tied_ref}->{$me->{_db}};
untie %{$me->{DBM}} if ref $me->{DBM}
&& defined keys %{$me->{DBM}}; # OK
###untie %{$me->{DBM}}; # CAUSES THE CRASH
if ( $me->{_fs}->{$me->{_db}}->{locked} ) {
my $fh = $me->{_fs}->{$me->{_db}}->{fh};
close $fh;
$me->{_fs}->{$me->{_db}}->{locked} = '';
}
$me->{_fs}->{$me->{_db}} = { dbopen => 0, fh => undef };
}
sub DESTROY {
my $me = shift;
return unless ref $me;
$me->CLOSE_DB() if defined $me->{_fs}->{$me->{_db}}->{dbopen}
&& $me->{_db} && exists $me->{_fs}->{$me->{_db}}->{dbopen};
delete $me->{curr_pids}->{$$} if defined $me->{curr_pids}->{$$};
}
Does this help you any further? I had no problems under the old standard
MacPerl release.
Cheers, Philippe
Philippe Wiede
Megapublic (R), Inc.
Gemsberg 11, 4051 Basel, Switzerland
www.megapublic.com
Chris Nandor wrote:
> Hm. Can you provide a short, complete, "working" test case, and either
> submit a bug report to SourceForge or mail it to [email protected]?