aboutsummaryrefslogtreecommitdiff
blob: 1d94006d125a65ca3a1e3f238331b53feeeb5fd0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/usr/bin/perl
use strict;
use warnings;

# import LOCK_*
use Fcntl qw(:flock);

my $lockbase      = shift;    # suggested: $GL_REPO_BASE/$GL_REPO.git/.gl-mirror-push-lock.$COPY_NAME
my @cmd_plus_args = @ARGV;    # the actual 'gitolite mirror ...' command
@ARGV = ();

# ----------------------------------------------------------------------

open( my $fhrun, ">", "$lockbase.run" ) or die "open '$lockbase.run' failed: $!";
if ( flock( $fhrun, LOCK_EX | LOCK_NB ) ) {
    # got run lock; you're good to go

    system(@cmd_plus_args);

    flock( $fhrun, LOCK_UN );
    exit 0;
}

# "run" lock failed; someone is already running the command

open( my $fhqueue, ">", "$lockbase.queue" ) or die "open '$lockbase.queue' failed: $!";
if ( flock( $fhqueue, LOCK_EX | LOCK_NB ) ) {
    # got queue lock, now block waiting for "run" lock
    flock( $fhrun, LOCK_EX );
    # got run lock, so take yourself out of "queue" state, then run
    flock( $fhqueue, LOCK_UN );

    system(@cmd_plus_args);

    flock( $fhrun, LOCK_UN );
    exit 0;
}

# "queue" lock also failed; someone is running AND someone is queued; we can go home
say STDERR "INFO: nothing to do/queue; '$lockbase' already running and 1 in queue";
exit 0;