class File

attr_accessor :format

# Get an exclusive (i.e., write) lock on the file.
# If the lock is not available, wait for it without blocking other ruby
# threads.
def lock_exclusive
  if Thread.list.size == 1
    begin
      flock(LOCK_EX) ## need to use fcntl for Linux NFS
    rescue Errno::EINTR
      retry
    end
  else
    # ugly hack because waiting for a lock in a Ruby thread blocks the process
    period = 0.001
    until flock(LOCK_EX|LOCK_NB) ## need to use fcntl for Linux NFS
      sleep period
      period *= 2 if period < 1
    end
  end
end

# Get a shared (i.e., read) lock on the file.
# If the lock is not available, wait for it without blocking other ruby
# threads.
def lock_shared
  if Thread.list.size == 1
    begin
      flock(LOCK_SH) ## need to use fcntl for Linux NFS
    rescue Errno::EINTR
      retry
    end
  else
    # ugly hack because waiting for a lock in a Ruby thread blocks the process
    period = 0.001
    until flock(LOCK_SH|LOCK_NB) ## need to use fcntl for Linux NFS
      sleep period
      period *= 2 if period < 1
    end
  end
end

end