Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 287096 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/wst/sse/core/internal/SSECorePlugin.java (-1 / +18 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2001, 2006 IBM Corporation and others.
2
 * Copyright (c) 2001, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 16-24 Link Here
16
import org.eclipse.core.runtime.Preferences;
16
import org.eclipse.core.runtime.Preferences;
17
import org.eclipse.wst.sse.core.StructuredModelManager;
17
import org.eclipse.wst.sse.core.StructuredModelManager;
18
import org.eclipse.wst.sse.core.internal.encoding.CommonEncodingPreferenceNames;
18
import org.eclipse.wst.sse.core.internal.encoding.CommonEncodingPreferenceNames;
19
import org.eclipse.wst.sse.core.internal.model.ModelManagerImpl;
19
import org.eclipse.wst.sse.core.internal.modelhandler.ModelHandlerRegistry;
20
import org.eclipse.wst.sse.core.internal.modelhandler.ModelHandlerRegistry;
20
import org.eclipse.wst.sse.core.internal.preferences.CommonModelPreferenceNames;
21
import org.eclipse.wst.sse.core.internal.preferences.CommonModelPreferenceNames;
21
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
22
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
23
import org.eclipse.wst.sse.core.internal.tasks.TaskScanningScheduler;
22
import org.osgi.framework.BundleContext;
24
import org.osgi.framework.BundleContext;
23
25
24
26
Lines 60-65 Link Here
60
	 */
62
	 */
61
	public void stop(BundleContext context) throws Exception {
63
	public void stop(BundleContext context) throws Exception {
62
		savePluginPreferences();
64
		savePluginPreferences();
65
		
66
		((ModelManagerImpl) ModelManagerImpl.getInstance()).removePreferenceListener();
67
68
		TaskScanningScheduler.shutdown();
69
63
		FileBufferModelManager.shutdown();
70
		FileBufferModelManager.shutdown();
64
71
65
		super.stop(context);
72
		super.stop(context);
Lines 75-80 Link Here
75
82
76
		// initialize FileBuffer handling
83
		// initialize FileBuffer handling
77
		FileBufferModelManager.startup();
84
		FileBufferModelManager.startup();
85
86
		/**
87
		 * If the user starts the workbench with
88
		 * -Dorg.eclipse.wst.sse.core.taskscanner=off, the scanner should be
89
		 * disabled
90
		 */
91
		String scan = System.getProperty("org.eclipse.wst.sse.core.taskscanner"); //$NON-NLS-1$
92
		if (scan == null || !scan.equalsIgnoreCase("off")) { //$NON-NLS-1$
93
			TaskScanningScheduler.startup();
94
		}
78
	}
95
	}
79
96
80
	/**
97
	/**
(-)src/org/eclipse/wst/sse/core/internal/model/ModelManagerImpl.java (-22 / +177 lines)
Lines 40-53 Link Here
40
import org.eclipse.core.runtime.IPath;
40
import org.eclipse.core.runtime.IPath;
41
import org.eclipse.core.runtime.IStatus;
41
import org.eclipse.core.runtime.IStatus;
42
import org.eclipse.core.runtime.NullProgressMonitor;
42
import org.eclipse.core.runtime.NullProgressMonitor;
43
import org.eclipse.core.runtime.OperationCanceledException;
43
import org.eclipse.core.runtime.Path;
44
import org.eclipse.core.runtime.Path;
44
import org.eclipse.core.runtime.Platform;
45
import org.eclipse.core.runtime.Platform;
45
import org.eclipse.core.runtime.Status;
46
import org.eclipse.core.runtime.Status;
46
import org.eclipse.core.runtime.jobs.ILock;
47
import org.eclipse.core.runtime.jobs.ILock;
47
import org.eclipse.core.runtime.jobs.Job;
48
import org.eclipse.core.runtime.jobs.Job;
49
import org.eclipse.core.runtime.preferences.ConfigurationScope;
50
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
51
import org.eclipse.core.runtime.preferences.IPreferencesService;
52
import org.eclipse.core.runtime.preferences.IScopeContext;
53
import org.eclipse.core.runtime.preferences.InstanceScope;
54
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
48
import org.eclipse.jface.text.BadLocationException;
55
import org.eclipse.jface.text.BadLocationException;
49
import org.eclipse.jface.text.IDocument;
56
import org.eclipse.jface.text.IDocument;
50
import org.eclipse.jface.text.IRegion;
57
import org.eclipse.jface.text.IRegion;
58
import org.eclipse.osgi.util.NLS;
51
import org.eclipse.text.edits.MultiTextEdit;
59
import org.eclipse.text.edits.MultiTextEdit;
52
import org.eclipse.text.edits.ReplaceEdit;
60
import org.eclipse.text.edits.ReplaceEdit;
53
import org.eclipse.text.edits.TextEdit;
61
import org.eclipse.text.edits.TextEdit;
Lines 94-99 Link Here
94
 */
102
 */
95
public class ModelManagerImpl implements IModelManager {
103
public class ModelManagerImpl implements IModelManager {
96
104
105
	private static int WAIT_DELAY = getInt("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad");
106
	private static boolean ALLOW_INTERRUPT_WAITING_THREAD = getBoolean("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad");
107
	private static IEclipsePreferences.IPreferenceChangeListener LISTENER;
108
	static {
109
		InstanceScope scope = new InstanceScope();
110
		IEclipsePreferences instancePrefs = scope.getNode(SSECorePlugin.ID);
111
		LISTENER = new IEclipsePreferences.IPreferenceChangeListener() {
112
113
					public void preferenceChange(PreferenceChangeEvent event) {
114
115
				if ("modelmanager.maxWaitDuringConcurrentLoad".equals(event.getKey())) {
116
					WAIT_DELAY = getInt("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad");
117
				}
118
				else if ("modelmanager.allowInterruptsDuringConcurrentLoad".equals(event.getKey())) {
119
					ALLOW_INTERRUPT_WAITING_THREAD = getBoolean("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad");
120
				}
121
			}
122
		};
123
		instancePrefs.addPreferenceChangeListener(LISTENER);
124
	}
125
97
	static class ReadEditType {
126
	static class ReadEditType {
98
		ReadEditType(String type) {
127
		ReadEditType(String type) {
99
		}
128
		}
Lines 107-113 Link Here
107
		int referenceCountForRead;
136
		int referenceCountForRead;
108
		IStructuredModel theSharedModel;
137
		IStructuredModel theSharedModel;
109
		boolean initializing = true;
138
		boolean initializing = true;
110
		boolean doWait = true;
139
		volatile boolean doWait = true;
140
		final Object loadCondition = new Object();
111
		
141
		
112
		SharedObject(IStructuredModel sharedModel) {
142
		SharedObject(IStructuredModel sharedModel) {
113
			theSharedModel = sharedModel;
143
			theSharedModel = sharedModel;
Lines 119-133 Link Here
119
		 * Waits until this shared object has been attempted to be loaded. 
149
		 * Waits until this shared object has been attempted to be loaded. 
120
		 * The load is "attempted" because not all loads result in a model. 
150
		 * The load is "attempted" because not all loads result in a model. 
121
		 * However, upon leaving this method, theShareModel variable
151
		 * However, upon leaving this method, theShareModel variable
122
		 * is up-to-date.
152
		 * is up-to-date. Should not be called if holding a lock on this object.
123
		 */
153
		 */
124
		public synchronized void waitForLoadAttempt() {
154
		public void waitForLoadAttempt() {
125
			while(initializing) {
155
			synchronized(loadCondition) {
126
				try {
156
				long start = System.currentTimeMillis();
127
					wait();
157
				// Note: A WAIT_DELAY of 0 is infinite
158
				int maxTimeMs = Math.max(0, WAIT_DELAY);
159
				final int waitInterval = Math.min(250, maxTimeMs);
160
				boolean interrupted = false;
161
				while (initializing && maxTimeMs >= 0) {
162
					try {
163
						loadCondition.wait(waitInterval);
164
						maxTimeMs -= waitInterval;
165
					}
166
					catch (InterruptedException e) {
167
						interrupted = true;
168
						if (ALLOW_INTERRUPT_WAITING_THREAD) {
169
							break;
170
						}
171
					}
128
				}
172
				}
129
				catch (InterruptedException e) {
173
				if (initializing) {
130
					// ignore interruption!
174
					long totalWaitTime = System.currentTimeMillis() - start;
175
					if (interrupted) {
176
						throw new OperationCanceledException(
177
								"Waiting thread interrupted during simultenous model load. Load aborted. (Waited "
178
										+ totalWaitTime + "ms)");
179
					}
180
					else {
181
						throw new OperationCanceledException(
182
								"Waiting thread timed-out during simultenous model load. Load aborted. (Waited "
183
										+ totalWaitTime + "ms)");
184
					}
185
				}
186
				if (interrupted) {
187
					// Propagate (don't swallow) the interrupt
188
					Thread.currentThread().interrupt();
131
				}
189
				}
132
			}
190
			}
133
		}
191
		}
Lines 137-145 Link Here
137
		 * {@link #waitForLoadAttempt()} will proceed after this 
195
		 * {@link #waitForLoadAttempt()} will proceed after this 
138
		 * method returns. 
196
		 * method returns. 
139
		 */
197
		 */
140
		public synchronized void setLoaded() {
198
		public void setLoaded() {
141
			initializing = false;
199
			synchronized(loadCondition) {
142
			notifyAll();
200
				initializing = false;
201
				loadCondition.notifyAll();
202
			}
143
		}
203
		}
144
	}
204
	}
145
205
Lines 164-169 Link Here
164
		return instance;
224
		return instance;
165
	}
225
	}
166
226
227
	public void removePreferenceListener() {
228
		InstanceScope scope = new InstanceScope();
229
		IEclipsePreferences instancePrefs = scope.getNode(SSECorePlugin.ID);
230
		instancePrefs.removePreferenceChangeListener(LISTENER);
231
	}
232
167
	/**
233
	/**
168
	 * Our cache of managed objects
234
	 * Our cache of managed objects
169
	 */
235
	 */
Lines 181-189 Link Here
181
	ModelManagerImpl() {
247
	ModelManagerImpl() {
182
		super();
248
		super();
183
		fManagedObjects = new HashMap();
249
		fManagedObjects = new HashMap();
184
		// To prevent deadlocks:  always acquire multiple locks in this order: SYNC, sharedObject. 
250
		/**
185
		// DO NOT acquire a SYNC within a sharedObject lock, unless you already own the SYNC lock
251
		 * NOTES: To prevent deadlocks: always acquire multiple locks in this
186
		// Tip: Try to hold the smallest number of locks you can
252
		 * order: SYNC->sharedObject->sharedObject.loadCondition DO NOT acquire a
253
		 * SYNC within a sharedObject lock, unless you already own the SYNC lock
254
		 * Tip: Try to hold the smallest number of locks you can
255
		 */
187
	}
256
	}
188
257
189
	private IStructuredModel _commonCreateModel(IFile file, String id, IModelHandler handler, URIResolver resolver, ReadEditType rwType, EncodingRule encodingRule) throws IOException,CoreException {
258
	private IStructuredModel _commonCreateModel(IFile file, String id, IModelHandler handler, URIResolver resolver, ReadEditType rwType, EncodingRule encodingRule) throws IOException,CoreException {
Lines 376-382 Link Here
376
	}
445
	}
377
446
378
	private IStructuredModel _commonCreateModel(String id, IModelHandler handler, URIResolver resolver) throws ResourceInUse {
447
	private IStructuredModel _commonCreateModel(String id, IModelHandler handler, URIResolver resolver) throws ResourceInUse {
379
380
		IModelLoader loader = handler.getModelLoader();
448
		IModelLoader loader = handler.getModelLoader();
381
		IStructuredModel result = loader.createModel();
449
		IStructuredModel result = loader.createModel();
382
		// in the past, id was null for "unmanaged" case, so we won't
450
		// in the past, id was null for "unmanaged" case, so we won't
Lines 1138-1147 Link Here
1138
				// and return the object.
1206
				// and return the object.
1139
				SYNC.release();
1207
				SYNC.release();
1140
				doRelease=false;
1208
				doRelease=false;
1209
				if (sharedObject.doWait) {
1210
					sharedObject.waitForLoadAttempt();
1211
				}
1141
				synchronized(sharedObject) {
1212
				synchronized(sharedObject) {
1142
					if (sharedObject.doWait) {
1143
						sharedObject.waitForLoadAttempt();
1144
					}
1145
					if (sharedObject.theSharedModel!=null) {
1213
					if (sharedObject.theSharedModel!=null) {
1146
						_incrCount(sharedObject, EDIT);
1214
						_incrCount(sharedObject, EDIT);
1147
					}
1215
					}
Lines 1220-1230 Link Here
1220
				// and return the object.
1288
				// and return the object.
1221
				SYNC.release();
1289
				SYNC.release();
1222
				doRelease=false;
1290
				doRelease=false;
1223
1291
				if (sharedObject.doWait) {
1292
					sharedObject.waitForLoadAttempt();
1293
				}
1224
				synchronized(sharedObject) {
1294
				synchronized(sharedObject) {
1225
					if (sharedObject.doWait) {
1226
						sharedObject.waitForLoadAttempt();
1227
					}
1228
					if (sharedObject.theSharedModel!=null) {
1295
					if (sharedObject.theSharedModel!=null) {
1229
						_incrCount(sharedObject, READ);
1296
						_incrCount(sharedObject, READ);
1230
					}
1297
					}
Lines 2073-2076 Link Here
2073
			SYNC.release();
2140
			SYNC.release();
2074
			return inUse;
2141
			return inUse;
2075
		}
2142
		}
2143
2144
	private static String getProperty(String property) {
2145
		// Importance order is:
2146
		// default-default < instanceScope < configurationScope < systemProperty < envVar
2147
		String value=null;
2148
		
2149
		if (value == null) {
2150
			value = System.getenv(property);
2151
		}
2152
		if (value == null) {
2153
			value = System.getProperty(property);
2154
		}
2155
		if (value==null) {
2156
			IPreferencesService preferencesService = Platform.getPreferencesService();
2157
			IScopeContext[] lookupOrder = new IScopeContext[] {
2158
					 new ConfigurationScope(), new InstanceScope()
2159
			};
2160
			String key = property;
2161
			if (property != null && property.startsWith(SSECorePlugin.ID)) {
2162
				// +1, include the "."
2163
				key = property.substring(SSECorePlugin.ID.length() + 1, property.length());
2164
			}
2165
			preferencesService.getString(SSECorePlugin.ID, key, null, lookupOrder);
2166
		}
2167
		
2168
		return value;
2169
	}
2170
2171
	private static String getDefault(String property) {
2172
		// this is the "default-default"
2173
		if ("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad".equals(property)) {
2174
			return "0";
2175
		}
2176
		else if ("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad"
2177
				.equals(property)) {
2178
			return "false";
2179
		}
2180
		return null;
2181
	}
2182
2183
	private static boolean getBoolean(String key) {
2184
		String property = getProperty(key);
2185
		// if (property != null) {
2186
		//			System.out.println("Tweak: " + key + "=" + Boolean.parseBoolean(property)); //$NON-NLS-1$ //$NON-NLS-2$
2187
		// }
2188
		return property != null ? Boolean.parseBoolean(property) : Boolean
2189
				.parseBoolean(getDefault(key));
2190
	}
2191
2192
	private static int getInt(String key) {
2193
		String property = getProperty(key);
2194
		int size = 0;
2195
		if (property != null) {
2196
			try {
2197
				size = Integer.parseInt(property);
2198
				//	System.out.println("Tweak: " + key + "=" + size); //$NON-NLS-1$ //$NON-NLS-2$
2199
			}
2200
			catch (NumberFormatException e) {
2201
				size = getDefaultInt(key, property, size);
2202
			}
2203
		}
2204
		else {
2205
			size = getDefaultInt(key, property, size);
2206
		}
2207
		return size;
2208
	}
2209
2210
	private static int getDefaultInt(String key, String property, int size) {
2211
		// ignored
2212
		try {
2213
			size = Integer.parseInt(getDefault(key));
2214
		}
2215
		catch (NumberFormatException e1) {
2216
			handleIntParseException(key, property, e1);
2217
			size = 0;
2218
		}
2219
		return size;
2220
	}
2221
2222
	private static void handleIntParseException(String key, String property,
2223
			NumberFormatException e1) {
2224
		Exception n = new Exception(
2225
				NLS
2226
						.bind(
2227
								"Exception during parse of default value for key ''{0}'' value was ''{1}''. Using 0 instead", //$NON-NLS-1$
2228
								key, property), e1);
2229
		n.printStackTrace();
2230
	}
2076
}
2231
}

Return to bug 287096