On 18/06/2014 13:06, Konstantin Kolinko wrote: > 2014-06-17 17:08 GMT+04:00 Mark Thomas <ma...@apache.org>: >> On 17/06/2014 00:50, Konstantin Kolinko wrote: >>> 2014-06-14 0:21 GMT+04:00 <ma...@apache.org>: >>>> Author: markt >>>> Date: Fri Jun 13 20:21:32 2014 >>>> New Revision: 1602510 >> >> <snip/> >> >>> 3) In case if there are several executor threads that process the >>> socket at the same time, what happens? >>> >>> My understanding/answer is that "synchronized (socket)" in >>> NioEndpoint$SocketProcessor.run() handles that. >> >> Correct. You don't want multiple threads trying to read from the socket >> at the same time. Neither do you want multiple threads trying to writ to >> the socket at the same time. One thread reading and one thread writing >> is OK. >> >>> In this case I see that NioEndpoint$SocketProcessor.doRun() does >>> "nioChannels.offer(socket)" >>> That is it offers the "socket" for reuse. >>> >>> Thus "synchronized (socket)" is broken, as the "socket" can be >>> recycled and reused by another thread while the second one waits to >>> obtain the monitor on the "socket". >> >> In theory yes. In practise, I don't believe that this will happen. >> >> The syncs were added as part of the Servlet 3.0 async processing >> implementation. The case they were trying to deal with was: >> a) app on container thread starts async processing >> b) app passes control to app thread >> c) container thread is returned to container for reuse >> (update state, does a little clean up before it is reused) >> d) app thread completes the async processing >> e) control returns to container thread to complete the request >> >> There was a chance that e) could complete before c) and that caused all >> sorts of confusion. The syncs ensure c) completes before e) starts. >> >> For the problem you describe to occur a fatal I/O error would have to >> occur during c) after e) had reached the sync. Since there should be no >> I/O during c) I don't think this can happen. >> >> If you have a scenario where you think this is an issue, please share it. > > I suspect that the following scenario might happen: > a),b),c) the same as above > > d) App thread performs I/O and an error happens > (e.g. in 'COMMIT' or 'ACK' case in AbstractHttp11Processor.action()) > e) AbstractProcessor.setErrorState() dispatches SocketStatus.CLOSE_NOW > > f) App thread calls async.complete() or async.dispatch() > g) AbstractHttp11Processor.action() dispatches SocketStatus.OPEN_READ > > How the race between e) and g) is resolved?
I don't think it is at the moment. I'm not sure if the spec covers what should happen in this case. For example, should the app continue and call complete() or dispatch()? Should the onError() method of any Async listener be called? One thing I am fairly sure of, the more we can refactor the connectors to reduce duplication, the easier handling this sort of thing will become. That refactoring is moving up my TODO list for Tomcat 9 the more I think about it. Mark --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org