1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Yet another deadlock in old ICDescriptor code.

Hitting this in our internal verify jobs. This invoke method locks
the element then calls removeProjectStorage which waits on fLock.
Meanwhile someone else has called getProjectData has the lock and
then tries to lock an element. Deadlock.

Change-Id: I5d013e8aa3c16e8c832fbe30b2dd3c17aeeefee5
This commit is contained in:
Doug Schaefer 2018-03-01 16:16:36 -05:00
parent 10c5897080
commit 071f118e27

View file

@ -510,21 +510,27 @@ final public class CConfigBasedDescriptor implements ICDescriptor {
Node parentProxy = (Node)Proxy.newProxyInstance(Node.class.getClassLoader(), new Class[]{Node.class}, new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method realMethod = parent.getClass().getMethod(method.getName(), method.getParameterTypes());
synchronized (xmlEl) {
// Handle the remove child case
if (method.getName().equals("removeChild")) { //$NON-NLS-1$
if (args[0] instanceof Element && ((Element)args[0]).getAttribute(
XmlStorage.MODULE_ID_ATTRIBUTE).length() > 0) {
ICStorageElement removed = removeProjectStorageElement(((Element)args[0]).getAttribute(
XmlStorage.MODULE_ID_ATTRIBUTE));
if (removed != null)
return ((XmlStorageElement)((SynchronizedStorageElement)removed).getOriginalElement()).fElement;
return null;
// Require the lock before locking the element
fLock.acquire();
try {
Method realMethod = parent.getClass().getMethod(method.getName(), method.getParameterTypes());
synchronized (xmlEl) {
// Handle the remove child case
if (method.getName().equals("removeChild")) { //$NON-NLS-1$
if (args[0] instanceof Element && ((Element)args[0]).getAttribute(
XmlStorage.MODULE_ID_ATTRIBUTE).length() > 0) {
ICStorageElement removed = removeProjectStorageElement(((Element)args[0]).getAttribute(
XmlStorage.MODULE_ID_ATTRIBUTE));
if (removed != null)
return ((XmlStorageElement)((SynchronizedStorageElement)removed).getOriginalElement()).fElement;
return null;
}
}
// else return the realMethod
return realMethod.invoke(parent, args);
}
// else return the realMethod
return realMethod.invoke(parent, args);
} finally {
fLock.release();
}
}
});