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/01/15 03:00:54 UTC

[jira] Commented: (DIRMINA-755) IoConnectot.dispose blocks forever

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

Emmanuel Lecharny commented on DIRMINA-755:
-------------------------------------------

Ok, I'm clearly able to reproduce the lock, and I think I can explain what's going on.

In your client, you close the session waiting for all the messages to be processed before the closure. So far, so good.

You get back a CloseFuture, and you associate a listener to it, which get called immediately after the last message has been processed. In this listener, you have this method :

            public void operationComplete(IoFuture future) {
                System.out.println("managed session count=" + connector.getManagedSessionCount());
                System.out.println("Disposing connector ...");
                connector.dispose();
                System.out.println("Disposing connector ... *finished*");
            }

The problem here is that this listener will be called in a thread, and then the dispose() method will be called, using the very same thread. As the dispose() will create internally a DisposalFuture, which waits until the internal 'ready' flag is set to true by another thread, it will wait forever just because no thread will be here to flip the flag to true.

You can fix this by simply moving the dispose() out of the listener :
...
        // Get the close future for this session
        CloseFuture closeFuture = cf.getSession().getCloseFuture();

        closeFuture.addListener((IoFutureListener<?>) new IoFutureListener<IoFuture>() {

            @Override
            public void operationComplete(IoFuture future) {
                System.out.println("managed session count=" + connector.getManagedSessionCount());
            }
        });

        // wait for session close and then dispose the connector
        System.out.println( "Closing the session..." );
        closeFuture.getSession().close(false);

        System.out.println( "Waiting for the session to be closed..." );
        closeFuture.awaitUninterruptibly();
        System.out.println( "Session closed !!!" );
        
        System.out.println("Disposing connector ...");
        connector.dispose();
        System.out.println("Disposing connector ... *finished*");
}


FYI, I have also called the close() method after having grabbed the CloseFuture and affected the listener to it.

Just tell me if this fix your problem.

> IoConnectot.dispose blocks forever
> ----------------------------------
>
>                 Key: DIRMINA-755
>                 URL: https://issues.apache.org/jira/browse/DIRMINA-755
>             Project: MINA
>          Issue Type: Bug
>    Affects Versions: 2.0.0-RC1
>            Reporter: Emmanuel Lecharny
>             Fix For: 2.0.0-RC2
>
>         Attachments: MinaTest.zip
>
>
> (Extracted from the ML)
> I recently switched from 2.0.0-M6 to 2.0.0-RC1 and now discovered a
> problem with the IoConnector (I'm using the nio stuff)...
> I'll try to explain:
> In case of network connection shutdown I try to clean up as good as
> possible. I terminate tread pools, I close the session, and finally I try
> to dispose the IoConnector. 
> Here's a small code-snippet from my shutdown-code:
> ----
> CloseFuture closeFuture = ctsc.getSession().close(false);
>                     closeFuture.addListener(new
> IoFutureListener<IoFuture>() {
>                         public void operationComplete(IoFuture future) {
>                             ctsc.getFilterchainWorkerPool().shutdown();
>                             System.out.println("managed session count=
> "+ctsc.getConnector().getManagedSessionCount());
>                             ctsc.getConnector().dispose();
>                         }
>                     });
> ----
> "ctsc" is a simple container which contains the session (getSession) and
> the used connection (getConnector). First I try to close the session. Then,
> if this operation is completed, I try to shutdown a thread pool and finally
> dispose the connector. I read in the api doc, that this dispose call may
> block in case of still open session related to this connector.
> I tried to print out the number of still open sessions. On the console I
> get: "managed session count= 0"
> But the next call, the dispose() call, blocks and prevents the remaining
> threads from shutdown to get a clean application termination.
> If I switch from RC1 backt o M6, this works quite well. 
> Am I doing something wrong? Has the behavior changed? *little bit
> confused*

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.