module DEBUGGER__::MultiProcessGroup

def after_fork child: true

def after_fork child: true
  if child || !@lock_file
    @m = Mutex.new unless @m
    @m.synchronize do
      @lock_level = 0
      @lock_file = open(@lock_tempfile.path, 'w')
    end
  end
end

def info msg

def info msg
  DEBUGGER__.info "#{msg} (#{@lock_level})" #  #{caller.first(1).map{|bt| bt.sub(__dir__, '')}}"
end

def lock

def lock
  unless trylock
    @m.synchronize do
      if locked?
        lock_level_up
      else
        info "Lock: block"
        @lock_file.flock(File::LOCK_EX)
        lock_level_up
      end
    end
    info "Lock: success"
  end
end

def lock_level_down

def lock_level_down
unless @m.owned?
"@lock_level underflow: #{@lock_level}" if @lock_level < 1
level -= 1

def lock_level_up

def lock_level_up
unless @m.owned?
level += 1

def locked?

def locked?
  # DEBUGGER__.debug{ "locked? #{@lock_level}" }
  @lock_level > 0
end

def multi_process!

def multi_process!
end

def sync &b

def sync &b
  info "sync"
  lock
  begin
    b.call if b
  ensure
    unlock
  end
end

def trylock

def trylock
chronize do
ocked?
ck_level_up
fo "Try lock, already locked"
ue

se r = @lock_file.flock(File::LOCK_EX | File::LOCK_NB)
en 0
lock_level_up
info "Try lock with file: success"
true
en false
info "Try lock with file: failed"
false
se
raise "unknown flock result: #{r.inspect}"
d

def unlock

def unlock
  @m.synchronize do
    raise "lock file is not opened (#{@lock_file.inspect})" if @lock_file.closed?
    lock_level_down
    @lock_file.flock(File::LOCK_UN) unless locked?
    info "Unlocked"
  end
end