On Wednesday 26 September 2007 14:26:20 [EMAIL PROTECTED] wrote:

> Author: coke
> Date: Wed Sep 26 14:26:19 2007
> New Revision: 21613
>
> Modified:
>    trunk/lib/Parrot/Configure/Messages.pm
>    trunk/tools/build/c2str.pl
>
> Log:
> [build]
>
> Update c2str.pl so that multiple copies running simultaneously no longer
> step on each other's toes drunkenly with a jackhammer.
>
> With this fix (Courtesy of jhorwitz++), 'make -j 2' now works, tested
> on a variety of platforms.

It even works for make -j 9 for me (two cores, but I like to keep them busy).  
However...

> Modified: trunk/tools/build/c2str.pl
> ===========================================================================
>=== --- trunk/tools/build/c2str.pl     (original)
> +++ trunk/tools/build/c2str.pl        Wed Sep 26 14:26:19 2007
> @@ -19,6 +19,21 @@
>
>  my $outfile          = 'all_cstring.str';
>  my $string_private_h = 'src/string_private_cstring.h';
> +my $lockfile         = "$outfile.lck";
> +my $max_lock_wait    = 120;
> +
> +my $start_time = time;
> +while ( -e $lockfile ) {
> +    sleep 1;
> +    if ( time - $start_time > $max_lock_wait ) {
> +        die "Lock still held after $max_lock_wait seconds -- something is
> wrong!"; +    }
> +}

... isn't there a race condition right here?

> +open my $lock, '>', $lockfile or die "Can't write '$lockfile': $!";
> +print $lock "$$\n";
> +close $lock;
> +
> +$SIG{'__DIE__'} = sub { unlink $lockfile };

For what it's worth, I think this patch is safer.  I did have some trouble 
with -j 3 and higher, but it's working for me on 32-bit x86 Linux now up 
to -j 9.

-- c

=== tools/build/c2str.pl
==================================================================
--- tools/build/c2str.pl	(revision 6130)
+++ tools/build/c2str.pl	(local)
@@ -13,6 +13,7 @@
 use strict;
 use lib 'lib';
 
+use Fcntl qw( :DEFAULT :flock );
 use Text::Balanced qw(extract_delimited);
 use Math::BigInt;
 use Getopt::Long;
@@ -20,21 +21,13 @@
 my $outfile          = 'all_cstring.str';
 my $string_private_h = 'src/string_private_cstring.h';
 my $lockfile         = "$outfile.lck";
-my $max_lock_wait    = 120;
 
-my $start_time = time;
-while ( -e $lockfile ) {
-    sleep 1;
-    if ( time - $start_time > $max_lock_wait ) {
-        die "Lock still held after $max_lock_wait seconds -- something is wrong!";
-    }
-}
-open my $lock, '>', $lockfile or die "Can't write '$lockfile': $!";
-print $lock "$$\n";
-close $lock;
+sysopen( my $lock, $lockfile, O_CREAT ) or die "Can't write '$lockfile': $!\n";
 
-$SIG{'__DIE__'} = sub { unlink $lockfile };
+flock($lock, LOCK_EX) or die "Can't lock '$lockfile': $!\n";
 
+END { close $lock; unlink $lockfile; }
+
 my ( $result, $do_all, $do_init, $file );
 $result = GetOptions(
     "all"  => \$do_all,
@@ -42,14 +35,12 @@
 );
 
 $do_all and do {
-    &read_all;
-    &create_c_include;
-    unlink $lockfile;
+    read_all();
+    create_c_include();
     exit;
 };
 $do_init and do {
     unlink $outfile;
-    unlink $lockfile;
     exit;
 };
 
@@ -61,13 +52,11 @@
 my %known_strings = ();
 my @all_strings;
 
-&read_all;
+read_all();
 open my $ALL, '>>', $outfile or die "Can't write '$outfile': $!";
 process_cfile();
 close $ALL;
 
-unlink $lockfile;
-
 sub hash_val {
     my $h = Math::BigInt->new('+0');
     my $s = shift;

Reply via email to