|
From: Michael N. <uu...@rz...> - 2002-05-14 17:47:46
|
On Mon, May 13, 2002 at 11:35:54AM -0700, Brad Hilton wrote:
> On Sun, 2002-05-12 at 21:20, Sean Chittenden wrote:
> > > Right now the could looks like:
> > >
> > > @res_handle.free if @res_handle
> > >
> > > Perhaps that needs to be changed to:
> > >
> > > @res_handle.free if (@res_handle and @res_handle.is_a? MysqlRes)
> > >
> > > I don't know...
> >
> > I'm a PostgreSQL guy myself. Could you test the above change and see
> > if it works for you? You seem to have done the diagnosis correctly
> > and I think it should work. -sc
>
> Actually, I think a better solution than my previous one is to set
> query_with_result = true in Mysql.rb line 313 in execute(). It is
> obvious that the code expects query_with_result to be set to true in
> that instance, and there are many places in the code that assume
> @res_handle is a MysqlRes object, so I believe this would be the best
> solution.
>
> Attached is a sample script which exposes the problem, as well as a
> patch to fix the bug.
This will not completely fix the bug, I fear.
When executing statements concurrently, it could happen that method #do
sets query_with_result=false, then #execute interrupts and sets
query_with_result=true ....
The solution is to use a Mutex, which prevents parallel execution of
methods #do and #execute.
The following patch fixes it (checked into -current):
----- patch ------
5c5
< # Version : 0.3.1
---
> # Version : 0.3.2
24a25
> require "thread" # for Mutex
30c31
< VERSION = "0.3.1"
---
> VERSION = "0.3.2"
148a150,154
> def initialize(handle, attr)
> super
> @mutex = Mutex.new
> end
>
208d213
<
210d214
< @handle.query_with_result = false
212,213c216,220
< @handle.query(sql)
< @handle.affected_rows
---
> @mutex.synchronize {
> @handle.query_with_result = false
> @handle.query(sql)
> @handle.affected_rows # return value
> }
220c227
< Statement.new(self, @handle, statement)
---
> Statement.new(self, @handle, statement, @mutex)
297c304
< def initialize(parent, handle, statement)
---
> def initialize(parent, handle, statement, mutex)
300c307
< @parent, @handle = parent, handle
---
> @parent, @handle, @mutex = parent, handle, mutex
303d309
< @handle.query_with_result = true # automatically switches store_result on
313,315c319,325
< @res_handle = @handle.query(@prep_stmt.bind(@params))
< @current_row = 0
< @rows = @handle.affected_rows
---
> sql = @prep_stmt.bind(@params)
> @mutex.synchronize {
> @handle.query_with_result = true
> @res_handle = @handle.query(sql)
> @current_row = 0
> @rows = @handle.affected_rows
> }
--
Michael Neumann *** eMail uu...@rz...
|