Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 55763200CB1 for ; Sat, 24 Jun 2017 20:48:32 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 53BA8160BE6; Sat, 24 Jun 2017 18:48:32 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 99D94160BD4 for ; Sat, 24 Jun 2017 20:48:31 +0200 (CEST) Received: (qmail 1391 invoked by uid 500); 24 Jun 2017 18:48:30 -0000 Mailing-List: contact commits-help@groovy.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@groovy.apache.org Delivered-To: mailing list commits@groovy.apache.org Received: (qmail 1382 invoked by uid 99); 24 Jun 2017 18:48:30 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 24 Jun 2017 18:48:30 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id ADA16DFA3C; Sat, 24 Jun 2017 18:48:30 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jwagenleitner@apache.org To: commits@groovy.apache.org Message-Id: <7fbf52cabb4242cbad318edb082f26df@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: groovy git commit: GROOVY-8230: Deadlock in GroovyClassLoader (closes #561) Date: Sat, 24 Jun 2017 18:48:30 +0000 (UTC) archived-at: Sat, 24 Jun 2017 18:48:32 -0000 Repository: groovy Updated Branches: refs/heads/GROOVY_2_6_X 635ccc2c9 -> 443eaace7 GROOVY-8230: Deadlock in GroovyClassLoader (closes #561) Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/443eaace Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/443eaace Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/443eaace Branch: refs/heads/GROOVY_2_6_X Commit: 443eaace7ae380cfd706123adee11cde7a82acaf Parents: 635ccc2 Author: John Wagenleitner Authored: Sun Jun 18 17:16:07 2017 -0700 Committer: John Wagenleitner Committed: Sat Jun 24 11:47:49 2017 -0700 ---------------------------------------------------------------------- src/main/groovy/lang/GroovyClassLoader.java | 28 +++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/443eaace/src/main/groovy/lang/GroovyClassLoader.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/GroovyClassLoader.java b/src/main/groovy/lang/GroovyClassLoader.java index 11dedfd..394627b 100644 --- a/src/main/groovy/lang/GroovyClassLoader.java +++ b/src/main/groovy/lang/GroovyClassLoader.java @@ -963,23 +963,45 @@ public class GroovyClassLoader extends URLClassLoader { /** * Removes all classes from the class cache. + *

+ * In addition to internal caches this method also clears any + * previously set MetaClass information for the given set of + * classes being removed. * * @see #getClassCacheEntry(String) * @see #setClassCacheEntry(Class) * @see #removeClassCacheEntry(String) */ public void clearCache() { + Class[] clearedClasses; synchronized (classCache) { - for (Class cl : classCache.values()) { - InvokerHelper.removeClass(cl); - } + clearedClasses = getLoadedClasses(); classCache.clear(); } synchronized (sourceCache) { sourceCache.clear(); } + for (Class c : clearedClasses) { + // Another Thread may be using an instance of this class + // (for the first time) requiring a ClassInfo lock and + // classloading which would require a lock on classCache. + // The following locks on ClassInfo and to avoid deadlock + // should not be done with a classCache lock. + InvokerHelper.removeClass(c); + } } + /** + * Closes this GroovyClassLoader and clears any caches it maintains. + *

+ * No use should be made of this instance after this method is + * invoked. Any classes that are already loaded are still accessible. + * + * @throws IOException + * @see URLClassLoader#close() + * @see #clearCache() + * @since 2.5.0 + */ @Override public void close() throws IOException { super.close();