OK. I think the new approach is better.
I just didn't know how to use the IoSession.write() method correctly.
It is clear now.
Thank you very much for the helpful answer.
Sincerely
Kai Zhang
On 08/17/2014 07:17 AM, Emmanuel Lécharny wrote:
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() ?