Bug 531085

Summary: ModelDescriptorRegistry#internalGetModel(IFile) throws ConcurrentModificationException
Product: [Automotive] Sphinx Reporter: Martin Hentschel <martin.hentschel>
Component: CoreAssignee: Project Inbox <sphinx-inbox>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: balazs.grill
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows 10   
Whiteboard:

Description Martin Hentschel CLA 2018-02-13 04:28:27 EST
The method ModelDescriptorRegistry#internalGetModel(IFile) creates a copy of a Set which was created by Collections#synchronizedSet(Set) as follows:

    Set<IModelDescriptor> unsynchronizedModelDescriptorsForMMDescriptor = new HashSet<IModelDescriptor>(modelDescriptorsForMMDescriptor);

The problem is, that the constructor of the HashSet iterates over the set to copy without protecting it against concurrent access which must be done manually with a synchronized statement as documented in Collections#synchronizedSet(Set). Consequently, a ConcurrentModificationException is thrown by the constructor of the HashSet in case of concurrent access.

The obvious solution is:

    synchronized (modelDescriptorsForMMDescriptor) {
        Set<IModelDescriptor> unsynchronizedModelDescriptorsForMMDescriptor = new HashSet<IModelDescriptor>(modelDescriptorsForMMDescriptor);
    }

Please test carefully, that no deadlocks are introduced related to comment with the "Important Note".
Comment 1 Martin Hentschel CLA 2018-02-13 04:41:21 EST
The following methods should be adjusted as well:
- ModelDescriptorRegistry#internalGetModel(Resource)
- ModelDescriptorRegistry#getOldModel(IFile)
- ModelDescriptorRegistry#getOldModel(Resource)
- ModelDescriptorRegistry#internalGetModel(IResource, IMetaModelDescriptor)
- ModelDescriptorRegistry#getModels(IProject)
- ModelDescriptorRegistry#getModels(IWorkspaceRoot)


- ModelDescriptorRegistry#getAllModels(IMetaModelDescriptor)
  => Return unmodifiable copy so that concurrent access is possible
Comment 2 Martin Hentschel CLA 2018-02-13 04:45:32 EST
Change the visibility from ModelDescriptorRegistry#modelDescriptors from protected to private to ensure that nobody else iterates over the sets, thus deadlocks can hopefully be excluded.
Comment 3 Balazs Grill CLA 2024-05-07 00:50:42 EDT
Closed stale issue before migration