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.

On 08/17/2014 02:18 AM, Emmanuel Lecharny wrote:
 From the top of my head (I'm in a bus atm), each session has its own chain
of filter, thus its own instance. The variable is not shared, and the
session is always handled by the same IoPricessor, so the same thread. That
should be thread safe unless you start doing weird things with an executor.
Le 16 août 2014 18:06, "Kai ZHANG" <[email protected]> a écrit :

Hi,

I am a beginer of Mina. I read the api doc located at:

/http://mina.apache.org/mina-project/apidocs/org/apache/
mina/core/session/IoSession.html/

It says that IoSession is thread-safe.

But when I read the source of mina trunk branch. I found the
IoSession.write() method may be not thread-safe. The java source file is :

/./core/src/main/java/org/apache/mina/session/AbstractIoSession.java/

Here is the method calling chain:
AbstractIoSession.write()
-> AbstractIoSession.doWriteWithFuture
-> AbstractIoSession.processMessageWriting()
-> AbstractIoFilter.messageWriting()
-> AbstractIoSession.callWriteNextFilter()

The code which is thread-safe reside in AbstractIoSession.callWriteNextFilter(),
here is the code:

        /**
          * process session message received event using the filter
    chain. To be called by the session {@link SelectorLoop} .
          *
          * @param message the received message
          */
         @Override
         public void callWriteNextFilter(WriteRequest message) {
             if (IS_DEBUG) {
                 LOG.debug("calling next filter for writing for message
    '{}' position : {}", message, writeChainPosition);
             }

    /writeChainPosition--;/

             if (writeChainPosition < 0 || chain.length == 0) {
                 // end of chain processing
                 enqueueWriteRequest(message);
             } else {
                 chain[writeChainPosition].messageWriting(this, message,
    this);
             }

    /writeChainPosition++;/
         }

Here the variable "writeChainPosition" is not thread-safe, If more than
one thread call IoSession.write() concurrently, the "writeChainPosition"
may have race condition.

The result is some of the IoFilter may be skipped or called twice, and the
message data passed down the filter chain may be broken.

Could you tell me if my understanding is correct?

Is IoSession.write() method designed to be thread-safe or should I use a
lock for every concurrent IoSession.write() operation?






Reply via email to