[364482] A race condition could occur in Server code
diff --git a/features/org.eclipse.wst.server_core.feature.patch/buildnotes_org.eclipse.wst.server_core.feature.patch.html b/features/org.eclipse.wst.server_core.feature.patch/buildnotes_org.eclipse.wst.server_core.feature.patch.html
index 0226ed5..bbe43e8 100644
--- a/features/org.eclipse.wst.server_core.feature.patch/buildnotes_org.eclipse.wst.server_core.feature.patch.html
+++ b/features/org.eclipse.wst.server_core.feature.patch/buildnotes_org.eclipse.wst.server_core.feature.patch.html
@@ -4,17 +4,17 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Build" content="Build">
- <title>WTP 3.2.2 Patches</title>
+ <title>WTP 3.2.5 Patches</title>
</head>
<body>
-<h1>WTP 3.2.2 Patches</h1>
+<h1>WTP 3.2.5 Patches</h1>
<h2>Feature Patched: org.eclipse.wst.server_core.feature</h2>
<h3>Plugin(s) replaced:</h3>
<ul><li>org.eclipse.wst.server.core</li></ul>
-<p>Bug <a href='https://bugs.eclipse.org/327247'>327247</a>. Deadlock during debugging</p>
+<p>Bug <a href='https://bugs.eclipse.org/364482'>364482</a>. A race condition could occur in Server code</p>
</body></html>
\ No newline at end of file
diff --git a/features/org.eclipse.wst.server_core.feature.patch/feature.properties b/features/org.eclipse.wst.server_core.feature.patch/feature.properties
index 40eb625..c44afc3 100644
--- a/features/org.eclipse.wst.server_core.feature.patch/feature.properties
+++ b/features/org.eclipse.wst.server_core.feature.patch/feature.properties
@@ -27,7 +27,7 @@
description=\
Contains fixes described in the following bugzilla(s):\n\
\n\
-Bug https://bugs.eclipse.org/327247 Deadlock during debugging\n\
+Bug https://bugs.eclipse.org/364482 A race condition could occur in Server code\n\
\n\
# "copyright" property - text of the "Feature Update Copyright"
copyright=\
diff --git a/features/org.eclipse.wst.server_core.feature.patch/feature.xml b/features/org.eclipse.wst.server_core.feature.patch/feature.xml
index 46c2bad..e148ee8 100644
--- a/features/org.eclipse.wst.server_core.feature.patch/feature.xml
+++ b/features/org.eclipse.wst.server_core.feature.patch/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.wst.server_core.feature.patch"
label="%featureName"
- version="3.2.2.qualifier"
+ version="3.2.5.qualifier"
provider-name="%providerName">
<description>%description</description>
@@ -12,7 +12,7 @@
<license url="%licenseURL">%license</license>
<requires>
- <import feature="org.eclipse.wst.server_core.feature" version="3.2.2.v20100908-30F8V8s734C3I3K" patch="true"/>
+ <import feature="org.eclipse.wst.server_core.feature" version="3.2.5.v20110729_1202-30F8_8s7355463Ha2845" patch="true"/>
</requires>
<plugin
diff --git a/plugins/org.eclipse.wst.server.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.server.core/META-INF/MANIFEST.MF
index a2d43e2..0350d2b 100644
--- a/plugins/org.eclipse.wst.server.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.wst.server.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.wst.server.core; singleton:=true
-Bundle-Version: 1.1.208.qualifier
+Bundle-Version: 1.1.209.qualifier
Bundle-Activator: org.eclipse.wst.server.core.internal.ServerPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
index 11670be..cdedc84 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/Server.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * Copyright (c) 2003, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -83,6 +83,9 @@
// the list of modules that are to be published to the server
protected List<IModule> modules;
+
+ /** A lock that is used to synchronize access to modules. */
+ protected final Object modulesLock = new Object();
// the list of external modules
protected List<IModule> externalModules;
@@ -923,22 +926,28 @@
if (getModules().length < 0)
return false;
- // shallow search: check for root modules first
- boolean deployed = modules.contains(requestedModule);
+ boolean deployed = false;
- if(!deployed){
- // deep search: look into all the child modules
- Iterator<IModule> itr = modules.iterator();
- while(itr.hasNext() && !deployed){
- IModule[] m = new IModule[] {itr.next()};
- deployed = !visitModule(m, new IModuleVisitor(){
- public boolean visit(IModule[] modules2) {
- for (int i =0;i<=modules2.length-1;i++){
- if (modules2[i].equals(requestedModule))
- return false;
- }
- return true;
- }}, null);
+ synchronized (modulesLock){
+ // shallow search: check for root modules first
+ if (modules != null){
+ deployed = modules.contains(requestedModule);
+
+ if(!deployed){
+ // deep search: look into all the child modules
+ Iterator<IModule> itr = modules.iterator();
+ while(itr.hasNext() && !deployed){
+ IModule[] m = new IModule[] {itr.next()};
+ deployed = !visitModule(m, new IModuleVisitor(){
+ public boolean visit(IModule[] modules2) {
+ for (int i =0;i<=modules2.length-1;i++){
+ if (modules2[i].equals(requestedModule))
+ return false;
+ }
+ return true;
+ }}, null);
+ }
+ }
}
}
@@ -2361,7 +2370,9 @@
serverSyncState = wc.serverSyncState;
//restartNeeded = wc.restartNeeded;
serverType = wc.serverType;
- modules = wc.modules;
+ synchronized(modulesLock){
+ modules = wc.modules;
+ }
// can never modify the following properties via the working copy
//serverState = wc.serverState;
@@ -2427,13 +2438,26 @@
}
public void clearModuleCache() {
- modules = null;
+ synchronized (modulesLock){
+ modules = null;
+ }
}
/* (non-Javadoc)
* @see org.eclipse.wst.server.core.IServer#getModules()
*/
public IModule[] getModules() {
+ synchronized (modulesLock){
+ return getModulesWithoutLock();
+ }
+ }
+
+ /* (non-Javadoc)
+ * The implementation for getModules but this one does not lock the modules object. Caller is responsible for locking the modulesLock
+ * object when calling this method for thread safe implementation.
+ * @see org.eclipse.wst.server.core.IServer#getModules()
+ */
+ protected IModule[] getModulesWithoutLock() {
if (modules == null) {
// convert from attribute
List<String> list = getAttribute(MODULE_LIST, (List<String>) null);
diff --git a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java
index cb88a6a..671b1a0 100644
--- a/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java
+++ b/plugins/org.eclipse.wst.server.core/servercore/org/eclipse/wst/server/core/internal/ServerWorkingCopy.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * Copyright (c) 2003, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -553,51 +553,53 @@
wch.setDirty(true);
// trigger load of modules list
- getModules();
-
- if (add != null) {
- int size = add.length;
- for (int i = 0; i < size; i++) {
- if (!modules.contains(add[i])) {
- modules.add(add[i]);
- resetState(new IModule[] { add[i] }, monitor);
+ synchronized (modulesLock){
+ getModulesWithoutLock();
+ if (add != null) {
+ int size = add.length;
+ for (int i = 0; i < size; i++) {
+ if (!modules.contains(add[i])) {
+ modules.add(add[i]);
+ resetState(new IModule[] { add[i] }, monitor);
+ }
}
}
- }
-
- if (remove != null) {
- int size = remove.length;
- externalModules = getExternalModules();
- for (int i = 0; i < size; i++) {
- if (modules.contains(remove[i])) {
- modules.remove(remove[i]);
- resetState(new IModule[] { remove[i] }, monitor);
- }
- if (externalModules != null && externalModules.contains(remove[i])) {
- externalModules.remove(remove[i]);
- resetState(new IModule[] { remove[i] }, monitor);
+
+ if (remove != null) {
+ int size = remove.length;
+ externalModules = getExternalModules();
+ for (int i = 0; i < size; i++) {
+ if (modules.contains(remove[i])) {
+ modules.remove(remove[i]);
+ resetState(new IModule[] { remove[i] }, monitor);
+ }
+ if (externalModules != null && externalModules.contains(remove[i])) {
+ externalModules.remove(remove[i]);
+ resetState(new IModule[] { remove[i] }, monitor);
+ }
}
}
- }
-
- // convert to attribute
- List<String> list = new ArrayList<String>();
- Iterator iterator = modules.iterator();
- while (iterator.hasNext()) {
- IModule module = (IModule) iterator.next();
- StringBuffer sb = new StringBuffer(module.getName());
- sb.append("::");
- sb.append(module.getId());
- IModuleType mt = module.getModuleType();
- if (mt != null) {
+
+ // convert to attribute
+ List<String> list = new ArrayList<String>();
+ Iterator iterator = modules.iterator();
+ while (iterator.hasNext()) {
+ IModule module = (IModule) iterator.next();
+ StringBuffer sb = new StringBuffer(module.getName());
sb.append("::");
- sb.append(mt.getId());
- sb.append("::");
- sb.append(mt.getVersion());
+ sb.append(module.getId());
+ IModuleType mt = module.getModuleType();
+ if (mt != null) {
+ sb.append("::");
+ sb.append(mt.getId());
+ sb.append("::");
+ sb.append(mt.getVersion());
+ }
+ list.add(sb.toString());
}
- list.add(sb.toString());
+ setAttribute(MODULE_LIST, list);
}
- setAttribute(MODULE_LIST, list);
+
resetOptionalPublishOperations();
resetPreferredPublishOperations();
} catch (CoreException ce) {