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