Skip to content

Commit

Permalink
Fix leaking file handles when loading modules
Browse files Browse the repository at this point in the history
Since commit efadff2 a PrecompilationUnit is
marked uninitialized after closing. When we use an accessor like .checksum
after closing (by !load-handle-for-path), the precomp file gets reopened and
stays that way.
When we load multiple modules with a shared dependency, we will detect that
dependency is already loaded and not call !load-handle-for-path for it again.
Unfortunately we also do not get the side effect of closing the unit this way.

Fix by moving the .close call out of !load-handle-for-path, making the program
flow more clear and using the accessors before the explicit call to .close.
  • Loading branch information
niner committed Jan 17, 2020
1 parent 8c0a5d6 commit 1c46740
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/core.c/CompUnit/PrecompilationRepository.pm6
Expand Up @@ -70,7 +70,6 @@ class CompUnit::PrecompilationRepository::Default does CompUnit::PrecompilationR
if $*RAKUDO_MODULE_DEBUG -> $RMD { $RMD("Loading precompiled\n$unit") }
#?if !jvm
my $handle := CompUnit::Loader.load-precompilation-file($unit.bytecode-handle);
$unit.close;
#?endif
#?if jvm
my $handle := CompUnit::Loader.load-precompilation($unit.bytecode);
Expand Down Expand Up @@ -150,6 +149,7 @@ class CompUnit::PrecompilationRepository::Default does CompUnit::PrecompilationR
unless %loaded{$dependency-precomp.id}:exists {
%loaded{$dependency-precomp.id} = self!load-handle-for-path($dependency-precomp);
}
$dependency-precomp.close;
}
}

Expand Down Expand Up @@ -195,9 +195,11 @@ class CompUnit::PrecompilationRepository::Default does CompUnit::PrecompilationR
and (not $source or ($checksum //= nqp::sha1($source.slurp(:enc<iso-8859-1>))) eq $unit.source-checksum)
and self!load-dependencies($unit, @precomp-stores)
{
my $checksum = $unit.checksum;
my \loaded = self!load-handle-for-path($unit);
$unit.close;
$loaded-lock.protect: { %loaded{$id} = loaded };
return (loaded, $unit.checksum);
return (loaded, $checksum);
}
else {
$RMD("Outdated precompiled {$unit}{$source ?? " for $source" !! ''}\n"
Expand Down

0 comments on commit 1c46740

Please sign in to comment.