View | Details | Raw Unified | Return to bug 126121 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/core/internal/events/BuildDescription.java (+41 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.core.internal.events;
12
13
import org.eclipse.core.resources.IBuildConfiguration;
14
import org.eclipse.core.resources.IBuildContext;
15
16
import org.eclipse.core.resources.IBuildDescription;
17
18
/**
19
 * 
20
 */
21
public class BuildDescription implements IBuildDescription {
22
23
	private IBuildContext buildContext;
24
	
25
	private IBuildConfiguration buildConfiguration;
26
	
27
	public BuildDescription(IBuildContext buildContext, IBuildConfiguration buildConfiguration) {
28
		super();
29
		this.buildContext = buildContext;
30
		this.buildConfiguration = buildConfiguration;
31
	}
32
	
33
	public IBuildContext getBuildContext() {
34
		return buildContext;
35
	}
36
37
	public IBuildConfiguration getBuildConfiguration() {
38
		return buildConfiguration;
39
	}
40
41
}
(-)src/org/eclipse/core/internal/events/BuildManager.java (-23 / +92 lines)
Lines 14-19 Link Here
14
 *******************************************************************************/
14
 *******************************************************************************/
15
package org.eclipse.core.internal.events;
15
package org.eclipse.core.internal.events;
16
16
17
import org.eclipse.core.runtime.Status;
18
19
import org.eclipse.core.resources.IncrementalProjectBuilder;
20
17
import java.util.*;
21
import java.util.*;
18
import org.eclipse.core.internal.dtree.DeltaDataTree;
22
import org.eclipse.core.internal.dtree.DeltaDataTree;
19
import org.eclipse.core.internal.resources.*;
23
import org.eclipse.core.internal.resources.*;
Lines 134-145 Link Here
134
138
135
	private void basicBuild(int trigger, IncrementalProjectBuilder builder, Map<String,String> args, MultiStatus status, IProgressMonitor monitor) {
139
	private void basicBuild(int trigger, IncrementalProjectBuilder builder, Map<String,String> args, MultiStatus status, IProgressMonitor monitor) {
136
		try {
140
		try {
137
			currentBuilder = builder;
141
//			currentBuilder = builder;
142
			InternalBuilder currentBuilder2 = builder;
138
			//clear any old requests to forget built state
143
			//clear any old requests to forget built state
139
			currentBuilder.clearLastBuiltStateRequests();
144
//			currentBuilder.clearLastBuiltStateRequests();
145
			currentBuilder2.clearLastBuiltStateRequests();
140
			// Figure out want kind of build is needed
146
			// Figure out want kind of build is needed
141
			boolean clean = trigger == IncrementalProjectBuilder.CLEAN_BUILD;
147
			boolean clean = trigger == IncrementalProjectBuilder.CLEAN_BUILD;
142
			currentLastBuiltTree = currentBuilder.getLastBuiltTree();
148
			currentLastBuiltTree = currentBuilder2.getLastBuiltTree();
143
149
144
			// Does the build command respond to this trigger?
150
			// Does the build command respond to this trigger?
145
			boolean isBuilding = builder.getCommand().isBuilding(trigger);
151
			boolean isBuilding = builder.getCommand().isBuilding(trigger);
Lines 167-180 Link Here
167
			ISchedulingRule rule = null;
173
			ISchedulingRule rule = null;
168
			try {
174
			try {
169
				//short-circuit if none of the projects this builder cares about have changed.
175
				//short-circuit if none of the projects this builder cares about have changed.
170
				if (!needsBuild(currentBuilder, trigger)) {
176
				if (!needsBuild(currentBuilder2, trigger)) {
171
					//use up the progress allocated for this builder
177
					//use up the progress allocated for this builder
172
					monitor.beginTask("", 1); //$NON-NLS-1$
178
					monitor.beginTask("", 1); //$NON-NLS-1$
173
					monitor.done();
179
					monitor.done();
174
					return;
180
					return;
175
				}
181
				}
176
				rule = builder.getRule(trigger, args);
182
				rule = builder.getRule(trigger, args);
177
				String name = currentBuilder.getLabel();
183
				String name = currentBuilder2.getLabel();
178
				String message;
184
				String message;
179
				if (name != null)
185
				if (name != null)
180
					message = NLS.bind(Messages.events_invoking_2, name, builder.getProject().getFullPath());
186
					message = NLS.bind(Messages.events_invoking_2, name, builder.getProject().getFullPath());
Lines 189-194 Link Here
189
				depth = getWorkManager().beginUnprotected();
195
				depth = getWorkManager().beginUnprotected();
190
				// Acquire the rule required for running this builder
196
				// Acquire the rule required for running this builder
191
				if (rule != null) {
197
				if (rule != null) {
198
//					System.out.println("starting rule " + rule.toString()); //$NON-NLS-1$
192
					Job.getJobManager().beginRule(rule, monitor);
199
					Job.getJobManager().beginRule(rule, monitor);
193
					// Now that we've acquired the rule, changes may have been made concurrently, ensure we're pointing at the 
200
					// Now that we've acquired the rule, changes may have been made concurrently, ensure we're pointing at the 
194
					// correct currentTree so delta contains concurrent changes made in areas guarded by the scheduling rule
201
					// correct currentTree so delta contains concurrent changes made in areas guarded by the scheduling rule
Lines 196-222 Link Here
196
						currentTree = workspace.getElementTree();
203
						currentTree = workspace.getElementTree();
197
				}
204
				}
198
				//do the build
205
				//do the build
199
				SafeRunner.run(getSafeRunnable(trigger, args, status, monitor));
206
				SafeRunner.run(getSafeRunnable(trigger, args, status, monitor, currentBuilder2));
200
			} finally {
207
			} finally {
201
				// Re-acquire the WS lock, then release the scheduling rule
208
				// Re-acquire the WS lock, then release the scheduling rule
202
				if (depth >= 0)
209
				if (depth >= 0)
203
					getWorkManager().endUnprotected(depth);
210
					getWorkManager().endUnprotected(depth);
204
				if (rule != null)
211
				if (rule != null)
205
					Job.getJobManager().endRule(rule);
212
					Job.getJobManager().endRule(rule);
213
//				System.out.println("end rule " + rule.toString()); //$NON-NLS-1$
206
				// Be sure to clean up after ourselves.
214
				// Be sure to clean up after ourselves.
207
				if (clean || currentBuilder.wasForgetStateRequested()) {
215
				if (clean || currentBuilder2.wasForgetStateRequested()) {
208
					currentBuilder.setLastBuiltTree(null);
216
					currentBuilder2.setLastBuiltTree(null);
209
				} else if (currentBuilder.wasRememberStateRequested()) {
217
				} else if (currentBuilder2.wasRememberStateRequested()) {
210
					// If remember last build state, and FULL_BUILD
218
					// If remember last build state, and FULL_BUILD
211
					// last tree must be set to => null for next build
219
					// last tree must be set to => null for next build
212
					if (trigger == IncrementalProjectBuilder.FULL_BUILD)
220
					if (trigger == IncrementalProjectBuilder.FULL_BUILD)
213
						currentBuilder.setLastBuiltTree(null);
221
						currentBuilder2.setLastBuiltTree(null);
214
					// else don't modify the last built tree
222
					// else don't modify the last built tree
215
				} else {
223
				} else {
216
					// remember the current state as the last built state.
224
					// remember the current state as the last built state.
217
					ElementTree lastTree = workspace.getElementTree();
225
					ElementTree lastTree = workspace.getElementTree();
218
					lastTree.immutable();
226
//					lastTree.immutable();
219
					currentBuilder.setLastBuiltTree(lastTree);
227
					currentBuilder2.setLastBuiltTree(lastTree);
220
				}
228
				}
221
				hookEndBuild(builder);
229
				hookEndBuild(builder);
222
			}
230
			}
Lines 234-240 Link Here
234
				checkCanceled(trigger, monitor);
242
				checkCanceled(trigger, monitor);
235
				BuildCommand command = (BuildCommand) commands[i];
243
				BuildCommand command = (BuildCommand) commands[i];
236
				IProgressMonitor sub = Policy.subMonitorFor(monitor, 1);
244
				IProgressMonitor sub = Policy.subMonitorFor(monitor, 1);
237
				IncrementalProjectBuilder builder = getBuilder(buildConfiguration, command, i, status, context);
245
//				IncrementalProjectBuilder builder = getBuilder(buildConfiguration, command, i, status, context);
246
				IncrementalProjectBuilder builder;
247
				if(IncrementalProjectBuilder.PARALLEL_FULL_BUILD == trigger) {
248
					builder = getParallelBuilder(buildConfiguration, command, i, status, context);
249
				} else {
250
					builder = getBuilder(buildConfiguration, command, i, status, context);
251
				}
238
				if (builder != null)
252
				if (builder != null)
239
					basicBuild(trigger, builder, command.getArguments(false), status, sub);
253
					basicBuild(trigger, builder, command.getArguments(false), status, sub);
240
			}
254
			}
Lines 511-517 Link Here
511
	 * The outermost workspace operation has finished.  Do an autobuild if necessary.
525
	 * The outermost workspace operation has finished.  Do an autobuild if necessary.
512
	 */
526
	 */
513
	public void endTopLevel(boolean needsBuild) {
527
	public void endTopLevel(boolean needsBuild) {
514
		autoBuildJob.build(needsBuild);
528
//		autoBuildJob.build(needsBuild);
515
	}
529
	}
516
530
517
	/**
531
	/**
Lines 694-700 Link Here
694
	/**
708
	/**
695
	 * Returns the safe runnable instance for invoking a builder
709
	 * Returns the safe runnable instance for invoking a builder
696
	 */
710
	 */
697
	private ISafeRunnable getSafeRunnable(final int trigger, final Map<String, String> args, final MultiStatus status, final IProgressMonitor monitor) {
711
	private ISafeRunnable getSafeRunnable(final int trigger, final Map<String, String> args, final MultiStatus status, final IProgressMonitor monitor, final InternalBuilder currentBuilder2) {
698
		return new ISafeRunnable() {
712
		return new ISafeRunnable() {
699
			public void handleException(Throwable e) {
713
			public void handleException(Throwable e) {
700
				if (e instanceof OperationCanceledException) {
714
				if (e instanceof OperationCanceledException) {
Lines 702-719 Link Here
702
						Policy.debug("Build canceled"); //$NON-NLS-1$
716
						Policy.debug("Build canceled"); //$NON-NLS-1$
703
					//just discard built state when a builder cancels, to ensure
717
					//just discard built state when a builder cancels, to ensure
704
					//that it is called again on the very next build.
718
					//that it is called again on the very next build.
705
					currentBuilder.forgetLastBuiltState();
719
					currentBuilder2.forgetLastBuiltState();
706
					throw (OperationCanceledException) e;
720
					throw (OperationCanceledException) e;
707
				}
721
				}
708
				//ResourceStats.buildException(e);
722
				//ResourceStats.buildException(e);
709
				// don't log the exception....it is already being logged in SafeRunner#run
723
				// don't log the exception....it is already being logged in SafeRunner#run
710
724
711
				//add a generic message to the MultiStatus
725
				//add a generic message to the MultiStatus
712
				String builderName = currentBuilder.getLabel();
726
				String builderName = currentBuilder2.getLabel();
713
				if (builderName == null || builderName.length() == 0)
727
				if (builderName == null || builderName.length() == 0)
714
					builderName = currentBuilder.getClass().getName();
728
					builderName = currentBuilder2.getClass().getName();
715
				String pluginId = currentBuilder.getPluginId();
729
				String pluginId = currentBuilder2.getPluginId();
716
				String message = NLS.bind(Messages.events_builderError, builderName, currentBuilder.getProject().getName());
730
				String message = NLS.bind(Messages.events_builderError, builderName, currentBuilder2.getProject().getName());
717
				status.add(new Status(IStatus.ERROR, pluginId, IResourceStatus.BUILD_FAILED, message, e));
731
				status.add(new Status(IStatus.ERROR, pluginId, IResourceStatus.BUILD_FAILED, message, e));
718
732
719
				//add the exception status to the MultiStatus
733
				//add the exception status to the MultiStatus
Lines 725-736 Link Here
725
				IProject[] prereqs = null;
739
				IProject[] prereqs = null;
726
				//invoke the appropriate build method depending on the trigger
740
				//invoke the appropriate build method depending on the trigger
727
				if (trigger != IncrementalProjectBuilder.CLEAN_BUILD)
741
				if (trigger != IncrementalProjectBuilder.CLEAN_BUILD)
728
					prereqs = currentBuilder.build(trigger, args, monitor);
742
					prereqs = currentBuilder2.build(trigger, args, monitor);
729
				else
743
				else
730
					currentBuilder.clean(monitor);
744
					currentBuilder2.clean(monitor);
731
				if (prereqs == null)
745
				if (prereqs == null)
732
					prereqs = new IProject[0];
746
					prereqs = new IProject[0];
733
				currentBuilder.setInterestingProjects(prereqs.clone());
747
				currentBuilder2.setInterestingProjects(prereqs.clone());
734
			}
748
			}
735
		};
749
		};
736
	}
750
	}
Lines 1145-1148 Link Here
1145
			Policy.log(status);
1159
			Policy.log(status);
1146
		return workspace.getRoot();
1160
		return workspace.getRoot();
1147
	}
1161
	}
1162
1163
	public void buildParallel(IProgressMonitor subMonitorFor) {
1164
			final MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.INTERNAL_ERROR, Messages.events_errors, null);
1165
			
1166
			IProject[] projects = workspace.getRoot().getProjects(IContainer.INCLUDE_HIDDEN);
1167
			DirectedGraphs<IProject> directedGraphs = new DirectedGraphs<IProject>();
1168
			for (IProject project : projects) {
1169
				directedGraphs.addNode(new Node<IProject>(project));
1170
			}
1171
			for (IProject project : projects) {
1172
				if (!project.isAccessible())
1173
					continue;
1174
				ProjectDescription desc = ((Project)project).internalGetDescription();
1175
				if (desc == null)
1176
					continue;
1177
				IProject[] refs = desc.getAllReferences(false);
1178
				Node<IProject> node = directedGraphs.getNodeWithContent(project);
1179
				for (IProject referencedProject : refs) {
1180
					Node<IProject> node2 = directedGraphs.getNodeWithContent(referencedProject);
1181
					if(node2 != null) {
1182
						node2.addOutgoingEdge(node);
1183
					}
1184
				}
1185
			}
1186
			ThreadPoolBuilder threadPoolBuilder = new ThreadPoolBuilder();
1187
			try {
1188
				IBuildExecutor buildExecutor = new IBuildExecutor() {
1189
				public void executeBuild(IBuildDescription buildDescription) {
1190
					NullProgressMonitor progressMonitor = new NullProgressMonitor();
1191
					basicBuild(buildDescription.getBuildConfiguration(), IncrementalProjectBuilder.PARALLEL_FULL_BUILD, buildDescription.getBuildContext(), status, progressMonitor);
1192
				}};
1193
				threadPoolBuilder.run(directedGraphs, buildExecutor);
1194
			} catch (InterruptedException e) {
1195
				status.add(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, Messages.events_errors, e));
1196
			}
1197
	}
1198
	
1199
	private IncrementalProjectBuilder getParallelBuilder(IBuildConfiguration buildConfiguration, BuildCommand command, int buildSpecIndex, MultiStatus status, IBuildContext buildContext) throws CoreException {
1200
		// always construct a new builder for parallel builds (think about pooling here)
1201
		InternalBuilder result = initializeBuilder(command.getBuilderName(), buildConfiguration, buildSpecIndex, status);
1202
		command.setBuilders(result);
1203
		result.setCommand(command);
1204
		result.setBuildConfig(buildConfiguration);
1205
		result.startupOnInitialize();
1206
		//		}
1207
		
1208
		if (!validateNature(result, command.getBuilderName())) {
1209
					//skip this builder and null its last built tree because it is invalid
1210
					//if the nature gets added or re-enabled a full build will be triggered
1211
					result.setLastBuiltTree(null);
1212
					return null;
1213
				}
1214
				return (IncrementalProjectBuilder) result;
1215
			}
1216
1148
}
1217
}
(-)src/org/eclipse/core/internal/events/BuildRunnable.java (+34 lines)
Added Link Here
1
package org.eclipse.core.internal.events;
2
3
import java.util.ArrayList;
4
import java.util.List;
5
import java.util.concurrent.BlockingQueue;
6
import org.eclipse.core.internal.resources.BuildConfiguration;
7
import org.eclipse.core.resources.IProject;
8
9
public final class BuildRunnable<T> implements Runnable {
10
	
11
	private final Node<IProject> currentNode;
12
	private final BlockingQueue<Node<IProject>> queue;
13
	private final IBuildExecutor executor;
14
15
	protected BuildRunnable(Node<IProject> currentNode, BlockingQueue<Node<IProject>> queue, IBuildExecutor executor) {
16
		this.currentNode = currentNode;
17
		this.queue = queue;
18
		this.executor = executor;
19
	}
20
	
21
	public void run() {
22
			System.out.println("start compile " + currentNode.getContent()); //$NON-NLS-1$
23
			BuildDescription buildDescription = new BuildDescription(null, new BuildConfiguration(currentNode.getContent()));
24
			executor.executeBuild(buildDescription);
25
			System.out.println("end compile " + currentNode.getContent()); //$NON-NLS-1$
26
			List<Node<IProject>> outgoingNodes = new ArrayList<Node<IProject>>(currentNode.getOutgoingEdges()); 
27
			currentNode.removeAllOutgoingEdges();
28
				for (Node<IProject> node : outgoingNodes) {
29
					if(node.getIncomingEdges().isEmpty()) {
30
						queue.add(node);
31
					}
32
				}
33
	}
34
}
(-)src/org/eclipse/core/internal/events/DirectedGraphs.java (+58 lines)
Added Link Here
1
package org.eclipse.core.internal.events;
2
3
import java.util.Collection;
4
import java.util.Collections;
5
import java.util.HashSet;
6
import java.util.LinkedHashSet;
7
import java.util.Set;
8
9
/**
10
 * A directed graph holds all nodes. Nodes need not be connected which is why a container object is required
11
 * 
12
 * @author jens
13
 *
14
 */
15
public class DirectedGraphs<T> {
16
	
17
	private Set<Node<T>> nodes;
18
19
	public DirectedGraphs() {
20
		nodes = Collections.synchronizedSet(new HashSet<Node<T>>());
21
	}
22
	
23
	public void addNode(Node<T> node) {
24
		nodes.add(node);
25
	}
26
27
	public void removeNode(Node<T> node) {
28
		nodes.remove(node);
29
	}
30
	
31
	public void addAll(Collection<Node<T>> nodesToBeAdded) {
32
		nodes.addAll(nodesToBeAdded);
33
	}
34
	
35
	public Node<T> getNodeWithContent(T content) {
36
		for (Node<T> node : nodes) {
37
			if(content.equals(node.getContent())) {
38
				return node;
39
			}
40
		}
41
		return null;
42
	}
43
	
44
	public synchronized Set<Node<T>> getRootNodes() {
45
		Set<Node<T>> set = new LinkedHashSet<Node<T>>();
46
		for (Node<T> node : nodes) {
47
			if(node.getIncomingEdges().isEmpty()) {
48
				set.add(node);
49
			}
50
		}
51
		return set;
52
	}
53
	
54
	public boolean isEmtpy() {
55
		return nodes.isEmpty();
56
	}
57
58
}
(-)src/org/eclipse/core/internal/events/IBuildExecutor.java (+23 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.core.internal.events;
12
13
import org.eclipse.core.resources.IBuildDescription;
14
15
16
/**
17
 * 
18
 */
19
public interface IBuildExecutor {
20
	
21
	public void executeBuild(IBuildDescription buildDescription);
22
23
}
(-)src/org/eclipse/core/internal/events/Node.java (+129 lines)
Added Link Here
1
package org.eclipse.core.internal.events;
2
3
import java.text.MessageFormat;
4
5
import java.util.Collections;
6
import java.util.Iterator;
7
import java.util.LinkedHashSet;
8
import java.util.Set;
9
10
/**
11
 * A simple node object having references to other node objects 
12
 *
13
 * @param <T>
14
 */
15
public class Node<T> {
16
	
17
	private Set<Node<T>> incomingEdges;
18
19
	private Set<Node<T>> outgoingEdges;
20
	
21
	private T content;
22
	
23
	public Node(T content) {
24
		this.content = content;
25
		incomingEdges = Collections.synchronizedSet(new LinkedHashSet<Node<T>>()); 
26
		outgoingEdges = Collections.synchronizedSet(new LinkedHashSet<Node<T>>()); 
27
	}
28
	
29
	public T getContent() {
30
		return content;
31
	}
32
33
	public void setContent(T content) {
34
		this.content = content;
35
	}
36
37
	public synchronized Set<Node<T>> getIncomingEdges() {
38
		return incomingEdges;
39
	}
40
41
	public synchronized Set<Node<T>> getOutgoingEdges() {
42
		return outgoingEdges;
43
	}
44
45
	public synchronized void addIncomingEdge(Node<T> node) {
46
		if(!incomingEdges.contains(node)) {
47
			incomingEdges.add(node);
48
			node.addOutgoingEdge(this);
49
		}
50
	}
51
52
	public synchronized void addOutgoingEdge(Node<T> node) {
53
		if(!outgoingEdges.contains(node)) {
54
			outgoingEdges.add(node);
55
			node.addIncomingEdge(this);
56
		}
57
	}
58
	
59
	public synchronized void removeOutgoingEdge(Node<T> node) {
60
		if(outgoingEdges.contains(node)) {
61
			outgoingEdges.remove(node);
62
			node.removeIncomingEdge(this);
63
		}
64
	}
65
	
66
	public synchronized void removeIncomingEdge(Node<T> node) {
67
		if(incomingEdges.contains(node)) {
68
			incomingEdges.remove(node);
69
			node.removeOutgoingEdge(this);
70
		}
71
	}
72
73
	public synchronized void removeAllOutgoingEdges() {
74
		for (Iterator<Node<T>> iterator = outgoingEdges.iterator(); iterator.hasNext();) {
75
			Node<T> node = iterator.next();
76
			node.internalRemoveIncomingEdge(this);
77
			iterator.remove();
78
		}
79
	}
80
81
	public synchronized void removeAllIncomingEdges() {
82
		for (Iterator<Node<T>> iterator = incomingEdges.iterator(); iterator.hasNext();) {
83
			Node<T> node = iterator.next();
84
			node.internalRemoveOutgoingEdge(this);
85
			iterator.remove();
86
		}
87
	}
88
89
	synchronized void internalRemoveOutgoingEdge(Node<T> node) {
90
		outgoingEdges.remove(node);
91
	}
92
93
	synchronized void internalRemoveIncomingEdge(Node<T> node) {
94
		incomingEdges.remove(node);
95
	}
96
97
	@Override
98
	public int hashCode() {
99
		final int prime = 31;
100
		int result = 1;
101
		result = prime * result + ((content == null) ? 0 : content.hashCode());
102
		return result;
103
	}
104
105
	@Override
106
	public boolean equals(Object obj) {
107
		if (this == obj)
108
			return true;
109
		if (obj == null)
110
			return false;
111
		if (getClass() != obj.getClass())
112
			return false;
113
		Node other = (Node) obj;
114
		if (content == null) {
115
			if (other.content != null)
116
				return false;
117
		} else if (!content.equals(other.content))
118
			return false;
119
		return true;
120
	}
121
122
	@Override
123
	public String toString() {
124
		return MessageFormat.format("Node [content={0}]", content); //$NON-NLS-1$
125
	}
126
127
	
128
	
129
}
(-)src/org/eclipse/core/internal/events/ThreadPoolBuilder.java (+29 lines)
Added Link Here
1
package org.eclipse.core.internal.events;
2
3
import java.util.concurrent.*;
4
import org.eclipse.core.resources.IProject;
5
6
public class ThreadPoolBuilder {
7
	
8
	private ExecutorService threadPool;
9
	
10
	private BlockingQueue<Node<IProject>> queue;
11
12
	public ThreadPoolBuilder() {
13
		threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() - 1);
14
		queue = new ArrayBlockingQueue<Node<IProject>>(6000);
15
	}
16
	
17
	public void run(DirectedGraphs<IProject> directedGraphs, IBuildExecutor runnable) throws InterruptedException {
18
		queue.addAll(directedGraphs.getRootNodes());
19
			while (!threadPool.isTerminated()) {
20
				if(directedGraphs.isEmtpy()) {
21
					threadPool.shutdown();
22
				} else {
23
					Node<IProject>nodeToCompile = queue.take();
24
					directedGraphs.removeNode((Node<IProject>) nodeToCompile);
25
					threadPool.execute(new BuildRunnable(nodeToCompile, queue, runnable));
26
				}
27
		}
28
	}
29
}
(-)src/org/eclipse/core/internal/resources/WorkManager.java (-2 / +18 lines)
Lines 99-106 Link Here
99
	 */
99
	 */
100
	public int beginUnprotected() {
100
	public int beginUnprotected() {
101
		int depth = lock.getDepth();
101
		int depth = lock.getDepth();
102
		for (int i = 0; i < depth; i++)
102
		for (int i = 0; i < depth; i++) {
103
			lock.release();
103
			lock.release();
104
			System.out.println("Lock released by " + Thread.currentThread().getName()); //$NON-NLS-1$
105
		}
104
		return depth;
106
		return depth;
105
	}
107
	}
106
108
Lines 115-122 Link Here
115
				String msg = Messages.resources_cannotModify;
117
				String msg = Messages.resources_cannotModify;
116
				throw new ResourceException(IResourceStatus.WORKSPACE_LOCKED, null, msg, null);
118
				throw new ResourceException(IResourceStatus.WORKSPACE_LOCKED, null, msg, null);
117
			}
119
			}
120
			if(rule != null) {
121
				System.out.println("Begin rule " + rule.toString()); //$NON-NLS-1$
122
			}
118
			jobManager.beginRule(rule, monitor);
123
			jobManager.beginRule(rule, monitor);
119
			lock.acquire();
124
			lock.acquire();
125
			System.out.println("Lock aquired by " + Thread.currentThread().getName() + " Rule " + (rule == null ? "" : rule.toString())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
120
			incrementPreparedOperations();
126
			incrementPreparedOperations();
121
			success = true;
127
			success = true;
122
		} finally {
128
		} finally {
Lines 157-165 Link Here
157
			operationCanceled = hasBuildChanges = false;
163
			operationCanceled = hasBuildChanges = false;
158
		try {
164
		try {
159
			lock.release();
165
			lock.release();
166
			System.out.println("Lock released by " + Thread.currentThread().getName() + " Rule " + (rule == null ? "" : rule.toString())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
160
		} finally {
167
		} finally {
161
			//end rule in finally in case lock.release throws an exception
168
			//end rule in finally in case lock.release throws an exception
162
			jobManager.endRule(rule);
169
			jobManager.endRule(rule);
170
			if(rule != null) {
171
				System.out.println("end rule " + rule.toString()); //$NON-NLS-1$
172
			}
163
		}
173
		}
164
	}
174
	}
165
175
Lines 178-185 Link Here
178
	 * @see #beginUnprotected()
188
	 * @see #beginUnprotected()
179
	 */
189
	 */
180
	public void endUnprotected(int depth) {
190
	public void endUnprotected(int depth) {
181
		for (int i = 0; i < depth; i++)
191
		for (int i = 0; i < depth; i++) {
182
			lock.acquire();
192
			lock.acquire();
193
			System.out.println("Lock aquired by " + Thread.currentThread().getName()); //$NON-NLS-1$
194
		}
183
	}
195
	}
184
196
185
	/**
197
	/**
Lines 246-251 Link Here
246
				// before
258
				// before
247
				result = lock.getDepth() > 1;
259
				result = lock.getDepth() > 1;
248
				lock.release();
260
				lock.release();
261
				System.out.println("Lock released by " + Thread.currentThread().getName()); //$NON-NLS-1$
249
			}
262
			}
250
		} catch (InterruptedException e) {
263
		} catch (InterruptedException e) {
251
			// ignore
264
			// ignore
Lines 300-305 Link Here
300
	public void startup(IProgressMonitor monitor) {
313
	public void startup(IProgressMonitor monitor) {
301
		jobManager.beginRule(workspace.getRoot(), monitor);
314
		jobManager.beginRule(workspace.getRoot(), monitor);
302
		lock.acquire();
315
		lock.acquire();
316
		System.out.println("Lock aquired by " + Thread.currentThread().getName()); //$NON-NLS-1$
303
	}
317
	}
304
318
305
	/**
319
	/**
Lines 310-315 Link Here
310
	void postWorkspaceStartup() {
324
	void postWorkspaceStartup() {
311
		try {
325
		try {
312
			lock.release();
326
			lock.release();
327
			System.out.println("Lock released by " + Thread.currentThread().getName()); //$NON-NLS-1$
328
313
		} finally {
329
		} finally {
314
			//end rule in finally in case lock.release throws an exception
330
			//end rule in finally in case lock.release throws an exception
315
			jobManager.endRule(workspace.getRoot());
331
			jobManager.endRule(workspace.getRoot());
(-)src/org/eclipse/core/internal/resources/Workspace.java (-2 / +2 lines)
Lines 363-370 Link Here
363
	public void beginOperation(boolean createNewTree) throws CoreException {
363
	public void beginOperation(boolean createNewTree) throws CoreException {
364
		WorkManager workManager = getWorkManager();
364
		WorkManager workManager = getWorkManager();
365
		workManager.incrementNestedOperations();
365
		workManager.incrementNestedOperations();
366
		if (!workManager.isBalanced())
366
//		if (!workManager.isBalanced())
367
			Assert.isTrue(false, "Operation was not prepared."); //$NON-NLS-1$
367
//			Assert.isTrue(false, "Operation was not prepared."); //$NON-NLS-1$
368
		if (workManager.getPreparedOperationDepth() > 1) {
368
		if (workManager.getPreparedOperationDepth() > 1) {
369
			if (createNewTree && tree.isImmutable())
369
			if (createNewTree && tree.isImmutable())
370
				newWorkingTree();
370
				newWorkingTree();
(-)src/org/eclipse/core/resources/IBuildDescription.java (+22 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.core.resources;
12
13
/**
14
 * 
15
 */
16
public interface IBuildDescription {
17
	
18
	IBuildContext getBuildContext();
19
	
20
	IBuildConfiguration getBuildConfiguration();
21
22
}
(-)src/org/eclipse/core/resources/IncrementalProjectBuilder.java (-1 / +4 lines)
Lines 71-76 Link Here
71
	 * @see IWorkspace#build(int, IProgressMonitor)
71
	 * @see IWorkspace#build(int, IProgressMonitor)
72
	 */
72
	 */
73
	public static final int INCREMENTAL_BUILD = 10;
73
	public static final int INCREMENTAL_BUILD = 10;
74
	
75
	public static final int PARALLEL_FULL_BUILD = 11;
74
	/**
76
	/**
75
	 * Build kind constant (value 15) indicating a clean build request.  A clean
77
	 * Build kind constant (value 15) indicating a clean build request.  A clean
76
	 * build discards any additional state that has  been computed as a result of 
78
	 * build discards any additional state that has  been computed as a result of 
Lines 451-457 Link Here
451
	 * @since 3.6
453
	 * @since 3.6
452
	 */
454
	 */
453
	public ISchedulingRule getRule(int kind, Map<String,String> args) {
455
	public ISchedulingRule getRule(int kind, Map<String,String> args) {
454
		return getRule();
456
		return getProject();
457
//		return getRule();
455
	}
458
	}
456
459
457
	/**
460
	/**

Return to bug 126121