Skip to content

Commit

Permalink
Do locking properly in precomp store File class.
Browse files Browse the repository at this point in the history
Turns out that there's some races in there besides the initial one
to write @!dependencies. So, use a lock. Fixes a warning that was
spat out in 1 run in 100 of the htmlify.p6 golf.
  • Loading branch information
jnthn committed Feb 8, 2017
1 parent 39c517e commit 917d473
Showing 1 changed file with 20 additions and 18 deletions.
38 changes: 20 additions & 18 deletions src/core/CompUnit/PrecompilationStore/File.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class CompUnit::PrecompilationStore::File does CompUnit::PrecompilationStore {
has $!initialized = False;
has $.checksum;
has $!bytecode;
has Lock $!update-lock = Lock.new;

submethod BUILD(CompUnit::PrecompilationId :$!id, IO::Path :$!path, :@!dependencies, :$!bytecode --> Nil) {
if $!bytecode {
Expand All @@ -24,21 +25,18 @@ class CompUnit::PrecompilationStore::File does CompUnit::PrecompilationStore {
}

method !read-dependencies() {
return if $!initialized;
self!open(:r) unless $!file;

$!checksum = $!file.get;
my $dependency = $!file.get;
my CompUnit::PrecompilationDependency @deps;
while $dependency {
@deps.push: CompUnit::PrecompilationDependency::File.deserialize($dependency);
$dependency = $!file.get;
$!update-lock.protect: {
return if $!initialized;
self!open(:r) unless $!file;

$!checksum = $!file.get;
my $dependency = $!file.get;
while $dependency {
@!dependencies.push: CompUnit::PrecompilationDependency::File.deserialize($dependency);
$dependency = $!file.get;
}
$!initialized = True;
}
# This bind helps towards thread safety; we may race to update it
# in the very occasional case, but we'll end up with the same data
# in there anyway. This saves us on a lock.
@!dependencies := @deps;
$!initialized = True;
}

method dependencies(--> Array[CompUnit::PrecompilationDependency]) {
Expand All @@ -47,8 +45,10 @@ class CompUnit::PrecompilationStore::File does CompUnit::PrecompilationStore {
}

method bytecode(--> Buf) {
self!read-dependencies;
$!bytecode //= $!file.slurp-rest(:bin,:close)
$!update-lock.protect: {
self!read-dependencies;
$!bytecode //= $!file.slurp-rest(:bin,:close)
}
}

method bytecode-handle(--> IO::Handle) {
Expand All @@ -66,8 +66,10 @@ class CompUnit::PrecompilationStore::File does CompUnit::PrecompilationStore {
}

method close(--> Nil) {
$!file.close if $!file;
$!file = Nil;
$!update-lock.protect: {
$!file.close if $!file;
$!file = Nil;
}
}

method save-to(IO::Path $precomp-file) {
Expand Down

0 comments on commit 917d473

Please sign in to comment.