require 'socket' require 'thread' module Mongoid module Lock def local_mutex @__mutex ||= Mutex.new end def reset_lock! self.set(:lock_used_by, nil) end def lock_acquire local = "#{Socket.gethostname}:#{Process.pid}" ident = self.lock_used_by if (ident and ident != local) raise Mongoid::Lock::UnsynchronizedAccess.new(ident) else self.set(:lock_used_by, local) end end def lock_release local = "#{Socket.gethostname}:#{Process.pid}" ident = self.lock_used_by if (ident and ident == local) self.reset_lock! else raise Mongoid::Lock::UnsynchronizedAccess.new(ident) end end def synchronized(&block) self.local_mutex.synchronize { self.lock_acquire begin block.call() ensure self.lock_release end } end def try_synchronized(&try_block) begin self.synchronized do try_block.call() end return true rescue Mongoid::Lock::UnsynchronizedAccess => ua return false end end def wait_synchronized(timeout, &block) started = Time.now expires = started + timeout begin success = self.try_synchronized do block.call() end unless (success) sleep(2) end end while(not success and Time.now < expires) return success end end end