mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Ilya Ivanov (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (DIRMINA-845) ProtocolEncoderOutputImpl isn't thread-safe
Date Fri, 29 Jul 2011 15:46:10 GMT

    [ https://issues.apache.org/jira/browse/DIRMINA-845?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13072871#comment-13072871
] 

Ilya Ivanov commented on DIRMINA-845:
-------------------------------------

Let suppose we have 3 session (3 rtmp connections) 1, 2 and 3. Session 1 receives video frame
and re-sends it to session 3, session 2 receives another video frame and re-send it to session
3 too. All sessions have different io-processor threads.

So, two incoming messages processed by different threads will pass through session 3 filter
chain concurrently and leads to above issue on flushing buffer queue in ProtocolCodecFilter.filterWrite.

I'm not sure this is right using of MINA or not but such implementation I saw in red5...

http://code.google.com/p/red5/source/browse/java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPMinaProtocolEncoder.java
 lines 50 and 70

I tried to eliminate entire connection lock and replace it on per-channel lock (RTMP itself
allows this).

> ProtocolEncoderOutputImpl isn't thread-safe
> -------------------------------------------
>
>                 Key: DIRMINA-845
>                 URL: https://issues.apache.org/jira/browse/DIRMINA-845
>             Project: MINA
>          Issue Type: Bug
>          Components: Filter
>    Affects Versions: 2.0.4
>            Reporter: Ilya Ivanov
>
> ProtocolEncoderOutputImpl uses ConcurrentLinkedQueue and at first look it seems to be
thread-safe. But really concurrent execution of flush method isn't thread-safe (and write-mergeAll
also).
> E.g. in RTMP several channels multiplexed in single connection. According protocol specification
it's possible to write to different channels concurrently. But it doesn't work with MINA.
> I've synchronized channel writing, but it doesn't prevent concurrent run of flushing
(in 2.0.4 it's done directly in ProtocolCodecFilter.filterWrite, but ProtocolEncoderOutputImpl.flush
has the same problem).
> Here the fragment of flushing code:
> while (!bufferQueue.isEmpty()) {
>   Object encodedMessage = bufferQueue.poll();
>                 
>   if (encodedMessage == null) {
>     break;
>   }
>   // Flush only when the buffer has remaining.
>   if (!(encodedMessage instanceof IoBuffer) || ((IoBuffer) encodedMessage).hasRemaining())
{
>     SocketAddress destination = writeRequest.getDestination();
>     WriteRequest encodedWriteRequest = new EncodedWriteRequest(encodedMessage, null,
destination); 
>     nextFilter.filterWrite(session, encodedWriteRequest);
>   }
> } 
> Suppose original packets sequence is A, B, ...
> Concurrent run of flushing may proceed as following:
> thread-1: Object encodedMessage = bufferQueue.poll(); // gets A packet
> thread-2: Object encodedMessage = bufferQueue.poll(); // gets B packet
> ...
> thread-2: nextFilter.filterWrite(...); // writes B packet
> thread-1: nextFilter.filterWrite(...); // writes A packet
> so, resulting sequence will B, A
> It's quite confusing result especially when documentation doesn't contain any explanation
about such behavior.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Mime
View raw message