# = syncarray.rb # # == Copyright (c) 2004 George Moschovitis # # Ruby License # # This module is free software. You may use, modify, and/or redistribute this # software under the same terms as Ruby. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. # # == Author(s) # # * George Moschovitis # Author:: George Moschovitis # Copyright:: Copyright (c) 2005 George Moschovitis # License:: Ruby License require 'sync' # = SyncArray # # A thread-safe array. We use a sync object instead of a # mutex, because it is re-entrant. An exclusive lock is # needed when writing, a shared lock IS NEEDED when reading. class Array def self.mutable_methods @mutable ||= %w{ << []= abbrev clear collect! compact! concat delete delete_at delete_if fill flatten insert map! pop push reject! replace reverse! shift slice! sort! transpose uniq! unshift } end end class SyncArray < Array attr :sync # # gmosx: delegator is not yet used. # def initialize(delegator = nil) @sync = ::Sync.new() super() end instance_methods.each do |m| next if Object.instance_methods.include?(m) if mutable_methods.include?(m) sync_type = "Sync::EX" else sync_type = "Sync::SH" end class_eval %{ def #{m}(*args) return @sync.synchronize(#{sync_type}) { super } end } end # def << (value) # return @sync.synchronize(Sync::SH) { super } # end # # def delete_if(&block) # return @sync.synchronize(Sync::SH) { super } # end # # def [](key) # return @sync.synchronize(Sync::SH) { super } # end # # def []=(key, value) # return @sync.synchronize(Sync::EX) { super } # end # # def delete(key) # return @sync.synchronize(Sync::EX) { super } # end # # def clear # @sync.synchronize(Sync::EX) { super } # end # # def size # return @sync.synchronize(Sync::SH) { super } # end # # def shift # return @sync.synchronize(::Sync::EX) { super } # end # # def unshift(el) # return @sync.synchronize(::Sync::EX) { super } # end end #-- # Funniest thing, remove the :: in front of Sync.new in the initialize # routine and uncomment the alias line below and watch the stack blow chunks. # I'm leaving this comment here as a reminder. ### Array::Sync = SyncArray #++ # _____ _ # |_ _|__ ___| |_ # | |/ _ \/ __| __| # | | __/\__ \ |_ # |_|\___||___/\__| # =begin testing require 'test/unit' # TODO class TC_SyncArray < Test::Unit::TestCase def test_01 assert_nothing_raised{ @s = SyncArray.new } end end =end