You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by "Emmanuel Lecharny (JIRA)" <ji...@apache.org> on 2010/11/03 23:50:29 UTC
[jira] Updated: (DIRMINA-807) Deadlock with NioDatagramAcceptor/Udp
(Compilable code inlined showing issue)
[ https://issues.apache.org/jira/browse/DIRMINA-807?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Emmanuel Lecharny updated DIRMINA-807:
--------------------------------------
Affects Version/s: 2.0.1
Fix Version/s: 2.0.2
I confirm there is an issue.
Doing a service.toString() in the listener.serviceActivated() method leads to a race condition : as this method is called when the Acceptor binds, the gelLocalAddress() called in the toString() method blocks as it's synchronized on a lock already hold by the bindInternal() method :
/**
* {@inheritDoc}
*/
public final void bind(Iterable<? extends SocketAddress> localAddresses) throws IOException {
...
boolean activate = false;
synchronized (bindLock) {
...
try {
boundAddresses.addAll(bindInternal(localAddressesCopy));
} catch (IOException e) {
protected final Set<SocketAddress> bindInternal(
List<? extends SocketAddress> localAddresses) throws Exception {
...
startupAcceptor();
wakeup();
request.awaitUninterruptibly(); <=== Here, we wait for the bind to ends. The bindLock is still hold at this point.
On the other thread :
public void serviceActivated( final IoService service ) throws Exception
{
String s = service.toString();
}
public String toString() {
...
Set<SocketAddress> addresses = getLocalAddresses();
public final Set<SocketAddress> getLocalAddresses() {
Set<SocketAddress> localAddresses = new HashSet<SocketAddress>();
synchronized (bindLock) { <=== DEAD LOCK !!!
> Deadlock with NioDatagramAcceptor/Udp (Compilable code inlined showing issue)
> -----------------------------------------------------------------------------
>
> Key: DIRMINA-807
> URL: https://issues.apache.org/jira/browse/DIRMINA-807
> Project: MINA
> Issue Type: Bug
> Components: Core
> Affects Versions: 2.0.0, 2.0.1
> Environment: Windows XP Service Pack 3 (32bit)
> Reporter: Jason
> Priority: Blocker
> Fix For: 2.0.2
>
>
> NOTE: This issue occurs with 2.0.0 and 2.0.1
> Comment out the addListener and apparent Deadlock goes away.
> final IoServiceListener listener = new UdpIoServiceListener();
> // APACHE: THIS CREATES A DEADLOCK
> acceptor.addListener(listener);
> When the listener is added bind never returns.
> acceptor.bind(new InetSocketAddress(12345));
> If you comment out the addListener, bind returns and you will see
> the System.out..
> (Compilable code inlined showing issue)
> [BEGIN]
> import java.io.IOException;
> import java.net.InetSocketAddress;
> import java.net.SocketAddress;
> import java.util.Set;
> import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
> import org.apache.mina.core.service.IoHandlerAdapter;
> import org.apache.mina.core.service.IoService;
> import org.apache.mina.core.service.IoServiceListener;
> import org.apache.mina.core.session.IdleStatus;
> import org.apache.mina.core.session.IoSession;
> import org.apache.mina.filter.logging.LoggingFilter;
> import org.apache.mina.transport.socket.DatagramSessionConfig;
> import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
> public class UdpBug {
> public static class UdpIoServiceListener implements IoServiceListener {
> @Override
> public void serviceActivated(final IoService service) throws Exception {
> System.out.println("UdpServiceListener#serviceActivated service: " + service);
> }
> @Override
> public void serviceDeactivated(final IoService service) throws Exception {
> System.out.println("UdpServiceListener#serviceDeactivated service: " + service);
> }
> @Override
> public void serviceIdle(final IoService service, final IdleStatus status) throws Exception {
> System.out.println("UdpServiceListener#serviceIdle service: " + service + " status: " + status);
> }
> @Override
> public void sessionCreated(final IoSession session) throws Exception {
> System.out.println("UdpServiceListener#sessionCreated session: " + session);
> }
> @Override
> public void sessionDestroyed(final IoSession session) throws Exception {
> System.out.println("UdpServiceListener#sessionDestroyed session: " + session);
> }
> }
> public static class UdpIoHandler extends IoHandlerAdapter {
> public UdpIoHandler() {
> }
> @Override
> public void sessionCreated(final IoSession session) throws Exception {
> System.out.println("UdpIoHandler#sessionCreated session: " + session);
> session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
> }
> @Override
> public void sessionOpened(final IoSession session) throws Exception {
> System.out.println("UdpIoHandler#sessionOpened session: " + session);
> }
> @Override
> public void sessionClosed(final IoSession session) throws Exception {
> System.out.println("UdpIoHandler#sessionClosed session: " + session);
> }
> @Override
> public void sessionIdle(final IoSession session, final IdleStatus status) throws Exception {
> System.out.println("UdpIoHandler#sessionCreated session: " + session + " status: " + status);
> session.close(true);
> }
> @Override
> public void exceptionCaught(final IoSession session, final Throwable cause) throws Exception {
> System.out.println("UdpIoHandler#exceptionCaught session: " + session + " cause: " + cause);
> session.close(true);
> }
> @Override
> public void messageReceived(final IoSession session, final Object message) throws Exception {
> System.out.println("UdpIoHandler#messageReceived session: " + session + " message: " + message);
> }
> }
> public static final void main(String[] args) throws IOException {
> // ByteBuffer.setUseDirectBuffers(false);
> NioDatagramAcceptor acceptor = new NioDatagramAcceptor();
> acceptor.setCloseOnDeactivation(true);
> final IoServiceListener listener = new UdpIoServiceListener();
> // APACHE: THIS CREATES A DEADLOCK
> acceptor.addListener(listener);
> final DatagramSessionConfig sessionConfig = acceptor.getSessionConfig();
> sessionConfig.setReuseAddress(true);
> final DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
> final LoggingFilter loggingFilter = new LoggingFilter();
> chain.addLast("logFilter", loggingFilter);
> // acceptor.setFilterChainBuilder(chain);
> acceptor.setHandler(new UdpIoHandler());
> acceptor.bind(new InetSocketAddress(12345));
> final Set<SocketAddress> addrs = acceptor.getLocalAddresses();
> for (final SocketAddress addr : addrs) {
> System.out.println("UdpServer.start " + addr.toString());
> }
> System.out.println("UdpServer started on port " + 12345);
> }
> }
> [END]
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.