71 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # typed: true
 | |
| # frozen_string_literal: true
 | |
| 
 | |
| require "fcntl"
 | |
| 
 | |
| # A lock file.
 | |
| #
 | |
| # @api private
 | |
| class LockFile
 | |
|   attr_reader :path
 | |
| 
 | |
|   def initialize(name)
 | |
|     @name = name.to_s
 | |
|     @path = HOMEBREW_LOCKS/"#{@name}.lock"
 | |
|     @lockfile = nil
 | |
|   end
 | |
| 
 | |
|   def lock
 | |
|     @path.parent.mkpath
 | |
|     create_lockfile
 | |
|     return if @lockfile.flock(File::LOCK_EX | File::LOCK_NB)
 | |
| 
 | |
|     raise OperationInProgressError, @name
 | |
|   end
 | |
| 
 | |
|   def unlock
 | |
|     return if @lockfile.nil? || @lockfile.closed?
 | |
| 
 | |
|     @lockfile.flock(File::LOCK_UN)
 | |
|     @lockfile.close
 | |
|   end
 | |
| 
 | |
|   def with_lock
 | |
|     lock
 | |
|     yield
 | |
|   ensure
 | |
|     unlock
 | |
|   end
 | |
| 
 | |
|   private
 | |
| 
 | |
|   def create_lockfile
 | |
|     return if @lockfile.present? && !@lockfile.closed?
 | |
| 
 | |
|     begin
 | |
|       @lockfile = @path.open(File::RDWR | File::CREAT)
 | |
|     rescue Errno::EMFILE
 | |
|       odie "The maximum number of open files on this system has been reached. Use `ulimit -n` to increase this limit."
 | |
|     end
 | |
|     @lockfile.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
 | |
|   end
 | |
| end
 | |
| 
 | |
| # A lock file for a formula.
 | |
| #
 | |
| # @api private
 | |
| class FormulaLock < LockFile
 | |
|   def initialize(name)
 | |
|     super("#{name}.formula")
 | |
|   end
 | |
| end
 | |
| 
 | |
| # A lock file for a cask.
 | |
| #
 | |
| # @api private
 | |
| class CaskLock < LockFile
 | |
|   def initialize(name)
 | |
|     super("#{name}.cask")
 | |
|   end
 | |
| end
 | 
