[ 
https://issues.apache.org/jira/browse/AMQ-7362?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Knut Saua Mathiesen updated AMQ-7362:
-------------------------------------
    Description: 
I'm trying to hunt down why my application, when using a vm broker, will not 
shutdown gracefully.

Though I have not found the problem (yet) I might have found a concurrency bug 
in the VMTransportServer code:
{code:java}
 VMTransport client = new VMTransport(location) {
    public void stop() throws Exception {
        if (!disposed.get()) {
            super.stop();
            if (connectionCount.decrementAndGet() == 0 && disposeOnDisconnect) {
                VMTransportServer.this.stop();
            }
        }
    };
};{code}
My debugger tells me that I've managed to get connectionCount less than 0 which 
does not make any sense.

>From what I can see: If _disposed.get()_ returns _false_ it will call 
>_super.stop()_ which does a compareAndSet on dispose:
{code:java}
    @Override
    public void stop() throws Exception {
        // Only need to do this once, all future oneway calls will now
        // fail as will any asnyc jobs in the task runner.
        if (disposed.compareAndSet(false, true)) {
...
{code}
One could easily imagine that two threads both come to the conclusion that 
disposed.get() returns false, while only one of the will be allowed into the 
body of VMTransport#stop().

The second thread will still decrement the connectionCount which as far as I 
can see is wrong.

 

I don't see why this couldn't just be:
{code:java}
 VMTransport client = new VMTransport(location) {
    public void stop() throws Exception {
        super.stop();
        if (!disposed.get()) {
            if (connectionCount.decrementAndGet() == 0 && disposeOnDisconnect) {
                VMTransportServer.this.stop();
            }
        }
    };
};
 {code}

  was:
I'm trying to hunt down why my application, when using a vm broker, will not 
shutdown gracefully.

Though I have not found the problem (yet) I might have found a concurrency bug 
in the VMTransportServer code:
{code:java}
 VMTransport client = new VMTransport(location) {
    public void stop() throws Exception {
        if (!disposed.get()) {
            super.stop();
            if (connectionCount.decrementAndGet() == 0 && disposeOnDisconnect) {
                VMTransportServer.this.stop();
            }
        }
    };
};{code}
My debugger tells me that I've managed to get connectionCount less than 0 which 
does not make any sense.

>From what I can see: If _disposed.get()_ returns _false_ it will call 
>_super.stop()_ which does a compareAndSet on dispose:
{code:java}
    @Override
    public void stop() throws Exception {
        // Only need to do this once, all future oneway calls will now
        // fail as will any asnyc jobs in the task runner.
        if (disposed.compareAndSet(false, true)) {
...
{code}
One could easily imagine that two threads both come to the conclusion that 
disposed.get() returns false, while only one of the will be allowed into the 
body of VMTransport#stop().

The second thread will still decrement the connectionCount which as far as I 
can see is wrong.


> Concurrency bug in closing of VMTransportServer?
> ------------------------------------------------
>
>                 Key: AMQ-7362
>                 URL: https://issues.apache.org/jira/browse/AMQ-7362
>             Project: ActiveMQ
>          Issue Type: Bug
>    Affects Versions: 5.15.11
>            Reporter: Knut Saua Mathiesen
>            Priority: Major
>
> I'm trying to hunt down why my application, when using a vm broker, will not 
> shutdown gracefully.
> Though I have not found the problem (yet) I might have found a concurrency 
> bug in the VMTransportServer code:
> {code:java}
>  VMTransport client = new VMTransport(location) {
>     public void stop() throws Exception {
>         if (!disposed.get()) {
>             super.stop();
>             if (connectionCount.decrementAndGet() == 0 && 
> disposeOnDisconnect) {
>                 VMTransportServer.this.stop();
>             }
>         }
>     };
> };{code}
> My debugger tells me that I've managed to get connectionCount less than 0 
> which does not make any sense.
> From what I can see: If _disposed.get()_ returns _false_ it will call 
> _super.stop()_ which does a compareAndSet on dispose:
> {code:java}
>     @Override
>     public void stop() throws Exception {
>         // Only need to do this once, all future oneway calls will now
>         // fail as will any asnyc jobs in the task runner.
>         if (disposed.compareAndSet(false, true)) {
> ...
> {code}
> One could easily imagine that two threads both come to the conclusion that 
> disposed.get() returns false, while only one of the will be allowed into the 
> body of VMTransport#stop().
> The second thread will still decrement the connectionCount which as far as I 
> can see is wrong.
>  
> I don't see why this couldn't just be:
> {code:java}
>  VMTransport client = new VMTransport(location) {
>     public void stop() throws Exception {
>         super.stop();
>         if (!disposed.get()) {
>             if (connectionCount.decrementAndGet() == 0 && 
> disposeOnDisconnect) {
>                 VMTransportServer.this.stop();
>             }
>         }
>     };
> };
>  {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to