Bug 531085 - ModelDescriptorRegistry#internalGetModel(IFile) throws ConcurrentModificationException
Summary: ModelDescriptorRegistry#internalGetModel(IFile) throws ConcurrentModification...
Status: CLOSED WONTFIX
Alias: None
Product: Sphinx
Classification: Automotive
Component: Core (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows 10
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-02-13 04:28 EST by Martin Hentschel CLA
Modified: 2024-05-07 00:50 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
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