Community
Participate
Working Groups
I had difficulties with parallel loading of p2 repositories (in most cases I got "Transfer initialization error" on loading of several repositories). After deep debugging I concluded that the problem stems from the AdapterManager, method getFactories(): public HashMap getFactories() { // avoid the synchronize if we don't have to call it if (lazyFactoryProviders.size() == 0) return factories; synchronized (lazyFactoryProviders) { while (lazyFactoryProviders.size() > 0) { IAdapterManagerProvider provider = (IAdapterManagerProvider) lazyFactoryProviders.remove(0); if (provider.addFactories(this)) flushLookup(); } } return factories; } Consider two threads competing on getting the factory map: 1. Thread (1) checks the size of lazyFactoryProviders, it is grater than zero 2. Thread (1) enters the synchronized block 3. Thread (1) checks the size again, it is still grater than zero 4. Thread (1) picks&removes the first factory provider from the collection 5. Thread (2) checks the size of lazyFactoryProviders, it is now equal to zero! 6. Thread (2) returns the factories (where the desired factory is still missing) 7. Thread (2) searches for the desired factory in returned map 8. Thread (2) fails on the factory not being found!!! 9. Thread (1) adds the factory created by the picked provider to factories 10. Thread (1) returns the properly initialized map of factories 11. Thread (1) continues successfully since the desired factory is present Solution: Remove the first lines and let the whole operation be always synchronized. Checking the size of the collection is not a performance issue.
Created attachment 162050 [details] Solution proposal Apply this patch to solve the problem.
I agree and the patch looks good. John, do you agree?
Yes, I agree the patch looks good. I have run all the tests and committed this fix to HEAD. Great find!