1# Blocking Exclusive Lock Test
2
3use strict;
4use warnings;
5
6use Test::More;
7if( $^O eq 'MSWin32' ) {
8  plan skip_all => 'Tests fail on Win32 due to forking';
9}
10else {
11  plan tests => 20+2;
12}
13use File::NFSLock;
14use Fcntl qw(O_CREAT O_RDWR O_RDONLY O_TRUNC LOCK_EX);
15
16# $m simultaneous processes each trying to count to $n
17my $m = 20;
18my $n = 50;
19
20$| = 1; # Buffer must be autoflushed because of fork() below.
21
22my $datafile = "testfile.dat";
23
24# Create a blank file
25sysopen ( my $fh, $datafile, O_CREAT | O_RDWR | O_TRUNC );
26close ($fh);
27ok (-e $datafile && !-s _);
28
29for (my $i = 0; $i < $m ; $i++) {
30  # For each process
31  if (!fork) {
32    # Child process need to count to $n
33    for (my $j = 0; $j < $n ; $j++) {
34      my $lock = new File::NFSLock {
35        file => $datafile,
36        lock_type => LOCK_EX,
37      };
38      sysopen(my $fh, $datafile, O_RDWR);
39      # Read the current value
40      my $count = <$fh>;
41      # Increment it
42      $count ++;
43      # And put it back
44      seek ($fh,0,0);
45      print $fh "$count\n";
46      close $fh;
47    }
48    exit;
49  }
50}
51
52for (my $i = 0; $i < $m ; $i++) {
53  # Wait until all the children are finished counting
54  wait;
55  ok 1;
56}
57
58# Load up whatever the file says now
59sysopen(my $fh2, $datafile, O_RDONLY);
60$_ = <$fh2>;
61close $fh2;
62chomp;
63# It should be $m processes time $n each
64is $n*$m, $_;
65
66# Wipe the temporary file
67unlink $datafile;
68