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

Sarthak Shukla updated POOL-407:
--------------------------------
    Description: 
While borrowing object from pool, threads are getting stuck. I initialised the 
pool size as 1. And had 3 threads created. First thread enters borrowObject 
method, since there are no idle objects to poll from, it will create one object 
and move forward.
{quote}p = (PooledObject)this.idleObjects.pollFirst();
if (p == null) {
  p = this.create();
  if (p != null) {
     create = true;
  }
}
{quote}
The other two threads will also follow same path and check for idle 
objects(there are none), will try to create one object but the pool size is set 
to 1. Thus, the two threads will move forward and enter 
*idleObjects.takeFirst()* function. Value of blockWhenExhausted is true and 
borrowMaxWaitMillis is -1 as we don't want timeout.
{quote}if (blockWhenExhausted) {
   if (p == null) {
      if (borrowMaxWaitMillis < 0L) {
           p = (PooledObject)this.idleObjects.takeFirst();
      } else {
           p = (PooledObject)this.idleObjects.pollFirst(borrowMaxWaitMillis, 
TimeUnit.MILLISECONDS);
      }
   }

   if (p == null) {
      throw new NoSuchElementException("Timeout waiting for idle object");
   }
}
{quote}
Now, the main thread does *this.factory.activateObject(p);* and object gets 
activated. Now, when the validation is checked *validate = 
this.factory.validateObject(p);* it comes out to be false as provider might 
have been disconnected.

So, the object is destroyed by calling *this.destroy(p);*
{quote}private void destroy(PooledObject<T> toDestroy) throws Exception {
     toDestroy.invalidate();
     this.idleObjects.remove(toDestroy);
     this.allObjects.remove(new 
BaseGenericObjectPool.IdentityWrapper(toDestroy.getObject()));

     try {
        this.factory.destroyObject(toDestroy);
     } finally {
        this.destroyedCount.incrementAndGet();
        this.createCount.decrementAndGet();
     }
}
{quote}
The object which was created is now destroyed and removed from idleObject and 
allObjects list. Now, the other two threads are still waiting to take object 
from idle objects list but there are no object present. Hence, the two threads 
are in wait state for infinite period and the application waits forever until 
we kill the process.
{quote}public E takeFirst() throws InterruptedException {
   this.lock.lock();

   Object var2;
   try {
      Object x;
      while((x = this.unlinkFirst()) == null)
Unknown macro: \{          this.notEmpty.await();       }
      var2 = x;
    } finally
Unknown macro: \{       this.lock.unlock();     }
    return var2;
}
{quote}

  was:
While borrowing object from pool, threads are getting stuck. I initialised the 
pool size as 1. And had 3 threads created. First thread enters borrowObject 
method, since there are no idle objects to poll from, it will create one object 
and move forward.
{quote}p = (PooledObject)this.idleObjects.pollFirst();

if (p == null) {

     p = this.create();

     if (p != null)
Unknown macro: \{         create = true;       }
}
{quote}
The other two threads will also follow same path and check for idle 
objects(there are none), will try to create one object but the pool size is set 
to 1. Thus, the two threads will move forward and enter 
*idleObjects.takeFirst()* function. Value of blockWhenExhausted is true and 
borrowMaxWaitMillis is -1 as we don't want timeout.
{quote}if (blockWhenExhausted) {
   if (p == null) {
      if (borrowMaxWaitMillis < 0L) {
           p = (PooledObject)this.idleObjects.takeFirst();
      } else {
           p = (PooledObject)this.idleObjects.pollFirst(borrowMaxWaitMillis, 
TimeUnit.MILLISECONDS);
      }
   }

   if (p == null) {
      throw new NoSuchElementException("Timeout waiting for idle object");
   }
}
{quote}
Now, the main thread does *this.factory.activateObject(p);* and object gets 
activated. Now, when the validation is checked *validate = 
this.factory.validateObject(p);* it comes out to be false as provider might 
have been disconnected.

So, the object is destroyed by calling *this.destroy(p);*
{quote}private void destroy(PooledObject<T> toDestroy) throws Exception {
     toDestroy.invalidate();
     this.idleObjects.remove(toDestroy);
     this.allObjects.remove(new 
BaseGenericObjectPool.IdentityWrapper(toDestroy.getObject()));

     try {
        this.factory.destroyObject(toDestroy);
     } finally {
        this.destroyedCount.incrementAndGet();
        this.createCount.decrementAndGet();
     }
}
{quote}
The object which was created is now destroyed and removed from idleObject and 
allObjects list. Now, the other two threads are still waiting to take object 
from idle objects list but there are no object present. Hence, the two threads 
are in wait state for infinite period and the application waits forever until 
we kill the process.
{quote}public E takeFirst() throws InterruptedException {
   this.lock.lock();

   Object var2;
   try {
      Object x;
      while((x = this.unlinkFirst()) == null) {
         this.notEmpty.await();
      }

      var2 = x;
    } finally {
      this.lock.unlock();
    }
    return var2;
}
{quote}


> Threads get stuck when idleObjects list is empty.
> -------------------------------------------------
>
>                 Key: POOL-407
>                 URL: https://issues.apache.org/jira/browse/POOL-407
>             Project: Commons Pool
>          Issue Type: Bug
>    Affects Versions: 2.8.1
>            Reporter: Sarthak Shukla
>            Priority: Major
>
> While borrowing object from pool, threads are getting stuck. I initialised 
> the pool size as 1. And had 3 threads created. First thread enters 
> borrowObject method, since there are no idle objects to poll from, it will 
> create one object and move forward.
> {quote}p = (PooledObject)this.idleObjects.pollFirst();
> if (p == null) {
>   p = this.create();
>   if (p != null) {
>      create = true;
>   }
> }
> {quote}
> The other two threads will also follow same path and check for idle 
> objects(there are none), will try to create one object but the pool size is 
> set to 1. Thus, the two threads will move forward and enter 
> *idleObjects.takeFirst()* function. Value of blockWhenExhausted is true and 
> borrowMaxWaitMillis is -1 as we don't want timeout.
> {quote}if (blockWhenExhausted) {
>    if (p == null) {
>       if (borrowMaxWaitMillis < 0L) {
>            p = (PooledObject)this.idleObjects.takeFirst();
>       } else {
>            p = (PooledObject)this.idleObjects.pollFirst(borrowMaxWaitMillis, 
> TimeUnit.MILLISECONDS);
>       }
>    }
>    if (p == null) {
>       throw new NoSuchElementException("Timeout waiting for idle object");
>    }
> }
> {quote}
> Now, the main thread does *this.factory.activateObject(p);* and object gets 
> activated. Now, when the validation is checked *validate = 
> this.factory.validateObject(p);* it comes out to be false as provider might 
> have been disconnected.
> So, the object is destroyed by calling *this.destroy(p);*
> {quote}private void destroy(PooledObject<T> toDestroy) throws Exception {
>      toDestroy.invalidate();
>      this.idleObjects.remove(toDestroy);
>      this.allObjects.remove(new 
> BaseGenericObjectPool.IdentityWrapper(toDestroy.getObject()));
>      try {
>         this.factory.destroyObject(toDestroy);
>      } finally {
>         this.destroyedCount.incrementAndGet();
>         this.createCount.decrementAndGet();
>      }
> }
> {quote}
> The object which was created is now destroyed and removed from idleObject and 
> allObjects list. Now, the other two threads are still waiting to take object 
> from idle objects list but there are no object present. Hence, the two 
> threads are in wait state for infinite period and the application waits 
> forever until we kill the process.
> {quote}public E takeFirst() throws InterruptedException {
>    this.lock.lock();
>    Object var2;
>    try {
>       Object x;
>       while((x = this.unlinkFirst()) == null)
> Unknown macro: \{          this.notEmpty.await();       }
>       var2 = x;
>     } finally
> Unknown macro: \{       this.lock.unlock();     }
>     return var2;
> }
> {quote}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to