Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-dev] AbstractIndexerTask.parseLinkages

The test PDOMProvidersTests.testCommonSDK occasionally fails. I‘ve narrowed the problem to code related to AbstractIndexerTask.LocationTask and FileVersionTask. I don’t understand what they are trying to do. Here is a description of what I've observed.

It is difficult to force the failure, but I'm able to trigger the race condition with the proper application of breakpoints.

The start of this test case has two lines:

ICProject cproject= CProjectHelper.createCCProject("foo" + System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject.getProject(), new Path("/this.h"), "class A {};\n\n");

This will always trigger a PDOMRebuildTask (since a new project is being added) but it will also sometimes trigger an extra PDOMIndexerTask. The behaviour depends on whether the core.resources plugin has time to send a ResourceDelta between these calls. If only one delta is sent then CDT only uses a PDOMRebuildTask. If two deltas are sent, then processing of the second delta creates a second PDOMIndexerTask.

In the problem case, the second task arrives (PDOMManager.enqueue) as the PDOMRebuildTask is still running. In this case that update is handled by the PDOMRebuildTask as an “urgent task”.

PDOMRebuildTask processes it's own file updates and creates a LocationTask for the updated file “header.hh”. When that file is processed, LocationTask.fStoredAVersion is set to true.

Next it processes files from the urgent task, which creates a new FileVersionTask in that same LocationTask. This new instance of FileVersionTask is initialized with fOutdated set to true.

Then #parseLinkage has three sections that try to parse the file.

1) “// First parse the required sources”: does nothing because the fKind is ONE_LINKAGE_HEADER.

2) “// Files with context”: calls #parseVersionInContext which calls #findContextFile which returns null because ctxFile.getParsedInContext() is null.

3) “// Files without context”: does nothing because locTask.needsVersion() returns false (since LocationTask.fStoredAVersion is true).

This means that the final part of the method runs and deletes the header.hh file from the index.

This is bad. It removes header.hh (which was added by the original PDOMRebuildTask handling) and also ignores the header.hh that was passed in by this urgent task.

I have different ideas for fixes:

[A] LocationTask.addVersionTask could clear the fStoredAVersion flag if it modifies the fVersionTasks list. However, that flag seems to be intentionally named to not change in this way.

[B] #parseVersionInContext could call FileVersionTask#setUpdated if the file is not going to be parsed. However, I'm not sure what will happen in cases where the file really is out of date and does need to be removed.

[C] PDOMManager.enqueue could be changed to stop offering new tasks to the currently running task. This would avoid cases where tasks are accepting new work in the middle of existing work.


Back to the top