lucene-solr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hoss...@apache.org
Subject svn commit: r949475 - in /lucene/solr/branches/branch-1.4: ./ CHANGES.txt src/java/org/apache/solr/core/SolrCore.java src/java/org/apache/solr/core/SolrResourceLoader.java
Date Sun, 30 May 2010 04:50:25 GMT
Author: hossman
Date: Sun May 30 04:50:25 2010
New Revision: 949475

URL: http://svn.apache.org/viewvc?rev=949475&view=rev
Log:
merging r925898 from solr/branches/branch-1.5-dev for SOLR-1797

Modified:
    lucene/solr/branches/branch-1.4/   (props changed)
    lucene/solr/branches/branch-1.4/CHANGES.txt
    lucene/solr/branches/branch-1.4/src/java/org/apache/solr/core/SolrCore.java
    lucene/solr/branches/branch-1.4/src/java/org/apache/solr/core/SolrResourceLoader.java

Propchange: lucene/solr/branches/branch-1.4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sun May 30 04:50:25 2010
@@ -1 +1 @@
-/lucene/solr/trunk:881642,881906,883566,891596,891889,903271,911245
+/lucene/solr/trunk:881642,881906,883566,891596,891889,903271,911245,925898

Modified: lucene/solr/branches/branch-1.4/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/solr/branches/branch-1.4/CHANGES.txt?rev=949475&r1=949474&r2=949475&view=diff
==============================================================================
--- lucene/solr/branches/branch-1.4/CHANGES.txt (original)
+++ lucene/solr/branches/branch-1.4/CHANGES.txt Sun May 30 04:50:25 2010
@@ -71,6 +71,9 @@ Bug Fixes
 * SOLR-1777: fieldTypes with sortMissingLast=true or sortMissingFirst=true can
   result in incorrectly sorted results.  (yonik)
 
+* SOLR-1797: fix ConcurrentModificationException and potential memory
+  leaks in ResourceLoader. (yonik)
+
 ================== Release 1.4.0 ==================
 Release Date:  See http://lucene.apache.org/solr for the official release date.
 

Modified: lucene/solr/branches/branch-1.4/src/java/org/apache/solr/core/SolrCore.java
URL: http://svn.apache.org/viewvc/lucene/solr/branches/branch-1.4/src/java/org/apache/solr/core/SolrCore.java?rev=949475&r1=949474&r2=949475&view=diff
==============================================================================
--- lucene/solr/branches/branch-1.4/src/java/org/apache/solr/core/SolrCore.java (original)
+++ lucene/solr/branches/branch-1.4/src/java/org/apache/solr/core/SolrCore.java Sun May 30
04:50:25 2010
@@ -585,7 +585,7 @@ public final class SolrCore implements S
 
       // Finally tell anyone who wants to know
       resourceLoader.inform( resourceLoader );
-      resourceLoader.inform( this );
+      resourceLoader.inform( this );  // last call before the latch is released.
       instance = this;   // set singleton for backwards compatibility
     } catch (IOException e) {
       throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);

Modified: lucene/solr/branches/branch-1.4/src/java/org/apache/solr/core/SolrResourceLoader.java
URL: http://svn.apache.org/viewvc/lucene/solr/branches/branch-1.4/src/java/org/apache/solr/core/SolrResourceLoader.java?rev=949475&r1=949474&r2=949475&view=diff
==============================================================================
--- lucene/solr/branches/branch-1.4/src/java/org/apache/solr/core/SolrResourceLoader.java
(original)
+++ lucene/solr/branches/branch-1.4/src/java/org/apache/solr/core/SolrResourceLoader.java
Sun May 30 04:50:25 2010
@@ -69,13 +69,15 @@ public class SolrResourceLoader implemen
   private final String instanceDir;
   private String dataDir;
   
-  private final List<SolrCoreAware> waitingForCore = new ArrayList<SolrCoreAware>();
-  private final List<SolrInfoMBean> infoMBeans = new ArrayList<SolrInfoMBean>();
-  private final List<ResourceLoaderAware> waitingForResources = new ArrayList<ResourceLoaderAware>();
+  private final List<SolrCoreAware> waitingForCore = Collections.synchronizedList(new
ArrayList<SolrCoreAware>());
+  private final List<SolrInfoMBean> infoMBeans = Collections.synchronizedList(new ArrayList<SolrInfoMBean>());
+  private final List<ResourceLoaderAware> waitingForResources = Collections.synchronizedList(new
ArrayList<ResourceLoaderAware>());
   private static final Charset UTF_8 = Charset.forName("UTF-8");
 
   private final Properties coreProperties;
 
+  private volatile boolean live;
+
   /**
    * <p>
    * This loader will delegate to the context classloader when possible,
@@ -399,18 +401,20 @@ public class SolrResourceLoader implemen
       throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
           "Error instantiating class: '" + clazz.getName()+"'", e, false );
     }
-    
-    if( obj instanceof SolrCoreAware ) {
-      assertAwareCompatibility( SolrCoreAware.class, obj );
-      waitingForCore.add( (SolrCoreAware)obj );
-    }
-    if( obj instanceof ResourceLoaderAware ) {
-      assertAwareCompatibility( ResourceLoaderAware.class, obj );
-      waitingForResources.add( (ResourceLoaderAware)obj );
-    }
-    if (obj instanceof SolrInfoMBean){
-      //TODO: Assert here?
-      infoMBeans.add((SolrInfoMBean) obj);
+
+    if (!live) {
+      if( obj instanceof SolrCoreAware ) {
+        assertAwareCompatibility( SolrCoreAware.class, obj );
+        waitingForCore.add( (SolrCoreAware)obj );
+      }
+      if( obj instanceof ResourceLoaderAware ) {
+        assertAwareCompatibility( ResourceLoaderAware.class, obj );
+        waitingForResources.add( (ResourceLoaderAware)obj );
+      }
+      if (obj instanceof SolrInfoMBean){
+        //TODO: Assert here?
+        infoMBeans.add((SolrInfoMBean) obj);
+      }
     }
     return obj;
   }
@@ -431,12 +435,16 @@ public class SolrResourceLoader implemen
       throw new SolrException( SolrException.ErrorCode.SERVER_ERROR,
           "Error instantiating class: '" + clazz.getName()+"'", e, false );
     }
-    //TODO: Does SolrCoreAware make sense here since in a multi-core context
-    // which core are we talking about ? 
-    if( obj instanceof ResourceLoaderAware ) {
-      assertAwareCompatibility( ResourceLoaderAware.class, obj );
-      waitingForResources.add( (ResourceLoaderAware)obj );
+
+    if (!live) {
+      //TODO: Does SolrCoreAware make sense here since in a multi-core context
+      // which core are we talking about ?
+      if( obj instanceof ResourceLoaderAware ) {
+        assertAwareCompatibility( ResourceLoaderAware.class, obj );
+        waitingForResources.add( (ResourceLoaderAware)obj );
+      }
     }
+
     return obj;
   }
 
@@ -460,18 +468,21 @@ public class SolrResourceLoader implemen
           "Error instantiating class: '" + clazz.getName()+"'", e, false );
     }
 
-    if( obj instanceof SolrCoreAware ) {
-      assertAwareCompatibility( SolrCoreAware.class, obj );
-      waitingForCore.add( (SolrCoreAware)obj );
-    }
-    if( obj instanceof ResourceLoaderAware ) {
-      assertAwareCompatibility( ResourceLoaderAware.class, obj );
-      waitingForResources.add( (ResourceLoaderAware)obj );
-    }
-    if (obj instanceof SolrInfoMBean){
-      //TODO: Assert here?
-      infoMBeans.add((SolrInfoMBean) obj);
+    if (!live) {
+      if( obj instanceof SolrCoreAware ) {
+        assertAwareCompatibility( SolrCoreAware.class, obj );
+        waitingForCore.add( (SolrCoreAware)obj );
+      }
+      if( obj instanceof ResourceLoaderAware ) {
+        assertAwareCompatibility( ResourceLoaderAware.class, obj );
+        waitingForResources.add( (ResourceLoaderAware)obj );
+      }
+      if (obj instanceof SolrInfoMBean){
+        //TODO: Assert here?
+        infoMBeans.add((SolrInfoMBean) obj);
+      }
     }
+
     return obj;
   }
 
@@ -482,10 +493,24 @@ public class SolrResourceLoader implemen
   public void inform(SolrCore core) 
   {
     this.dataDir = core.getDataDir();
-    for( SolrCoreAware aware : waitingForCore ) {
-      aware.inform( core );
+
+    // make a copy to avoid potential deadlock of a callback calling newInstance and trying
to
+    // add something to waitingForCore.
+    SolrCoreAware[] arr;
+
+    while (waitingForCore.size() > 0) {
+      synchronized (waitingForCore) {
+        arr = waitingForCore.toArray(new SolrCoreAware[waitingForCore.size()]);
+        waitingForCore.clear();
+      }
+
+      for( SolrCoreAware aware : arr) {
+        aware.inform( core );
+      }
     }
-    waitingForCore.clear();
+
+    // this is the last method to be called in SolrCore before the latch is released.
+    live = true;
   }
   
   /**
@@ -493,10 +518,20 @@ public class SolrResourceLoader implemen
    */
   public void inform( ResourceLoader loader ) 
   {
-    for( ResourceLoaderAware aware : waitingForResources ) {
-      aware.inform( loader );
+
+     // make a copy to avoid potential deadlock of a callback adding to the list
+    ResourceLoaderAware[] arr;
+
+    while (waitingForResources.size() > 0) {
+      synchronized (waitingForResources) {
+        arr = waitingForResources.toArray(new ResourceLoaderAware[waitingForResources.size()]);
+        waitingForResources.clear();
+      }
+
+      for( ResourceLoaderAware aware : arr) {
+        aware.inform(loader);
+      }
     }
-    waitingForResources.clear();
   }
 
   /**
@@ -504,10 +539,21 @@ public class SolrResourceLoader implemen
    * @param infoRegistry The Info Registry
    */
   public void inform(Map<String, SolrInfoMBean> infoRegistry) {
-    for (SolrInfoMBean bean : infoMBeans) {
+    // this can currently happen concurrently with requests starting and lazy components
+    // loading.  Make sure infoMBeans doesn't change.
+
+    SolrInfoMBean[] arr;
+    synchronized (infoMBeans) {
+      arr = infoMBeans.toArray(new SolrInfoMBean[infoMBeans.size()]);
+      waitingForResources.clear();
+    }
+
+
+    for (SolrInfoMBean bean : arr) {
       infoRegistry.put(bean.getName(), bean);
     }
   }
+  
   /**
    * Determines the solrhome from the environment.
    * Tries JNDI (java:comp/env/solr/home) then system property (solr.solr.home);



Mime
View raw message