Hi all,
I'm having some problems with a deadlock in Mina 1.0.0. We are using
Java 5 on Windows XP, so I had to apply DIRMINA-277.patch.
I have only created a snapshot (from Eclipse) of the two threads which
are involved in the deadlock (see below). It looks like both threads are
blocked at:
BaseIoSession.write:
public WriteFuture write( Object message, SocketAddress remoteAddress
)
{
synchronized( this ) // <-- deadlock here
{
if( isClosing() || !isConnected() )
{
return DefaultWriteFuture.newNotWrittenFuture( this );
}
}
WriteFuture future = new DefaultWriteFuture( this );
write0( new WriteRequest( message, future, remoteAddress ) );
return future;
}
The thread snapshots shows that both treads already owns a lock and
wants a lock on another instance.
(After a few moments of thinking) I think I know why the deadlock
occures. Mina is used by a routing instance, which have a front
connection and multiple backend connections. The class
DataStructureProtocolHandler in the trace below is an instance of
IoHandler. The trace shows that one IoHandler receives a message and
routs it to another IoHandler. So messageReceived is causing a call to a
method on another IoHandler (DatastructureProtocolHandler.consume). The
consume method is calling write on another IoSession.
The deadlock occures when the front connection receives a message and is
trying to sent it to a backend connection while that backend connection
at the same time is trying to write a response back to the front
connection.
How should I solve the problem? We have never had any problems with
prior versions of Mina and it happens very often with 1.0.0. We have now
reverted back to a prior version.
Thanks for your time :)
Kaj
-- Beginning of snapshot of the two threads
Thread [AnonymousIoService-5] (Suspended)
owns: SocketSessionImpl (id=164)
waited by: Thread [SocketAcceptorIoProcessor-0.0]
(Running)
waited by: Thread [AnonymousIoService-16] (Suspended)
waited by: Thread [Timer-1] (Running)
waiting for: SocketSessionImpl (id=183)
owned by: Thread [AnonymousIoService-16] (Suspended)
SocketSessionImpl(BaseIoSession).write(Object, SocketAddress)
line: 137
SocketSessionImpl(BaseIoSession).write(Object) line: 132
DatastructureProtocolHandler.consume(ByteMessage, boolean) line:
538
DataConnector.consume(IDataSet, boolean) line: 109
BackendHandler.consume(IDataSet, boolean) line: 65
RoutingService.routeToBackend(RoutingInformation, String,
String, String, IDataSet) line: 458
RoutingService.routeNewMessage(RoutingAlgorithm, String, String,
String, String, String, IDataSet) line: 406
RoutingService.routeMessage(RoutingAlgorithm, String,
RoutingService$Request, IDataSet) line: 344
RoutingService.onIncomingMessage(IDataSet) line: 193
FrontendHandler.consume(IDataSet, boolean) line: 62
DataConnector.consume(ByteMessage, boolean) line: 130
DatastructureProtocolHandler.messageReceived(IoSession, Object)
line: 465
AbstractIoFilterChain$2.messageReceived(IoFilter$NextFilter,
IoSession, Object) line: 189
SocketFilterChain(AbstractIoFilterChain).callNextMessageReceived(IoFilte
rChain$Entry, IoSession, Object) line: 502
AbstractIoFilterChain.access$1000(AbstractIoFilterChain,
IoFilterChain$Entry, IoSession, Object) line: 52
AbstractIoFilterChain$EntryImpl$1.messageReceived(IoSession,
Object) line: 777
ExecutorFilter.processEvent(IoFilter$NextFilter, IoSession,
ExecutorFilter$EventType, Object) line: 243
ExecutorFilter$ProcessEventsRunnable.run() line: 305
ThreadPoolExecutor$Worker.runTask(Runnable) line: 650
ThreadPoolExecutor$Worker.run() line: 675
Thread.run() line: 595
Thread [AnonymousIoService-16] (Suspended)
owns: SocketSessionImpl (id=183)
waited by: Thread [AnonymousIoService-12] (Running)
waited by: Thread [AnonymousIoService-5] (Suspended)
owns: SocketSessionImpl (id=164)
waited by: Thread
[SocketAcceptorIoProcessor-0.0] (Running)
waited by: Thread
[AnonymousIoService-16] (Suspended)
waited by: Thread [Timer-1] (Running)
waited by: Thread [SocketAcceptorIoProcessor-1.0]
(Suspended)
waited by: Thread [Timer-2] (Running)
waiting for: SocketSessionImpl (id=164)
owned by: Thread [AnonymousIoService-5] (Suspended)
SocketSessionImpl(BaseIoSession).write(Object, SocketAddress)
line: 137
SocketSessionImpl(BaseIoSession).write(Object) line: 132
DatastructureProtocolHandler.consume(ByteMessage, boolean) line:
538
DataConnector.consume(IDataSet, boolean) line: 109
FrontendHandler.consume(IDataSet, boolean) line: 64
RoutingService.handleResponseMessage(String, IDataSet) line: 563
RoutingService.onBackendMessage(IDataSet) line: 532
BackendHandler.consume(IDataSet, boolean) line: 61
DataConnector.consume(ByteMessage, boolean) line: 130
DatastructureProtocolHandler.messageReceived(IoSession, Object)
line: 465
AbstractIoFilterChain$2.messageReceived(IoFilter$NextFilter,
IoSession, Object) line: 189
SocketFilterChain(AbstractIoFilterChain).callNextMessageReceived(IoFilte
rChain$Entry, IoSession, Object) line: 502
AbstractIoFilterChain.access$1000(AbstractIoFilterChain,
IoFilterChain$Entry, IoSession, Object) line: 52
AbstractIoFilterChain$EntryImpl$1.messageReceived(IoSession,
Object) line: 777
ExecutorFilter.processEvent(IoFilter$NextFilter, IoSession,
ExecutorFilter$EventType, Object) line: 243
ExecutorFilter$ProcessEventsRunnable.run() line: 305
ThreadPoolExecutor$Worker.runTask(Runnable) line: 650
ThreadPoolExecutor$Worker.run() line: 675
Thread.run() line: 595