> > I'm experiencing strange behavior in a Ruby app doing
> > multithreaded I/O, and I seem to have narrowed it down
> > to my using a timeout { } block around a condition
> > variable wait. E.g.
> >
> > timeout(1.0) { @condition_variable.wait(@mutex) }
>
>
> I have gotten the code down to a couple hundred lines,
> and am able to reproduce the problem easily on:
>
> ruby 1.8.0 (2003-08-04) [i386-mswin32]
> ruby 1.8.2 (2004-07-29) [i386-mswin32]
> ruby 1.8.0 (2003-10-24) [i686-linux]
>
> My apologies in advance if I turn out to be doing something
> stupid in my own code.
> http://bwk.homeip.net/ftp/buffered-io-test3.rb
I have a bit more info. The timeout on ConditionVariable#wait
was causing the current thread to be left in the @waiters
queue in ConditionVariable. I have added a line to ensure
Thread.current is removed from @waiters:
class ConditionVariable
def wait(mutex)
begin
mutex.exclusive_unlock do
@waiters.push(Thread.current)
Thread.stop
end
ensure
mutex.lock
@waiters.delete Thread.current # ADDED THIS LINE
end
end
end
Adding this line SEEMS to fix the primary problem I've
been seeing, but I can't explain why. Because although
my condition variable surrounded by the timeout was
indeed filling up with hundreds of references to
Thread.current in @waiters, the problem I'm seeing
is that a totally different thread with a different
condition variable, simply starts not waking up when
signalled. At least, it doesn't wake up promptly,
consistently. I've tried giving it a high priority,
I know the other threads are mostly sleeping anyway,
whatever, ... I'm still trying to make the program
that reproduces the problem smaller... There's probably
a stupid near-deadlock situation that's my own fault
and I'm just not seeing it.
In any case, I think something like the line I've
added above to ConditionVariable#wait needs to be
there. . . .
Regards,
Bill