Le 16/08/14 21:04, Kai ZHANG a écrit : > Thanks for your reply, Emmanuel. > > My application is an instant message server(like openfire, an open > source XMPP server). > > When a IM client connected, an IoSession is created for this > connection. Each time a message is received from a client, it will be > handled by a client thread from the client thread pool. Then in this > thread the message will be routed to the target user connection by > calling IoSession.write(). > > There may be situations more than one users are sending message to the > same target user at the same time, then there maybe more than one > threads trying to call IoSession.write() on the target IoSession object. > > So if two threads call IoSession.write() at the same time, the > internal variable "writeChainPosition" of IoSession may be changed by > two threads at the same time. This may lead the write operation locate > a wrong io filter in the chain. > > I check the source codes of mina 1.1.7, which is used in openfire > project. The IoSession.write() operation is same to be called in two > threads simutaneously. It did not store the next filter position in a > IoSession variable, but use a nextFilter pointer in the Entry. > > In mina 1.1.7, find the next filter to run, is iterate over a linked > list. But in the current version of mina trunk, it use an offset > variable of an array. This offset variable is the source of race > condition if two threads call IoSession.write() at the same time. > > Please let me know if I am correct. You are basically correct.
We changed the way we were processing next filter selection in the chain for many reasons, one of them was the pain of debugging the app in the previous version (the stack was twice deeper before). Obviously, if you are sharing the session on the client or server, then that is a problem. OTOH, you have a pool of threads on the client side, all of theme sharing the same session. That was working well at the price of extra complexity in the filter chain, it's clearly problematic in the new approach. Could you use a queue on the client side to avoid having concurrent access to IoSession.write() ?
