Bug 289670 - Concurrency issues in XMLParser.acquireXMLParsing()
Summary: Concurrency issues in XMLParser.acquireXMLParsing()
Status: RESOLVED FIXED
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: p2 (show other bugs)
Version: 3.5   Edit
Hardware: All All
: P3 major (vote)
Target Milestone: 3.5.2   Edit
Assignee: Simon Kaegi CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed
Depends on: 289480
Blocks:
  Show dependency tree
 
Reported: 2009-09-16 21:44 EDT by Pascal Rapicault CLA
Modified: 2010-01-05 15:32 EST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pascal Rapicault CLA 2009-09-16 21:44:20 EDT
+++ This bug was initially created as a clone of Bug #289480 +++

I am running builds with Buckminster. This uses multiple MetadataRepositoryIO
instances in concurrent threads to read repository metadata from various p2
repo locations. From time to time, I run into the following exception:

org.eclipse.equinox.internal.provisional.p2.core.ProvisionException: Unable to
read repository at
http://svn.exxcellent.de/projects/orchideo/common/integration/trunk/site/content.jar.
         at
org.eclipse.equinox.internal.p2.metadata.repository.MetadataRepositoryIO.read(MetadataRepositoryIO.java:73)
         at
org.eclipse.buckminster.pde.internal.EclipseImportReaderType.getVersionFinder(EclipseImportReaderType.java:506)
        at
org.eclipse.buckminster.core.rmap.model.Provider.findMatch(Provider.java:234)
         at
org.eclipse.buckminster.core.rmap.model.SearchPath.getProvider(SearchPath.java:103)
         at
org.eclipse.buckminster.core.rmap.model.ResourceMap.resolve(ResourceMap.java:321)
         at
org.eclipse.buckminster.core.rmap.model.ResourceMap.resolve(ResourceMap.java:232)
         at
org.eclipse.buckminster.core.resolver.ResourceMapResolver.innerResolve(ResourceMapResolver.java:232)
         at
org.eclipse.buckminster.core.resolver.ResolverNodeWithJob.resolve(ResolverNodeWithJob.java:227)
         at
org.eclipse.buckminster.core.resolver.ResolverNodeWithJob.run(ResolverNodeWithJob.java:102)
         at
org.eclipse.buckminster.core.resolver.ResolverNodeWithJob$NodeResolutionJob.run(ResolverNodeWithJob.java:49)
         at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
 Caused by: java.io.IOException: Unable to acquire a SAX parser service.
         at
org.eclipse.equinox.internal.p2.metadata.repository.MetadataRepositoryIO$Parser.parse(MetadataRepositoryIO.java:206)
         at
org.eclipse.equinox.internal.p2.metadata.repository.MetadataRepositoryIO.read(MetadataRepositoryIO.java:55)
         ... 10 more

The root cause of the "Unable to acquire a SAX parser service" exception is a
bit obscured by the fact that the MetadataRepositoryIO$Parser.parse() method
erases the original stack trace by just passing on the exception message. But
anyway, it just _can't_ be that there is no SAXParserFactory in one out of 20
invocations of the exact same code.

I tracked the problem down to the call to XMLParser.acquireXMLParsing(). In the
debugger, I was able to reproduce the exception by provoking a race condition
between to concurrently executing threads. It goes like this:

    1 private static SAXParserFactory acquireXMLParsing(BundleContext context)
{
    2     if (xmlTracker == null) {
    3         xmlTracker = new ServiceTracker(context,
SAXParserFactory.class.getName(), null);
    4         xmlTracker.open();
    5     }
    6     return (SAXParserFactory) xmlTracker.getService();
    7 }

Both threads execute line 2, which evaluates to true, and continue to line 3.
Now thread 1 executes lines 3, 4, and 5. Now we switch to thread 2, execute
line 3. Now back to thread 1, which executes line 6. At this point, the static
xmlTracker member refers to a new ServiceTracker that has not yet been
open()ed. The call to getService() thus returns null and provokes the exception
I observed.

I think the initialization of the xmlTracker member must be synchronized.
Comment 1 Pascal Rapicault CLA 2009-09-16 21:44:55 EDT
Let's consider that for 3.5.2.
Comment 2 Thomas Hallgren CLA 2009-09-17 02:17:07 EDT
Achim, if you want a fix for this in 3.5.1, a workaround could be to add a synchronization around the call in Buckminster. We have our RC4 (+2) dead-line today so there is still time.
Comment 3 Simon Kaegi CLA 2010-01-05 15:32:34 EST
Committed patch from bug 289480 and tagged.
Marking fixed.