[
https://issues.apache.org/jira/browse/HTTPCORE-659?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Oleg Kalnichevski resolved HTTPCORE-659.
----------------------------------------
Fix Version/s: 5.1-beta3
5.0.4
Resolution: Fixed
[~ncapponi] PR merged to 5.0.x and master.
Oleg
> Race condition in IOSessionImpl when setting event
> --------------------------------------------------
>
> Key: HTTPCORE-659
> URL: https://issues.apache.org/jira/browse/HTTPCORE-659
> Project: HttpComponents HttpCore
> Issue Type: Bug
> Components: HttpCore NIO
> Affects Versions: 5.0.3
> Reporter: Nicolas Capponi
> Priority: Major
> Fix For: 5.0.4, 5.1-beta3
>
> Time Spent: 1h 10m
> Remaining Estimate: 0h
>
> There is a race condition in class
> {{org.apache.hc.core5.reactor.IOSessionImpl}} when setting an event through
> the {{setEvent(final int op)}} method: there is a check on the session to
> ensure it is not closed but this check is performed outside the lock that is
> later acquired to protect the call on the {{SelectionKey}}. If the session is
> closed just after the check but before getting the lock, then it will throw a
> {{CancelledKeyException}} when trying to perform the call on the
> {{SelectionKey}}.
> I have implemented an HTTP server that use the reactive library
> ({{httpcore5-reactive}} component) and execute the requests in a separate
> thread pool. I was hit by this issue, here is a stack trace (with traces non
> specific to HttpCore library removed):
> {code:java}
> CancelledKeyException at SelectionKeyImpl.java:71
> SelectionKeyImpl.java:90
> IOSessionImpl.java:159
> InternalDataChannel.java:324
> AbstractHttp1StreamDuplexer.java: 452
> ServerHttp1StreamDuplexer.java:136
> ServerHttp1StreamHandler.java:94
> ReactiveDataProducer.java:108
> ReactiveDataProducer.java:100
> ... traces from publisher implementation using Rx java library...
> ReactiveServerExchangeHandler.java:91
> ReactiveServerExchangeHandler.java:83
> ...{code}
>
> I was able to reproduce it almost systematically with unit test from my
> application (concurrency issues are very sensitive to time). If necessary I
> can provide a sample {{HttpAsyncServer}} which allows me to reproduce it by
> introducing a simple {{Thread.sleep(50)}} sequence in {{IOSessionImpl}} code.
> There is a simple fix: move the check on close status inside the lock-unlock
> block
> {code:java}
> lock.lock();
> try {
> if (isStatusClosed()) {
> return;
> }
> this.key.interestOps(this.key.interestOps() | op);
> } finally {
> lock.unlock();
> }
> {code}
> Note that 2 other methods of this class are subject to this problem:
> {{setEventMask(final int newValue)}} and {{clearEvent(final int op)}}. The
> fix is the same than for the first method.
> I can submit a pull request with the fix(es) if you indicate me in which
> branch I should submit it.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]