So I'm using flock, but I have this noxious race condition when I try to
clean up the lock files.

I need a way of knowing if anything has a file open at the same time as
me, or I must always leave lock files lying around. Any suggestions?


Here is the sequence..
Process A: fd = open( "lockfile", 'a')
Process A: flock(fd, LOCK_EX)

Process A: do stuff in critical section...

Process B : fd = open( "lockfile", 'a')
Process B: flock(fd, LOCK_EX) // Blocks waiting for lock

Process A: Finishes, doesn't know about B, wants to clean up...
Process A: unlink fd
Process A: close(fd)

Process B: Unblocks, B grabs lock.

Process C : fd = open( "lockfile", 'a') // CREATES A NEW ONE!
Process C: flock(fd, LOCK_EX) // DOESN'T BLOCK!


Here is a chunk of ruby that demonstrates this...


fork do
   fd = open( "lockfile", 'a')
   puts fd.stat.ino
   fd.flock(File::LOCK_EX)
   puts "Sleeping"
   sleep 10
   File.unlink "lockfile"
   fd.close
end

sleep 1
fork do
   fd = open( "lockfile", 'a')
   puts fd.stat.ino
   puts "Waiting for lock"
   fd.flock(File::LOCK_EX) # Blocks waiting for lock
   puts "Got lock"
   sleep 100
end

sleep 15

puts "Open file #{Time.now}"
fd = open( "lockfile", 'a') # CREATES A NEW ONE!
puts fd.stat.ino
fd.flock(File::LOCK_EX) # DOESN'T BLOCK!

puts "Did it block #{Time.now}"

====================================

Here is the result...
ruby -w try.rb
6157824
Sleeping
6157824
Waiting for lock
Got lock
Open file Mon Aug 14 14:10:55 +1200 2006
6158309     <-------- Note new INODE NUMBER, 
Did it block Mon Aug 14 14:10:55 +1200 2006  <---- No it didn't!
__________________



John Carter                             Phone : (64)(3) 358 6639
Tait Electronics                        Fax   : (64)(3) 359 4632
PO Box 1645 Christchurch                Email : john.carter / tait.co.nz
New Zealand

Carter's Clarification of Murphy's Law.

"Things only ever go right so that they may go more spectacularly wrong later."

From this principle, all of life and physics may be deduced.