From: Weston Sewell Date: 2009-05-15T16:37:56+09:00 Subject: [ruby-core:23456] REXML Thread Safety --0016369891d511b00f0469ee859b Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit I've been using Ruby for several years but I just joined the list because I ran into a problem that I'm not sure how to solve (sorry for not lurking for the requisite eon, I've been working night and day on a Ruby project for work). It appears that REXML may not be completely thread-safe. Is it intended to be? I've run into a problem that I was able to reproduce in a test that I'll post at the bottom. Basically, it appears that accessing either #to_s or #value on REXML::Attribute causes a change in the state of the instance (setting @normalized and @unnormalized to a computed value or 'nil'). And since these are not intended to be "destructive" calls, neither are some of the Element methods that call them (i.e. Element#inspect). When using threads of course we are not protecting non-destructive calls with semaphors (and actually we are using XMPP4r so we don't have complete conrol over what gets called and how). Is there anyone who is familiar with this situation? TIA Weston Test Code - exception occurs in either #to_s or #value (on my system this always happens within 900 iterations) ------------------------------------------------------------------------------ common_doc = REXML::Document.new( '' ) def parse(doc) foo = doc.root foo.inspect foo.attributes['bar'] end def multiparse(doc) 1000000.times do |iteration| puts "Iteration #{iteration}" if(iteration == 0 || (iteration % 100 == 0)) parse(doc) end end threads = [] threads << Thread.new { multiparse(common_doc) } threads << Thread.new { multiparse(common_doc) } threads << Thread.new { multiparse(common_doc) } threads << Thread.new { multiparse(common_doc) } threads << Thread.new { multiparse(common_doc) } threads << Thread.new { multiparse(common_doc) } threads.each do |thread| thread.join end --0016369891d511b00f0469ee859b Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable I've been using Ruby for several years but I just joined the list becau= se I ran into a problem that I'm not sure how to solve (sorry for not l= urking for the requisite eon, I've been working night and day on a Ruby= project for work).

It appears that REXML may not be completely thread-safe. Is it intended= to be? I've run into a problem that I was able to reproduce in a test = that I'll post at the bottom. Basically, it appears that accessing eith= er #to_s or #value on REXML::Attribute causes a change in the state of the = instance (setting @normalized and @unnormalized to a computed value or '= ;nil'). And since these are not intended to be "destructive" = calls, neither are some of the Element methods that call them (i.e. Element= #inspect). When using threads of course we are not protecting non-destructi= ve calls with semaphors (and actually we are using XMPP4r so we don't h= ave complete conrol over what gets called and how).

Is there anyone who is familiar with this situation?

TIA
West= on

Test Code=A0 - exception occurs in either #to_s or #value (on my = system this always happens within 900 iterations)
----------------------= --------------------------------------------------------
common_doc =3D REXML::Document.new( '<foo bar=3D"somevalue"= ; />' )

def parse(doc)
=A0=A0=A0 foo =3D doc.root
=A0= =A0=A0 foo.inspect
=A0=A0=A0 foo.attributes['bar']
end
def multiparse(doc)
=A0=A0=A0 1000000.times do |iteration|
=A0=A0=A0=A0=A0=A0=A0 puts "= Iteration #{iteration}" if(iteration =3D=3D 0 || (iteration % 100 =3D= =3D 0))
=A0=A0=A0=A0=A0=A0=A0 parse(doc)
=A0=A0=A0 end
end

= threads =3D []
threads << Thread.new { multiparse(common_doc) } threads << Thread.new { multiparse(common_doc) }
threads << = Thread.new { multiparse(common_doc) }
threads << Thread.new { mult= iparse(common_doc) }
threads << Thread.new { multiparse(common_doc= ) }
threads << Thread.new { multiparse(common_doc) }

threads.each = do |thread|
=A0=A0=A0 thread.join
end

--0016369891d511b00f0469ee859b--