Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require 'debug_helper'
- class Lock
- include DebugHelper
- attr_reader :type, :range, :owner
- EXCLUSIVE = 1
- NORMAL = 2
- def initialize(owner, type = EXCLUSIVE,offset = nil, size = nil)
- @owner = owner
- @type = type
- if !offset.nil? and !size.nil? then
- @range = Range.new(offset,offset+size)
- end
- end
- def concurrent?(lock)
- if (@type == EXCLUSIVE) or (lock.type == EXCLUSIVE) then
- print_debug({:op => "concurrent?", :result => false, :type => "exclusive"})
- return false
- elsif @range.include?(lock.range.begin) or @range.include?(lock.range.end) then
- print_debug({:op => "concurrent?", :result => false, :type => "normal"})
- return false
- end
- print_debug({:op => "concurrent?", :result => true, :type => "normal"})
- true
- end
- end
- class DLM
- include DebugHelper
- attr_reader :locks, :config
- def initialize(config)
- @locks = Hash.new { Array.new }
- @config = config
- @m = Mutex.new
- end
- def lock(path,type = Lock::EXCLUSIVE, offset = nil, size = nil)
- @m.synchronize do
- # requested EXCLUSIVE
- if type == Lock::EXCLUSIVE then
- return nil if @locks.has_key?(path)
- l = Lock.new(@config.local_ip)
- @locks[path] << l
- print_debug({:op => "lock", :path => path, :result => true, :type => "exclusive"}) if @config.debug_dlm
- return l
- elsif (offset.nil? or size.nil?) then
- print_debug({:op => "lock", :error => "somebody kidding"})
- return nil
- else
- l = Lock.new(@config.local_ip,Lock::NORMAL,offset,size)
- if @locks.has_key?(path) then
- @locks[path].each { |x| return nil if !l.concurrent?(x) }
- @locks[path] << l
- print_debug({:op => "lock", :path => path, :result => true, :type => "normal/concurrent"}) if @config.debug_dlm
- return l
- else
- @locks[path] << l
- print_debug({:op => "lock", :path => path, :result => true, :type => "normal"}) if @config.debug_dlm
- return l
- end
- end
- end
- end
- def release(path, lock = nil)
- @m.synchronize do
- #exclusive lock
- if lock.nil? then
- print_debug({:op => "lock", :error => "exclusive and normal lock?!?!"}) if @locks[path].size > 1
- @locks.delete path
- else
- arr = @locks[path]
- if arr.nil? then
- print_debug({:op => "lock", :error => "trying to release a lock in a path that doesn't exists"})
- else
- l = arr.delete(lock)
- print_debug({:op => "lock", :error => "trying to release a lock that doesn't exists"}) if l.nil?
- end
- end
- end
- end
- end
Add Comment
Please, Sign In to add comment