Thanks for the reply Hugo. I went with something like what you suggest. Added a test before we try to aquire the LOCK_EX to make sure the lockfile doesnt exist or is at least 3 seconds old, and double checking that the process data stays the same after the LOCK_UN and LOCK_SH. The append logic I didnt quite follow so I didnt go that way. Here is what I have:

sub get_lock { my ($lock_dir,$name)=@_; my $debug=1; $name=~s/[^-\w.#!\@~=+%\$]//g; my $lockfile=catfile($lock_dir,$name.'.lock'); print "Trying lockfile $lockfile\n"; if (-e $lockfile and (time()- -M $lockfile)<3) { print "\tLockfile exists and is very recent skipping for now\n +"; return; } sysopen(my $FH, $lockfile, O_RDWR | O_CREAT) or do { warn "can't open $lockfile: $!" if $debug; return; }; # autoflush $FH select( (select($FH), $|++)[0] ); my ( $time, $process, $lname ); if (flock( $FH, LOCK_EX | LOCK_NB )) { ( $time, $process, $lname )=split /\|/,join "",<$FH>; seek $FH, 0, 0 or die "Failed rewind:$!"; if ($debug) { if ($process) { print "\tLockfile appears to be abandonded by Process +#$process started at $time\n" } else { print "\tLockfile appears to be unprocessed\n" } } my $lock_msg=join("|", iso_time(), $$, $name)."\n"; print $FH $lock_msg; truncate($FH, tell($FH)) or die "Failed to truncate:$!"; flock($FH, LOCK_UN) or die "sharedlock: $!"; flock($FH, LOCK_SH|LOCK_NB) or do { print "\tFailed to relock!\n" if $debug; return; }; seek $FH, 0, 0 or die "Failed rewind2:$!"; my $msg=<$FH>; unless ($msg eq $lock_msg) { print "\tWhoops, (harmless) race condition on $lockfile!\n +"; return } print "File Locked! : $lock_msg"; return OnDestroy { print "*** Finished with and removing $loc +kfile ***\n"; close $FH or die "Failed to close \$FH:$!" +; unlink $lockfile or die "Failed to unlink +$lockfile\n"; undef $FH; }; } elsif (flock($FH, LOCK_SH)) { ( $time, $process, $lname )=split /\|/,join "",<$FH>; print "\tLockfile appears to be locked by Process #$process at + $time\n" if $debug; } else { print "\tFailed to get lock! Not sure why.\n"; } return }

Yes its a bit wordy, id be interested to see a less clunky implementation if anyone feels inclined.

Incidentally there is no need to wait to get the exclusive lock. Under normal situations this will be polling a table in a DB every 60 seconds or so, and then processing any records it finds there. So if the lock file is too young returning to try the next record is better.

Cheers


---
demerphq

    First they ignore you, then they laugh at you, then they fight you, then you win.
    -- Gandhi



In reply to Re: Re: Frustration with changing lock type by demerphq
in thread Frustration with changing lock type by demerphq

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.