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 308120 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/wst/sse/core/internal/model/ModelManagerImpl.java (-54 / +53 lines)
Lines 41-46 Link Here
41
import org.eclipse.core.runtime.IPath;
41
import org.eclipse.core.runtime.IPath;
42
import org.eclipse.core.runtime.IStatus;
42
import org.eclipse.core.runtime.IStatus;
43
import org.eclipse.core.runtime.NullProgressMonitor;
43
import org.eclipse.core.runtime.NullProgressMonitor;
44
import org.eclipse.core.runtime.OperationCanceledException;
44
import org.eclipse.core.runtime.Path;
45
import org.eclipse.core.runtime.Path;
45
import org.eclipse.core.runtime.Platform;
46
import org.eclipse.core.runtime.Platform;
46
import org.eclipse.core.runtime.QualifiedName;
47
import org.eclipse.core.runtime.QualifiedName;
Lines 103-177 Link Here
103
		}
104
		}
104
	}
105
	}
105
106
106
	/**
107
	class SharedObject {
107
	 * A Data class to track our shared objects
108
	 */
109
	 static class SharedObject {
110
		int referenceCountForEdit;
108
		int referenceCountForEdit;
111
		int referenceCountForRead;
109
		int referenceCountForRead;
112
		IStructuredModel theSharedModel;
110
		volatile IStructuredModel theSharedModel;
111
		final ILock LOAD_LOCK = Job.getJobManager().newLock();
113
		volatile boolean initializing = true;
112
		volatile boolean initializing = true;
114
		volatile boolean doWait = true;
113
		volatile boolean doWait = true;
115
		
114
		// The field 'id' is only meant for debug
116
		SharedObject(IStructuredModel sharedModel) {
115
		volatile String id;
117
			theSharedModel = sharedModel;
116
118
			referenceCountForRead = 0;
117
		SharedObject(String id) {
119
			referenceCountForEdit = 0;
118
			this.id=id;
119
			// be aware, this lock will leak and cause the deadlock detector to be horrible if we never release it
120
			LOAD_LOCK.acquire();
120
		}
121
		}
121
		
122
122
		/**
123
		/**
123
		 * Waits until this shared object has been attempted to be loaded. 
124
		 * Waits until this shared object has been attempted to be loaded. The
124
		 * The load is "attempted" because not all loads result in a model. 
125
		 * load is "attempted" because not all loads result in a model. However,
125
		 * However, upon leaving this method, theShareModel variable
126
		 * upon leaving this method, theShareModel variable is up-to-date.
126
		 * is up-to-date.
127
		 */
127
		 */
128
		public void waitForLoadAttempt() {
128
		public void waitForLoadAttempt() {
129
			Job current = Job.getJobManager().currentJob();
129
			boolean interrupted = false;
130
			boolean interrupted = false;
130
			try {
131
			try {
131
				// if we have a rule, then use a polling system with
132
				while (initializing) {
132
				// short-circuit, otherwise use wait/notify
133
					if (current!=null) {
133
				if (Job.getJobManager().currentRule() != null) {
134
						current.yieldRule(null);
134
					while (initializing) {
135
						Job.getJobManager().currentJob().yieldRule(null);
136
						synchronized (this) {
137
							if (initializing) {
138
								try {
139
									wait(WAIT_INTERVAL_MS);
140
								}
141
								catch (InterruptedException e) {
142
									interrupted = true;
143
								}
144
							}
145
						}
146
					}
135
					}
147
				}
136
					try {
148
				else {
137
						loop();
149
					synchronized (this) {
138
					} catch (InterruptedException e) {
150
						while (initializing) {
139
						interrupted=true;
151
							try {
152
								wait();
153
							}
154
							catch (InterruptedException e) {
155
								interrupted = true;
156
							}
157
						}
158
					}
140
					}
159
				}
141
				}
160
			}
142
			}
161
			finally {
143
			finally {
162
				if (interrupted)
144
				if (interrupted) {
163
					Thread.currentThread().interrupt();
145
					Thread.currentThread().interrupt();
146
				}
164
			}
147
			}
165
		}
148
		}
166
		
149
150
		private void loop() throws InterruptedException {	
151
			if (initializing) {
152
				if (LOAD_LOCK.acquire(WAIT_INTERVAL_MS)) {
153
					// if we got the lock, but initializing is still not true the deadlock detector gave us
154
					// the lock and caused reentrancy into this critical section. This is invalid and the 
155
					// sign of a cyclical load attempt. In this case, we through an 
156
					// OperationCanceledException in lew of entering a spin-loop. 
157
					if (initializing) {
158
						LOAD_LOCK.release();
159
						throw new OperationCanceledException("Aborted cyclic load attempt for model with id: "+ id);
160
					} else {
161
						LOAD_LOCK.release();
162
					}
163
				}
164
			}
165
		}
166
167
		/**
167
		/**
168
		 * Flags this model as loaded. All waiting methods on 
168
		 * Flags this model as loaded. All waiting methods on
169
		 * {@link #waitForLoadAttempt()} will proceed after this 
169
		 * {@link #waitForLoadAttempt()} will proceed after this method returns.
170
		 * method returns. 
171
		 */
170
		 */
172
		public synchronized void setLoaded() {
171
		public void setLoaded() {
173
			initializing = false;
172
			initializing = false;
174
			notifyAll();
173
			LOAD_LOCK.release();
175
		}
174
		}
176
	}
175
	}
177
176
Lines 239-245 Link Here
239
			SharedObject testObject = (SharedObject) fManagedObjects.get(id);
238
			SharedObject testObject = (SharedObject) fManagedObjects.get(id);
240
			if (testObject==null) {
239
			if (testObject==null) {
241
				// null means it's been disposed, we need to do the work to reload it.
240
				// null means it's been disposed, we need to do the work to reload it.
242
				sharedObject = new SharedObject(null);
241
				sharedObject = new SharedObject(id);
243
				fManagedObjects.put(id, sharedObject);
242
				fManagedObjects.put(id, sharedObject);
244
				SYNC.release();
243
				SYNC.release();
245
				_doCommonCreateModel(file, id, handler, resolver, rwType, encodingRule,
244
				_doCommonCreateModel(file, id, handler, resolver, rwType, encodingRule,
Lines 350-356 Link Here
350
			SharedObject testObject = (SharedObject) fManagedObjects.get(id);
349
			SharedObject testObject = (SharedObject) fManagedObjects.get(id);
351
			if (testObject==null) {
350
			if (testObject==null) {
352
				// it was removed ,so lets create it
351
				// it was removed ,so lets create it
353
				sharedObject = new SharedObject(null);
352
				sharedObject = new SharedObject(id);
354
				fManagedObjects.put(id, sharedObject);
353
				fManagedObjects.put(id, sharedObject);
355
				SYNC.release();
354
				SYNC.release();
356
				_doCommonCreateModel(inputStream, id, handler, resolver, rwType,
355
				_doCommonCreateModel(inputStream, id, handler, resolver, rwType,
Lines 493-499 Link Here
493
				SharedObject testObject = (SharedObject) fManagedObjects.get(id);
492
				SharedObject testObject = (SharedObject) fManagedObjects.get(id);
494
				if (testObject==null) {
493
				if (testObject==null) {
495
					// it was removed ,so lets create it
494
					// it was removed ,so lets create it
496
					sharedObject = new SharedObject(null);
495
					sharedObject = new SharedObject(id);
497
					fManagedObjects.put(id, sharedObject);
496
					fManagedObjects.put(id, sharedObject);
498
					
497
					
499
					SYNC.release();
498
					SYNC.release();
Lines 569-575 Link Here
569
				throw new ResourceInUse();
568
				throw new ResourceInUse();
570
			}
569
			}
571
			
570
			
572
			sharedObject = new SharedObject(null);
571
			sharedObject = new SharedObject(id);
573
			fManagedObjects.put(id, sharedObject);
572
			fManagedObjects.put(id, sharedObject);
574
			
573
			
575
		} finally {
574
		} finally {
Lines 614-620 Link Here
614
			SYNC.acquire();
613
			SYNC.acquire();
615
			SharedObject testObject = (SharedObject) fManagedObjects.get(id);
614
			SharedObject testObject = (SharedObject) fManagedObjects.get(id);
616
			if (testObject==null) {
615
			if (testObject==null) {
617
				sharedObject = new SharedObject(null);
616
				sharedObject = new SharedObject(id);
618
				fManagedObjects.put(id, sharedObject);
617
				fManagedObjects.put(id, sharedObject);
619
				SYNC.release();
618
				SYNC.release();
620
				synchronized(sharedObject) {
619
				synchronized(sharedObject) {
Lines 832-838 Link Here
832
			if (sharedObject != null) {
831
			if (sharedObject != null) {
833
				throw new ResourceInUse();
832
				throw new ResourceInUse();
834
			}
833
			}
835
			sharedObject = new SharedObject(null);
834
			sharedObject = new SharedObject(newId);
836
			fManagedObjects.put(newId,sharedObject);
835
			fManagedObjects.put(newId,sharedObject);
837
		} finally {
836
		} finally {
838
			SYNC.release();
837
			SYNC.release();

Return to bug 308120