From 77f495900a5689b9e2992fc2ffb74ca21993cb1d Mon Sep 17 00:00:00 2001 From: cbateman Date: Wed, 24 Nov 2010 18:23:46 +0000 Subject: [bug 330937] Apply patch. --- .../core/internal/registry/FaceletTagRegistry.java | 100 +++++++++++++++------ .../internal/registry/LibraryOperationFactory.java | 24 ++--- 2 files changed, 82 insertions(+), 42 deletions(-) diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.core/src/org/eclipse/jst/jsf/facelet/core/internal/registry/FaceletTagRegistry.java b/jsf/plugins/org.eclipse.jst.jsf.facelet.core/src/org/eclipse/jst/jsf/facelet/core/internal/registry/FaceletTagRegistry.java index 16f782b66..559f953e3 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.facelet.core/src/org/eclipse/jst/jsf/facelet/core/internal/registry/FaceletTagRegistry.java +++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.core/src/org/eclipse/jst/jsf/facelet/core/internal/registry/FaceletTagRegistry.java @@ -16,6 +16,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.ILock; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; @@ -54,7 +55,8 @@ public final class FaceletTagRegistry extends AbstractTagRegistry implements private final FaceletDocumentFactory _factory; private final LibraryOperationFactory _operationFactory = new LibraryOperationFactory( this); - private boolean _isInitialized; + private final ILock _lock = Job.getJobManager().newLock(); + private volatile boolean _isInitialized; private ChangeJob _changeJob; private MyTaglibListener _listener; @@ -100,28 +102,54 @@ public final class FaceletTagRegistry extends AbstractTagRegistry implements * the containned objects are not copies. */ @Override - public synchronized Collection getAllTagLibraries() + public Collection getAllTagLibraries() { - final Set allTagLibraries = new HashSet(); - if (!_isInitialized) - { - try - { - initialize(false); - _isInitialized = true; - } - catch (final JavaModelException e) - { - FaceletCorePlugin.log("Problem during initialization", e); //$NON-NLS-1$ - } - catch (final CoreException e) - { - FaceletCorePlugin.log("Problem during initialization", e); //$NON-NLS-1$ - } - } - allTagLibraries.addAll(_nsResolved.values()); - allTagLibraries.addAll(_unResolved); - return allTagLibraries; + boolean setEndRule = false; + try { + final Set allTagLibraries = new HashSet(); + + if (!_isInitialized) + { + // preemptive project rule setting here ensures consistent lock ordering + // and gives the opportunity for the other thread having the project lock + // to finish before we enter synchronization block created with reentrant + // lock below + // NOTE: it is essential to have _lock.acquire() after project rule start + // NOTE: if current thread already has any rule, do not start project rule + if(Job.getJobManager().currentRule() == null){ + Job.getJobManager().beginRule(_project, null); + setEndRule = true; + } + _lock.acquire(); + + // double check after sync block if no one else entered "if(!_isInitialized)" + if(!_isInitialized){ + try + { + initialize(false); + _isInitialized = true; + } + catch (final JavaModelException e) + { + FaceletCorePlugin.log("Problem during initialization", e); //$NON-NLS-1$ + } + catch (final CoreException e) + { + FaceletCorePlugin.log("Problem during initialization", e); //$NON-NLS-1$ + } + } + }else{ + _lock.acquire(); + } + allTagLibraries.addAll(_nsResolved.values()); + allTagLibraries.addAll(_unResolved); + return allTagLibraries; + } finally { + _lock.release(); + if (setEndRule){ + Job.getJobManager().endRule(_project); + } + } } private void initialize(boolean fireEvent) throws JavaModelException, CoreException @@ -195,7 +223,7 @@ public final class FaceletTagRegistry extends AbstractTagRegistry implements } @Override - public synchronized Namespace getTagLibrary(final String uri) + public Namespace getTagLibrary(final String uri) { // TODO: getAllTagLibraries(); @@ -214,9 +242,14 @@ public final class FaceletTagRegistry extends AbstractTagRegistry implements // { // JSFCoreTraceOptions.log("FaceletTagRegistry.refresh: start"); //$NON-NLS-1$ // } - - synchronized (FaceletTagRegistry.this) + boolean setEndRule = false; + try { + if(Job.getJobManager().currentRule() == null){ + Job.getJobManager().beginRule(_project, null); + setEndRule = true; + } + _lock.acquire(); if (JSFCoreTraceOptions.TRACE_JSPTAGREGISTRY) { JSFCoreTraceOptions @@ -262,6 +295,11 @@ public final class FaceletTagRegistry extends AbstractTagRegistry implements // .log("TLDTagRegistry.refresh: finished"); // } return Status.OK_STATUS; + } finally { + _lock.release(); + if (setEndRule){ + Job.getJobManager().endRule(_project); + } } } }; @@ -303,13 +341,20 @@ public final class FaceletTagRegistry extends AbstractTagRegistry implements public ChangeJob(final String projectName) { super("Update job for project " + projectName); //$NON-NLS-1$ + // preemptive project rule setting here ensures consistent lock ordering + // and gives the opportunity for the other thread having the project lock + // to finish before we enter synchronization block created with reentrant + // lock below + // NOTE: it is essential to have _lock.acquire() after project rule start + setRule(_project); } @Override protected IStatus run(final IProgressMonitor monitor) { - synchronized (FaceletTagRegistry.this) + try { + _lock.acquire(); _rescheduleTime = -1; LibraryOperation operation = null; @@ -333,6 +378,8 @@ public final class FaceletTagRegistry extends AbstractTagRegistry implements } return multiStatus; + } finally { + _lock.release(); } } } @@ -371,4 +418,5 @@ public final class FaceletTagRegistry extends AbstractTagRegistry implements // TODO ?? } + } diff --git a/jsf/plugins/org.eclipse.jst.jsf.facelet.core/src/org/eclipse/jst/jsf/facelet/core/internal/registry/LibraryOperationFactory.java b/jsf/plugins/org.eclipse.jst.jsf.facelet.core/src/org/eclipse/jst/jsf/facelet/core/internal/registry/LibraryOperationFactory.java index c69cbfed9..0346a989d 100644 --- a/jsf/plugins/org.eclipse.jst.jsf.facelet.core/src/org/eclipse/jst/jsf/facelet/core/internal/registry/LibraryOperationFactory.java +++ b/jsf/plugins/org.eclipse.jst.jsf.facelet.core/src/org/eclipse/jst/jsf/facelet/core/internal/registry/LibraryOperationFactory.java @@ -56,12 +56,9 @@ class LibraryOperationFactory @Override protected IStatus doRun() { - synchronized (_tagRegistry) - { - // fire change event if applicable - _tagRegistry.initialize(_changeRecord, true); - return Status.OK_STATUS; - } + // fire change event if applicable + _tagRegistry.initialize(_changeRecord, true); + return Status.OK_STATUS; } } @@ -100,18 +97,13 @@ class LibraryOperationFactory @Override protected IStatus doRun() { - IStatus result = null; + IStatus result = new RemoveTagLibrary(_tagRegistry, _changeRecord).doRun(); - synchronized (_tagRegistry) + if (result.getSeverity() != IStatus.ERROR + && result.getSeverity() != IStatus.CANCEL) { - result = new RemoveTagLibrary(_tagRegistry, _changeRecord).doRun(); - - if (result.getSeverity() != IStatus.ERROR - && result.getSeverity() != IStatus.CANCEL) - { - result = new AddTagLibrary(_tagRegistry, _changeRecord) - .doRun(); - } + result = new AddTagLibrary(_tagRegistry, _changeRecord) + .doRun(); } return result; -- cgit v1.2.3