mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Andre de C. Rodrigues" <andre.rodrigue...@gmail.com>
Subject Concurrency problems in MINA
Date Mon, 04 Jun 2007 18:22:53 GMT
Hello,

I'm having a few concurrency problems in my project.

In my project, I have an IoHandler that binds to another port when it
receives it's first message. If another person connects to my program,
it has to close the previous connection before it binds to the same
port again, otherwise I'd get an exception stating "address already in
use". So, what I do is that I have a filter that detects a second
connection incoming and closes the previous connection. Obviously, the
previous connection has to be closed *before* the current connection
attempts to bind.

The thing is, session.close().join() does not work as expected: it
does not wait until the other session is closed before continuing with
the calling thread's execution, so the new session is not *always*
created only after the old session was closed.

I took some excerpts from my code to reproduce the error. Since I
don't know how you handle Attachments, I'll just paste my code here.
There are only 3 classes, and they are rather small =P.

Does anyone has any idea to fix or work around this?

Thanks in advance for the help, MINA is great.

Cheers.

PS: I'm using MINA 1.1

MAIN:
/////////////////////////////////////////////////////
package bug;

import java.net.InetSocketAddress;

import org.apache.mina.common.IoAcceptor;
import org.apache.mina.common.IoAcceptorConfig;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;

public class Main
{
	/** Choose your favorite port number. */
	private static final int PORT = 9999;

	public static void main( String[] args ) throws Exception
	{
		IoAcceptor acceptor = new SocketAcceptor();
		
		IoAcceptorConfig config = new SocketAcceptorConfig();
		config.getFilterChain().addLast("Filter",  new Filter());
		
		acceptor.bind(
				new InetSocketAddress( PORT ),
				new Handler(),
				config);

		System.out.println( "Listening on port " + PORT );
	}

}

/////////////////////////////////////////////////////

Filter:
/////////////////////////////////////////////////////
package bug;

import org.apache.mina.common.IoFilterAdapter;
import org.apache.mina.common.IoSession;



public class Filter extends IoFilterAdapter {
	private IoSession currentSession;


	@Override
	public void messageReceived(NextFilter nextFilter, IoSession session,
Object message) throws Exception {
		if((Boolean)session.getAttribute("FirstMessage")){
			if(currentSession != null){
				System.out.println("Filter: Closing previous session...");
				currentSession.close().join();
			}
			System.out.println("Filter: Saving new session...");
			currentSession = session;
		}
		super.messageReceived(nextFilter, session, message);
	}
}
/////////////////////////////////////////////////////

Handler:
/////////////////////////////////////////////////////
package bug;

import java.net.InetSocketAddress;

import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.apache.mina.transport.socket.nio.SocketAcceptor;

public class Handler extends IoHandlerAdapter
{
	public void sessionClosed( IoSession session )
	{
                Thread.sleep(1000);   //this is only to make sure that
it always takes longer to close the previous session than to create
the new one... without this, it works *sometimes*.
		System.out.println("Unbinding...");
		((IoAcceptor) session.getAttribute("ACCEPTOR")).unbindAll();
	}


	@Override
	public void sessionCreated(IoSession session) throws Exception {
		session.setAttribute("FirstMessage", true);
		super.sessionCreated(session);
	}


	public void messageReceived( IoSession session, Object message )
throws Exception
	{
		if((Boolean)session.getAttribute("FirstMessage")){
			System.out.println("Handler: Creating new session...");
			int PORTA = 10000;
			IoAcceptor acceptor = new SocketAcceptor();
			session.setAttribute("ACCEPTOR", acceptor);
			System.out.println("Binding...");
		        acceptor.bind(new InetSocketAddress(PORTA), new Handler());
			System.out.println("Handler: Listening on port "+PORTA);
			session.setAttribute("FirstMessage", false);
		}

		else{
			if( !( message instanceof ByteBuffer ) )
			{
				return;
			}
			ByteBuffer rb = ( ByteBuffer ) message;
			System.out.println("\nBUFFER: "+rb);
		}
	}

}
/////////////////////////////////////////////////////

Mime
View raw message