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 (+4 lines)
Lines 16-21 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;
Lines 62-71 Link Here
62
	public void stop(BundleContext context) throws Exception {
63
	public void stop(BundleContext context) throws Exception {
63
		savePluginPreferences();
64
		savePluginPreferences();
64
		
65
		
66
		((ModelManagerImpl) ModelManagerImpl.getInstance()).removePreferenceListener();
67
65
		TaskScanningScheduler.shutdown();
68
		TaskScanningScheduler.shutdown();
66
69
67
		FileBufferModelManager.shutdown();
70
		FileBufferModelManager.shutdown();
68
71
72
69
		super.stop(context);
73
		super.stop(context);
70
	}
74
	}
71
75
(-)src/org/eclipse/wst/sse/core/internal/model/ModelManagerImpl.java (-13 / +170 lines)
Lines 40-45 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.QualifiedName;
46
import org.eclipse.core.runtime.QualifiedName;
Lines 47-55 Link Here
47
import org.eclipse.core.runtime.content.IContentDescription;
48
import org.eclipse.core.runtime.content.IContentDescription;
48
import org.eclipse.core.runtime.jobs.ILock;
49
import org.eclipse.core.runtime.jobs.ILock;
49
import org.eclipse.core.runtime.jobs.Job;
50
import org.eclipse.core.runtime.jobs.Job;
51
import org.eclipse.core.runtime.preferences.ConfigurationScope;
52
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
53
import org.eclipse.core.runtime.preferences.IPreferencesService;
54
import org.eclipse.core.runtime.preferences.IScopeContext;
55
import org.eclipse.core.runtime.preferences.InstanceScope;
56
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
50
import org.eclipse.jface.text.BadLocationException;
57
import org.eclipse.jface.text.BadLocationException;
51
import org.eclipse.jface.text.IDocument;
58
import org.eclipse.jface.text.IDocument;
52
import org.eclipse.jface.text.IRegion;
59
import org.eclipse.jface.text.IRegion;
60
import org.eclipse.osgi.util.NLS;
53
import org.eclipse.text.edits.MultiTextEdit;
61
import org.eclipse.text.edits.MultiTextEdit;
54
import org.eclipse.text.edits.ReplaceEdit;
62
import org.eclipse.text.edits.ReplaceEdit;
55
import org.eclipse.text.edits.TextEdit;
63
import org.eclipse.text.edits.TextEdit;
Lines 96-101 Link Here
96
 */
104
 */
97
public class ModelManagerImpl implements IModelManager {
105
public class ModelManagerImpl implements IModelManager {
98
106
107
	private static int WAIT_DELAY = getInt("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad");
108
	private static boolean ALLOW_INTERRUPT_WAITING_THREAD = getBoolean("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad");
109
	private static IEclipsePreferences.IPreferenceChangeListener LISTENER;
110
	static {
111
		InstanceScope scope = new InstanceScope();
112
		IEclipsePreferences instancePrefs = scope.getNode(SSECorePlugin.ID);
113
		LISTENER = new IEclipsePreferences.IPreferenceChangeListener() {
114
115
					public void preferenceChange(PreferenceChangeEvent event) {
116
117
				if ("modelmanager.maxWaitDuringConcurrentLoad".equals(event.getKey())) {
118
					WAIT_DELAY = getInt("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad");
119
				}
120
				else if ("modelmanager.allowInterruptsDuringConcurrentLoad".equals(event.getKey())) {
121
					ALLOW_INTERRUPT_WAITING_THREAD = getBoolean("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad");
122
				}
123
			}
124
		};
125
		instancePrefs.addPreferenceChangeListener(LISTENER);
126
	}
127
99
	static class ReadEditType {
128
	static class ReadEditType {
100
		ReadEditType(String type) {
129
		ReadEditType(String type) {
101
		}
130
		}
Lines 109-115 Link Here
109
		int referenceCountForRead;
138
		int referenceCountForRead;
110
		IStructuredModel theSharedModel;
139
		IStructuredModel theSharedModel;
111
		boolean initializing = true;
140
		boolean initializing = true;
112
		boolean doWait = true;
141
		volatile boolean doWait = true;
142
		final Object loadLock = new Object();
113
		
143
		
114
		SharedObject(IStructuredModel sharedModel) {
144
		SharedObject(IStructuredModel sharedModel) {
115
			theSharedModel = sharedModel;
145
			theSharedModel = sharedModel;
Lines 124-136 Link Here
124
		 * is up-to-date.
154
		 * is up-to-date.
125
		 */
155
		 */
126
		public synchronized void waitForLoadAttempt() {
156
		public synchronized void waitForLoadAttempt() {
127
			while(initializing) {
157
			long start = System.currentTimeMillis();
158
			// Note: A WAIT_DELAY of 0 is infinite
159
			int maxTimeMs = Math.max(0, WAIT_DELAY);
160
			final int waitInterval = Math.min(250, maxTimeMs);
161
			boolean interrupted = false;
162
			while (initializing && maxTimeMs >= 0) {
128
				try {
163
				try {
129
					wait();
164
					wait(waitInterval);
165
					maxTimeMs -= waitInterval;
130
				}
166
				}
131
				catch (InterruptedException e) {
167
				catch (InterruptedException e) {
132
					// ignore interruption!
168
					interrupted = true;
169
					if (ALLOW_INTERRUPT_WAITING_THREAD) {
170
						break;
171
					}
172
				}
173
			}
174
			if (initializing) {
175
				long totalWaitTime = System.currentTimeMillis() - start;
176
				if (interrupted) {
177
					throw new OperationCanceledException(
178
							"Waiting thread interrupted during simultenous model load. Load aborted. (Waited "
179
									+ totalWaitTime + "ms)");
133
				}
180
				}
181
				else {
182
					throw new OperationCanceledException(
183
							"Waiting thread timed-out during simultenous model load. Load aborted. (Waited "
184
									+ totalWaitTime + "ms)");
185
				}
186
			}
187
			if (interrupted) {
188
				// Propagate (don't swallow) the interrupt
189
				Thread.currentThread().interrupt();
134
			}
190
			}
135
		}
191
		}
136
		
192
		
Lines 166-171 Link Here
166
		return instance;
222
		return instance;
167
	}
223
	}
168
224
225
	public void removePreferenceListener() {
226
		InstanceScope scope = new InstanceScope();
227
		IEclipsePreferences instancePrefs = scope.getNode(SSECorePlugin.ID);
228
		instancePrefs.removePreferenceChangeListener(LISTENER);
229
	}
230
169
	/**
231
	/**
170
	 * Our cache of managed objects
232
	 * Our cache of managed objects
171
	 */
233
	 */
Lines 183-191 Link Here
183
	ModelManagerImpl() {
245
	ModelManagerImpl() {
184
		super();
246
		super();
185
		fManagedObjects = new HashMap();
247
		fManagedObjects = new HashMap();
186
		// To prevent deadlocks:  always acquire multiple locks in this order: SYNC, sharedObject. 
248
		/**
187
		// DO NOT acquire a SYNC within a sharedObject lock, unless you already own the SYNC lock
249
		 * NOTES: To prevent deadlocks: always acquire multiple locks in this
188
		// Tip: Try to hold the smallest number of locks you can
250
		 * order: SYNC->sharedObject.loadLock->sharedObject DO NOT acquire a
251
		 * SYNC within a sharedObject lock, unless you already own the SYNC lock
252
		 * Tip: Try to hold the smallest number of locks you can
253
		 */
189
	}
254
	}
190
255
191
	private IStructuredModel _commonCreateModel(IFile file, String id, IModelHandler handler, URIResolver resolver, ReadEditType rwType, EncodingRule encodingRule) throws IOException,CoreException {
256
	private IStructuredModel _commonCreateModel(IFile file, String id, IModelHandler handler, URIResolver resolver, ReadEditType rwType, EncodingRule encodingRule) throws IOException,CoreException {
Lines 262-268 Link Here
262
			SharedObject sharedObject) throws CoreException, IOException {
327
			SharedObject sharedObject) throws CoreException, IOException {
263
		// XXX: Does not integrate with FileBuffers
328
		// XXX: Does not integrate with FileBuffers
264
		boolean doRemove = false;
329
		boolean doRemove = false;
265
		synchronized(sharedObject) {
330
		synchronized (sharedObject.loadLock) {
266
			InputStream inputStream = null;
331
			InputStream inputStream = null;
267
			IStructuredModel model = null;
332
			IStructuredModel model = null;
268
			try {
333
			try {
Lines 283-291 Link Here
283
				}
348
				}
284
			}
349
			}
285
			if (model != null) {
350
			if (model != null) {
351
				synchronized (sharedObject) {
286
				// add to our cache
352
				// add to our cache
287
				sharedObject.theSharedModel=model;
353
				sharedObject.theSharedModel=model;
288
				_initCount(sharedObject, rwType);
354
				_initCount(sharedObject, rwType);
355
				}
289
			} else {
356
			} else {
290
				doRemove = true;
357
				doRemove = true;
291
			}
358
			}
Lines 348-354 Link Here
348
			URIResolver resolver, ReadEditType rwType, String encoding, String lineDelimiter,
415
			URIResolver resolver, ReadEditType rwType, String encoding, String lineDelimiter,
349
			SharedObject sharedObject) throws IOException {
416
			SharedObject sharedObject) throws IOException {
350
		boolean doRemove = false;
417
		boolean doRemove = false;
351
		synchronized(sharedObject) {
418
		synchronized (sharedObject.loadLock) {
352
			IStructuredModel model = null;
419
			IStructuredModel model = null;
353
			try {
420
			try {
354
				model = _commonCreateModel(id, handler, resolver);
421
				model = _commonCreateModel(id, handler, resolver);
Lines 380-388 Link Here
380
						((AbstractStructuredModel) model).setContentTypeIdentifier(description.getContentType().getId());
447
						((AbstractStructuredModel) model).setContentTypeIdentifier(description.getContentType().getId());
381
					}
448
					}
382
				}
449
				}
383
450
				synchronized (sharedObject) {
384
				sharedObject.theSharedModel = model;
451
				sharedObject.theSharedModel = model;
385
				_initCount(sharedObject, rwType);
452
				_initCount(sharedObject, rwType);
453
				}
386
			} else {
454
			} else {
387
				doRemove = true;
455
				doRemove = true;
388
			}
456
			}
Lines 492-504 Link Here
492
560
493
	private void _doCommonGetModel(IFile file, String id, SharedObject sharedObject,ReadEditType rwType) {
561
	private void _doCommonGetModel(IFile file, String id, SharedObject sharedObject,ReadEditType rwType) {
494
		boolean doRemove = false;
562
		boolean doRemove = false;
495
		synchronized(sharedObject) {
563
		synchronized (sharedObject.loadLock) {
496
			sharedObject.doWait=false;
564
			sharedObject.doWait=false;
497
			IStructuredModel model = FileBufferModelManager.getInstance().getModel(file);
565
			IStructuredModel model = FileBufferModelManager.getInstance().getModel(file);
498
			sharedObject.doWait=true;
566
			sharedObject.doWait=true;
499
			if (model != null) {
567
			if (model != null) {
568
				synchronized (sharedObject) {
500
				sharedObject.theSharedModel=model;
569
				sharedObject.theSharedModel=model;
501
				_initCount(sharedObject, rwType);
570
				_initCount(sharedObject, rwType);
571
				}
502
			} else {
572
			} else {
503
				doRemove = true;
573
				doRemove = true;
504
			}
574
			}
Lines 582-591 Link Here
582
				sharedObject = new SharedObject(null);
652
				sharedObject = new SharedObject(null);
583
				fManagedObjects.put(id, sharedObject);
653
				fManagedObjects.put(id, sharedObject);
584
				SYNC.release();
654
				SYNC.release();
585
				synchronized(sharedObject) {
655
				synchronized (sharedObject.loadLock) {
586
					sharedObject.theSharedModel = FileBufferModelManager.getInstance().getModel(document);
656
					IStructuredModel model = FileBufferModelManager.getInstance()
657
							.getModel(document);
658
					synchronized (sharedObject) {
659
						sharedObject.theSharedModel = model;
587
					_initCount(sharedObject, accessType);
660
					_initCount(sharedObject, accessType);
588
					sharedObject.setLoaded();
661
					sharedObject.setLoaded();
662
					}
589
				}
663
				}
590
				break;
664
				break;
591
			} else if (sharedObject == testObject) {
665
			} else if (sharedObject == testObject) {
Lines 2098-2101 Link Here
2098
			SYNC.release();
2172
			SYNC.release();
2099
			return inUse;
2173
			return inUse;
2100
		}
2174
		}
2175
2176
	private static String getProperty(String property) {
2177
		// Preference overrides system property overrides env-var
2178
2179
		IPreferencesService preferencesService = Platform.getPreferencesService();
2180
		IScopeContext[] lookupOrder = new IScopeContext[] {
2181
				new InstanceScope(), new ConfigurationScope()
2182
		};
2183
		String key = property;
2184
		if (property != null && property.startsWith(SSECorePlugin.ID)) {
2185
			// +1, include the "."
2186
			key = property.substring(SSECorePlugin.ID.length() + 1, property.length());
2187
		}
2188
		String value = preferencesService.getString(SSECorePlugin.ID, key, null, lookupOrder);
2189
		if (value == null) {
2190
			value = System.getProperty(property);
2191
		}
2192
		if (value == null) {
2193
			value = System.getenv(property);
2194
		}
2195
		return value;
2196
	}
2197
2198
	private static String getDefault(String property) {
2199
		// this is the "default-default"
2200
		if ("org.eclipse.wst.sse.core.modelmanager.maxWaitDuringConcurrentLoad".equals(property)) {
2201
			return "0";
2202
		}
2203
		else if ("org.eclipse.wst.sse.core.modelmanager.allowInterruptsDuringConcurrentLoad"
2204
				.equals(property)) {
2205
			return "false";
2206
		}
2207
		return null;
2208
	}
2209
2210
	private static boolean getBoolean(String key) {
2211
		String property = getProperty(key);
2212
		// if (property != null) {
2213
		//			System.out.println("Tweak: " + key + "=" + Boolean.parseBoolean(property)); //$NON-NLS-1$ //$NON-NLS-2$
2214
		// }
2215
		return property != null ? Boolean.parseBoolean(property) : Boolean
2216
				.parseBoolean(getDefault(key));
2217
	}
2218
2219
	private static int getInt(String key) {
2220
		String property = getProperty(key);
2221
		int size = 0;
2222
		if (property != null) {
2223
			try {
2224
				size = Integer.parseInt(property);
2225
				//	System.out.println("Tweak: " + key + "=" + size); //$NON-NLS-1$ //$NON-NLS-2$
2226
			}
2227
			catch (NumberFormatException e) {
2228
				size = getDefaultInt(key, property, size);
2229
			}
2230
		}
2231
		else {
2232
			size = getDefaultInt(key, property, size);
2233
		}
2234
		return size;
2235
	}
2236
2237
	private static int getDefaultInt(String key, String property, int size) {
2238
		// ignored
2239
		try {
2240
			size = Integer.parseInt(getDefault(key));
2241
		}
2242
		catch (NumberFormatException e1) {
2243
			handleIntParseException(key, property, e1);
2244
			size = 0;
2245
		}
2246
		return size;
2247
	}
2248
2249
	private static void handleIntParseException(String key, String property,
2250
			NumberFormatException e1) {
2251
		Exception n = new Exception(
2252
				NLS
2253
						.bind(
2254
								"Exception during parse of default value for key ''{0}'' value was ''{1}''. Using 0 instead", //$NON-NLS-1$
2255
								key, property), e1);
2256
		n.printStackTrace();
2257
	}
2101
}
2258
}

Return to bug 287096