> Good catch. My bad. I re-introduced the critical section around interestOps
> and made interestOps volatile. Please review [1]
>
> The reason I have done this change is to make it possible for the I/O
> session to defer mutation of SelectionKey's interestOps to the I/O dispatch
> in order to avoid the dead-lock condition described in HTTPCORE-155 [2] when
> running on buggy JREs such as IBM's

I'm not positive the changes (or those in r724457) will do anything to
resolve the issue on the IBM JREs.  The issue is caused by very poor
javadoc recommendations on SelectionKey -- as Marc pointed out, "...
In a naive implementation, reading or writing the interest set may
block indefinitely if a selection operation is already in progress".
In a nutshell, this means that if the selector is blocked on a
select(), it is impossible to tell it ask a SelectionKey to change its
interest.  This makes no sense in a high-performing NIO application,
as interest changes can happen from any thread and selector.wakeup()
tells the selecting-thread to take a new look at the interest.

I think the code as it is now (with r724457) will actually hinder
speed in the already-working case and be ineffective in the
not-working case.  (That said, they won't break the already-working
case.)  This is because there's no an additional mutex required for
changing interestOps -- the local one and the one implicitly gotten
when calling setInterestOps on a SelectionKey.

There's a few approaches that can help the IBM JRE case.  One, which
might not work all the time, but should work fairly reliably, would be
to call selector.wakeup() prior to grabbing the SelectionKey's mutex.
You'll still need to call selector.wakeup() after setting the ops,
though, because of the problem with the approach.  The selector may
wakeup & reselect before the ops are actually set.  In Sun's case,
this would just be a temporary problem -- the additional wakeup()
afterwards will fix things.  In IBM's case, it would lead right back
to the deadlock.

The other approach would be to somehow pass the requested ops into the
selecting thread & have the thread calling select() set the interest
ops.  This can be done by storing the ops locally, telling the
selector to wakeup, and having the selecting thread iterate through
all of it's channels prior to the next select and resetting the
interestOps before selecting.  That should fix the problem on all
JREs, but may be architecturally difficult.

(Sorry for the delay in responding... been working furiously to
release an alpha version of LimeWire 5, now finally released.)

Sam

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to