> 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]
