[ 
https://issues.apache.org/jira/browse/GROOVY-8067?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15853145#comment-15853145
 ] 

ASF GitHub Bot commented on GROOVY-8067:
----------------------------------------

GitHub user jwagenleitner opened a pull request:

    https://github.com/apache/groovy/pull/489

    GROOVY-8067: Possible deadlock when creating new ClassInfo entries in the 
cache

    As suggested in PR #484 removed the locking on the `ManagedLinkedList` by 
creating a new `ManagedConcurrentLinkedQueue`.
    
    Also added a `stress` subproject for tests that employ many threads, need 
GC, or just in general try to break things and take a long time.  These require 
a special property to be set in order to run, otherwise they will be skipped.  
I tried to work it out in the `performance` subproject, but that seems to be 
very specialized for the compiler tests.  Open to suggestions on a better way 
to handle these types of tests.

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/jwagenleitner/groovy groovy8067-mclq

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/groovy/pull/489.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #489
    
----
commit bb2464a919a3655f36707fa72fb30080c92a7288
Author: John Wagenleitner <[email protected]>
Date:   2017-02-05T06:13:26Z

    GROOVY-8067: Possible deadlock when creating new ClassInfo entries in the 
cache

----


> Possible deadlock when creating new ClassInfo entries in the cache
> ------------------------------------------------------------------
>
>                 Key: GROOVY-8067
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8067
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-runtime
>    Affects Versions: 2.4.8
>            Reporter: John Wagenleitner
>            Priority: Critical
>         Attachments: ClassInfoDeadlockTest.java
>
>
> When running Groovy without {{-Dgroovy.use.classvalue=true}} the ClassInfo 
> instances are cached in a {{ManagedConcurrentMap}} (MCM).  New values are 
> computed on demand and computation involves both a lock on a segment within 
> the MCM and a lock on the {{GlobalClassSet}} (GCS) which is backed by a 
> {{ManagedLinkedList}}.  The problem is that both the ManagedConcurrentMap and 
> the GlobalClassSet share the same ReferenceQueue.
> Assume there is an enqueued {{ClassInfo}} value that is stored in Segment2 of 
> the MCM.  Now assume that Thread1 and Thread2 both request 
> {{ClassInfo.getClassInfo(..)}} for two different classes that do not 
> currently exist in the cache.  Assume that based on hashing Thread1 gets a 
> lock on Segment1 and Thread2 gets a lock on Segment2.  Assume that Thread1 is 
> the first to call computeValue which in turn calls 
> {{GlobalClassSet.add(..)}}.  This call adds a new value to a 
> {{ManagedLinkedList}}, and since it's managed the add operation will process 
> the ReferenceQueue. So Thread1 will attempt to dequeue the ClassInfo and the 
> finalizeReference method on it's entry will attempt to remove it from 
> Segment2. Thread2 holds the lock for Segment2 and Thread2 is blocked and 
> can't progress it's waiting on the the lock Thread1 holds the lock for the 
> GlobalClassSet, so deadlock occurs.
> The attached test case includes a thread dump at the bottom.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to