commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Buğra Gedik (JIRA) <j...@apache.org>
Subject [jira] [Updated] (POOL-315) GenericObjectPool close() does not wait for the current eviction task
Date Tue, 18 Oct 2016 13:04:58 GMT

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

Buğra Gedik updated POOL-315:
-----------------------------
    Description: 
The {{close}} method is implemented as follows:

{code}
public void close() {
        if(!this.isClosed()) {
            Object var1 = this.closeLock;
            synchronized(this.closeLock) {
                if(!this.isClosed()) {
                    this.startEvictor(-1L);
                    this.closed = true;
                    this.clear();
                    this.jmxUnregister();
                    this.idleObjects.interuptTakeWaiters();
                }
            }
        }
    }
{code}

The line {{this.startEvictor(-1L);}} calls {{EvictionTimer.cancel(this.evictor);}} from {{BaseGenericObjectPool}}
and that in turn calls the following method in {{EvictionTimer}}:

{code}
    static synchronized void cancel(TimerTask task) {
        task.cancel();
        --_usageCount;
        if(_usageCount == 0) {
            _timer.cancel();
            _timer = null;
        }
    }
{code}

Here, {{_timer}} is a {{java.util.TimerTask}}. If you look at the documentation of it, you'll
see that it does not block on the currently executing task. Even though {{task.cancel()}}
is called, there is no code to wait for it to complete. The end result is that, when if you
close the pool, there may still be an eviction thread running. Yes, it will eventually go
away, but in some rare cases it takes a bit of time to go away.

When running code under Tomcat, this results in the {{"commons-pool-EvictionTimer"}} thread
(created in the class {{EvictionTimer}}) to be reported as leaking, despite the pool being
closed. This happens rarely, since most of the time the timer thread goes away before Tomcat
checks for leaking threads.






  was:
The {{close}} method is implemented as follows:

{code}
public void close() {
        if(!this.isClosed()) {
            Object var1 = this.closeLock;
            synchronized(this.closeLock) {
                if(!this.isClosed()) {
                    this.startEvictor(-1L);
                    this.closed = true;
                    this.clear();
                    this.jmxUnregister();
                    this.idleObjects.interuptTakeWaiters();
                }
            }
        }
    }
{code}

The line {{this.startEvictor(-1L);}} calls {{EvictionTimer.cancel(this.evictor);}} from {{BaseGenericObjectPool}}
and that in turn calls the following method in {{EvictionTimer}}:

{{code}}
    static synchronized void cancel(TimerTask task) {
        task.cancel();
        --_usageCount;
        if(_usageCount == 0) {
            _timer.cancel();
            _timer = null;
        }
    }
{{code}}

Here, {{_timer}} is a {{java.util.TimerTask}}. If you look at the documentation of it, you'll
see that it does not block on the currently executing task. Even though {{task.cancel()}}
is called, there is no code to wait for it to complete. The end result is that, when if you
close the pool, there may still be an eviction thread running. Yes, it will eventually go
away, but in some rare cases it takes a bit of time to go away.

When running code under Tomcat, this results in the {{"commons-pool-EvictionTimer"}} thread
(created in the class {{EvictionTimer}}) to be reported as leaking, despite the pool being
closed. This happens rarely, since most of the time the timer thread goes away before Tomcat
checks for leaking threads.







> GenericObjectPool close() does not wait for the current eviction task
> ---------------------------------------------------------------------
>
>                 Key: POOL-315
>                 URL: https://issues.apache.org/jira/browse/POOL-315
>             Project: Commons Pool
>          Issue Type: Bug
>            Reporter: Buğra Gedik
>
> The {{close}} method is implemented as follows:
> {code}
> public void close() {
>         if(!this.isClosed()) {
>             Object var1 = this.closeLock;
>             synchronized(this.closeLock) {
>                 if(!this.isClosed()) {
>                     this.startEvictor(-1L);
>                     this.closed = true;
>                     this.clear();
>                     this.jmxUnregister();
>                     this.idleObjects.interuptTakeWaiters();
>                 }
>             }
>         }
>     }
> {code}
> The line {{this.startEvictor(-1L);}} calls {{EvictionTimer.cancel(this.evictor);}} from
{{BaseGenericObjectPool}} and that in turn calls the following method in {{EvictionTimer}}:
> {code}
>     static synchronized void cancel(TimerTask task) {
>         task.cancel();
>         --_usageCount;
>         if(_usageCount == 0) {
>             _timer.cancel();
>             _timer = null;
>         }
>     }
> {code}
> Here, {{_timer}} is a {{java.util.TimerTask}}. If you look at the documentation of it,
you'll see that it does not block on the currently executing task. Even though {{task.cancel()}}
is called, there is no code to wait for it to complete. The end result is that, when if you
close the pool, there may still be an eviction thread running. Yes, it will eventually go
away, but in some rare cases it takes a bit of time to go away.
> When running code under Tomcat, this results in the {{"commons-pool-EvictionTimer"}}
thread (created in the class {{EvictionTimer}}) to be reported as leaking, despite the pool
being closed. This happens rarely, since most of the time the timer thread goes away before
Tomcat checks for leaking threads.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message