db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r790412 - in /db/derby/code/branches/10.5: ./ java/engine/org/apache/derby/impl/services/monitor/TopService.java
Date Wed, 01 Jul 2009 22:28:19 GMT
Author: kahatlen
Date: Wed Jul  1 22:28:18 2009
New Revision: 790412

URL: http://svn.apache.org/viewvc?rev=790412&view=rev
Log:
DERBY-4018: ArrayIndexOutOfBoundsException in TopService.inService under heavy multithreaded
use of EmbeddedDriver

Merged fix from trunk (revisions 789264 and 790218).

Modified:
    db/derby/code/branches/10.5/   (props changed)
    db/derby/code/branches/10.5/java/engine/org/apache/derby/impl/services/monitor/TopService.java

Propchange: db/derby/code/branches/10.5/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jul  1 22:28:18 2009
@@ -1 +1 @@
-/db/derby/code/trunk:772090,772449,772534,774281,779681,782991,785163,785570,785662,788369,788670,788674,788968
+/db/derby/code/trunk:772090,772449,772534,774281,779681,782991,785163,785570,785662,788369,788670,788674,788968,789264,790218

Modified: db/derby/code/branches/10.5/java/engine/org/apache/derby/impl/services/monitor/TopService.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.5/java/engine/org/apache/derby/impl/services/monitor/TopService.java?rev=790412&r1=790411&r2=790412&view=diff
==============================================================================
--- db/derby/code/branches/10.5/java/engine/org/apache/derby/impl/services/monitor/TopService.java
(original)
+++ db/derby/code/branches/10.5/java/engine/org/apache/derby/impl/services/monitor/TopService.java
Wed Jul  1 22:28:18 2009
@@ -102,14 +102,11 @@
 
 	void setTopModule(Object instance) {
 		synchronized (this) {
-			for (int i = 0; i < moduleInstances.size(); i++) {
-				ModuleInstance module = (ModuleInstance) moduleInstances.elementAt(i);
-				if (module.getInstance() == instance) {
-					topModule = module;
-					notifyAll();
-					break;
-				}
-			}
+            ModuleInstance module = findModuleInstance(instance);
+            if (module != null) {
+                topModule = module;
+                notifyAll();
+            }
 
 			// now add an additional entry into the hashtable
 			// that maps the server name as seen by the user
@@ -223,6 +220,29 @@
 		return null;
 	}
 
+    /**
+     * Find a {@code ModuleInstance} object whose {@code getInstance()} method
+     * returns the object specified by the {@code instance} parameter.
+     *
+     * @param instance the instance to look for
+     * @return a {@code ModuleInstance} object, or {@code null} if no match
+     * was found
+     */
+    private ModuleInstance findModuleInstance(Object instance) {
+        // DERBY-4018: Need to hold the synchronization over the entire loop
+        // to prevent concurrent modifications from causing an
+        // ArrayIndexOutOfBoundsException.
+        synchronized (moduleInstances) {
+            for (int i = 0; i < moduleInstances.size(); i++) {
+                ModuleInstance module = (ModuleInstance) moduleInstances.get(i);
+                if (module.getInstance() == instance) {
+                    return module;
+                }
+            }
+        }
+        return null;
+    }
+
 	/**
 		Boot a module, performs three steps.
 
@@ -252,8 +272,20 @@
 		// see if a running implementation will handle this protocol
 		synchronized (this) {
 
-			for (int i = 0; i < moduleInstances.size(); i++) {
-				ModuleInstance module = (ModuleInstance) moduleInstances.elementAt(i);
+            for (int i = 0;; i++) {
+                final ModuleInstance module;
+
+                // DERBY-4018: Synchronized block in order to close the window
+                // between size() and elementAt() where the size may change
+                // and result in an ArrayIndexOutOfBoundsException.
+                synchronized (moduleInstances) {
+                    if (i < moduleInstances.size()) {
+                        module = (ModuleInstance) moduleInstances.elementAt(i);
+                    } else {
+                        // No more instances to look at, break out of the loop.
+                        break;
+                    }
+                }
 
                 // DERBY-2074: The module has not been properly booted, so we
                 // cannot yet determine whether or not this is a module we can
@@ -394,14 +426,7 @@
 	}
 
 	boolean inService(Object instance) {
-
-		for (int i = 0; i < moduleInstances.size(); i++) {
-
-			ModuleInstance mi = (ModuleInstance) moduleInstances.elementAt(i);
-			if (mi.getInstance() == instance)
-				return true;
-		}
-		return false;
+        return findModuleInstance(instance) != null;
 	}
 
 	public ProtocolKey getKey() {



Mime
View raw message