From 7672ba3b843c737d9f282c71551330913d47ee0a Mon Sep 17 00:00:00 2001 From: Christian Walther Date: Tue, 10 Jun 2014 11:00:25 +0200 Subject: [PATCH] Bug 436060 - Race condition in updateProjectDescriptions() Before calling setProjectDescription() with a description that was obtained earlier without contiguous protection by an appropriate scheduling rule, check whether it is still current, otherwise changes to the project made by others in the meantime may get overwritten. Change-Id: I5d739116f2b83525a19187b3cc396e857865440a Signed-off-by: Christian Walther Reviewed-on: https://git.eclipse.org/r/27463 Tested-by: Hudson CI Reviewed-by: Andrew Gvozdev Tested-by: Andrew Gvozdev --- .../model/CProjectDescriptionManager.java | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java index 91f171da0de..617ed549468 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2013 Intel Corporation and others. + * Copyright (c) 2007, 2014 Intel 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 @@ -11,6 +11,7 @@ * IBM Corporation * James Blackburn (Broadcom Corp.) * Alex Blewitt Bug 132511 - nature order not preserved + * Christian Walther (Indel AG) - [436060] Race condition in updateProjectDescriptions() *******************************************************************************/ package org.eclipse.cdt.internal.core.settings.model; @@ -537,12 +538,16 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { IWorkspace wsp = ResourcesPlugin.getWorkspace(); if(projects == null) projects = wsp.getRoot().getProjects(); - final ICProjectDescription dess[] = new ICProjectDescription[projects.length]; + final ICProjectDescription dessWritable[] = new ICProjectDescription[projects.length]; + final ICProjectDescription dessCache[] = new ICProjectDescription[projects.length]; int num = 0; for (IProject project : projects) { ICProjectDescription des = getProjectDescription(project, false, true); - if(des != null) - dess[num++] = des; + if (des != null) { + dessWritable[num] = des; + dessCache[num] = getProjectDescription(project, false, false); + num++; + } } if(num != 0){ @@ -554,12 +559,19 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { public void run(IProgressMonitor monitor) throws CoreException { monitor.beginTask(SettingsModelMessages.getString("CProjectDescriptionManager.13"), fi[0]); //$NON-NLS-1$ - for (ICProjectDescription des : dess) { - if(des == null) - break; + for (int i = 0; i < fi[0]; i++) { + ICProjectDescription des = dessWritable[i]; + ICProjectDescription desCache = dessCache[i]; IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1); try { - setProjectDescription(des.getProject(), des, true, subMonitor); + // Only apply the project description if it is still current, otherwise: + // - someone else must already have called setProjectDescription, so there is + // nothing to do + // - we might overwrite someone else's changes with our older description + if (desCache == getProjectDescription(des.getProject(), false, + false)) { + setProjectDescription(des.getProject(), des, true, subMonitor); + } } catch (CoreException e){ CCorePlugin.log(e); } finally {