# ObjectPool -- Sharing of instantiated objects. # # Copyright (C) 2001 Masao Mutoh # This program is licenced under the same licence as Ruby. # # $Id: objectpool.rb,v 1.1.1.1 2001/12/30 13:12:19 mutoh Exp $ # require 'singleton' require 'timeout' require 'thread' class ObjectPool include Singleton alias _timeout timeout def initialize @used_list = {} @free_list = [] @max = 10 @timeout = nil @wait = 1 @out = nil @mutex = Mutex.new end def get _timeout(@timeout) do loop { @mutex.synchronize { Thread.exclusive { # to prohibit TimeoutError if !@free_list.empty? result = @free_list.pop elsif @used_list.size < @max result = create end if result @used_list.store(result.__id__, result) return result end } } @out.printf("%s, wait %d sec\n", Time.now, @wait) unless @out.nil? sleep(@wait) } end rescue TimeoutError raise TimeoutError.new("There are no more available Objects. max = %d" % @max) end # Release an object. # This method does not mean that the object is actually released. # If you do, you can use the obect after release, but you should avoid # as much as possible. def release(obj) @mutex.synchronize { @used_list.delete(obj.__id__) @free_list.push(obj) } nil end def max=(size) @mutex.synchronize { if @free_list.size + @used_list.size > size raise ArgumentError.new("Cannot change max size to %d. There are objects over the size." % size) end @max = size } size end def create raise "Implement this method." end attr_reader :max attr_accessor :timeout attr_accessor :wait attr_accessor :out end if __FILE__ == $0 class Test end class TestPool < ObjectPool def initialize super self.max = 3 self.timeout = 10 end def create Test.new end end objectpool = TestPool.instance objectpool.out = $stderr p a = objectpool.get p b = objectpool.get # a, b, c are not same object. p c = objectpool.get # a, b, c are not same object. objectpool.release(a) # release a. p "released = %s" % a p d = objectpool.get # d and a is same object. Thread.new do sleep 5 objectpool.release(b) # after 5 sec, release b. end p e = objectpool.get # wait 5 sec until b is released. # e and b is same object. end