Home » Modeling » EMF » [Papyrus, CDO] Deadlock situation when same model is loaded in different CDOViews
[Papyrus, CDO] Deadlock situation when same model is loaded in different CDOViews [message #1733832] |
Wed, 01 June 2016 10:37 |
Thorsten Schlathölter Messages: 312 Registered: February 2012 Location: Düsseldorf |
Senior Member |
|
|
Hi,
I found a deadlock situation in Papyrus in conjunction with CDO. If I have the same model loaded in different CDOTransactions I get a deadlock very reliably when I modify the model. This is due to the CacheAdapter performing "handleCrossReference" which is synced on the "inverseCrossReferencer" and the CDOLegacyAdapter performing "revisionToInstance" which is synced on "recursionCounter".
This are the stacks starting from the point where the threads aquire theirs blocking lock:
Daemon System Thread [Attach Listener] (Suspended)
Daemon System Thread [Signal Dispatcher] (Suspended)
Daemon System Thread [Finalizer] (Suspended)
Daemon System Thread [Reference Handler] (Suspended)
Thread [main] (Suspended)
owns: CDOTransactionImpl (id=79)
owns: CacheAdapter$InverseCrossReferencer (id=80)
waiting for: InheritableThreadLocal<T> (id=78)
owned by: Thread [Worker-1] (Suspended)
waiting for: CacheAdapter$InverseCrossReferencer (id=80)
owned by: Thread [main] (Suspended)
waiting for: InheritableThreadLocal<T> (id=78)
CDOLegacyAdapter(CDOLegacyWrapper).revisionToInstance() line: 444
CDOLegacyAdapter(CDOLegacyWrapper).cdoInternalPostLoad() line: 369
CDOTransactionImpl(AbstractCDOView).cleanObject(InternalCDOObject, InternalCDORevision) line: 1950
CDOTransactionImpl(AbstractCDOView).createObject(CDOID) line: 1859
CDOTransactionImpl(AbstractCDOView).getObject(CDOID, boolean) line: 1661
CDOTransactionImpl.getObject(CDOID, boolean) line: 1498
CDOTransactionImpl(AbstractCDOView).convertIDToObject(Object) line: 2140
CDOStoreImpl.convertIDToObject(InternalCDOView, EObject, EStructuralFeature, int, Object) line: 897
CDOStoreImpl.convertToEMF(EObject, InternalCDORevision, EStructuralFeature, int, Object) line: 860
CDOStoreImpl.isSet(InternalEObject, EStructuralFeature) line: 248
ValueTableImpl(CDOObjectImpl).eDynamicIsSet(int, EStructuralFeature) line: 734
ValueTableImpl(BasicEObjectImpl).eIsSet(int) line: 1257
ValueTableImpl(BasicEObjectImpl).eIsSet(EStructuralFeature) line: 1241
EContentsEList$FeatureIteratorImpl<E>.hasNext() line: 437
CacheAdapter(ECrossReferenceAdapter).setTarget(EObject) line: 775
CacheAdapter(ECrossReferenceAdapter).setTarget(Notifier) line: 752
CacheAdapter.setTarget(Notifier) line: 360
Thread [Worker-1] (Suspended)
owns: InheritableThreadLocal<T> (id=78)
owns: CDOTransactionImpl (id=82)
owns: SoxRepositoryProject (id=83)
waiting for: CacheAdapter$InverseCrossReferencer (id=80)
owned by: Thread [main] (Suspended)
waiting for: InheritableThreadLocal<T> (id=78)
owned by: Thread [Worker-1] (Suspended)
waiting for: CacheAdapter$InverseCrossReferencer (id=80)
owned by: Thread [main] (Suspended)
CacheAdapter.handleCrossReference(EObject) line: 341
AssociationImpl(ElementImpl).eSetDeliver(boolean) line: 988
CDOLegacyAdapter(CDOLegacyWrapper).revisionToInstance() line: 520
Both locks are static so I think the situation could also occur when working with different models are processed at the same time.
Any idea how to tackle this?
Regards,
Thorsten
|
|
|
Re: [Papyrus, CDO] Deadlock situation when same model is loaded in different CDOViews [message #1733907 is a reply to message #1733832] |
Thu, 02 June 2016 06:55 |
|
Hi Thorsten,
I'm unfamiliar with this CacheAdapter. Where does it come from and, more importantly, why are the two
CDOTransactions/ResourceSets use the same instance of this CacheAdapter?
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Am 01.06.2016 um 12:37 schrieb Thorsten Schlathölter:
> Hi,
> I found a deadlock situation in Papyrus in conjunction with CDO. If I have the same model loaded in different
> CDOTransactions I get a deadlock very reliably when I modify the model. This is due to the CacheAdapter performing
> "handleCrossReference" which is synced on the "inverseCrossReferencer" and the CDOLegacyAdapter performing
> "revisionToInstance" which is synced on "recursionCounter".
>
> This are the stacks starting from the point where the threads aquire theirs blocking lock:
>
>
> Daemon System Thread [Attach Listener] (Suspended)
> Daemon System Thread [Signal Dispatcher] (Suspended)
> Daemon System Thread [Finalizer] (Suspended)
> Daemon System Thread [Reference Handler] (Suspended)
> Thread [main] (Suspended)
> owns: CDOTransactionImpl (id=79)
> owns: CacheAdapter$InverseCrossReferencer (id=80)
> waiting for: InheritableThreadLocal<T> (id=78)
> owned by: Thread [Worker-1] (Suspended)
> waiting for: CacheAdapter$InverseCrossReferencer (id=80)
> owned by: Thread [main] (Suspended)
> waiting for: InheritableThreadLocal<T> (id=78)
> CDOLegacyAdapter(CDOLegacyWrapper).revisionToInstance() line: 444
> CDOLegacyAdapter(CDOLegacyWrapper).cdoInternalPostLoad() line: 369
> CDOTransactionImpl(AbstractCDOView).cleanObject(InternalCDOObject, InternalCDORevision) line: 1950
> CDOTransactionImpl(AbstractCDOView).createObject(CDOID) line: 1859
> CDOTransactionImpl(AbstractCDOView).getObject(CDOID, boolean) line: 1661
> CDOTransactionImpl.getObject(CDOID, boolean) line: 1498
> CDOTransactionImpl(AbstractCDOView).convertIDToObject(Object) line: 2140
> CDOStoreImpl.convertIDToObject(InternalCDOView, EObject, EStructuralFeature, int, Object) line: 897
> CDOStoreImpl.convertToEMF(EObject, InternalCDORevision, EStructuralFeature, int, Object) line: 860
> CDOStoreImpl.isSet(InternalEObject, EStructuralFeature) line: 248
> ValueTableImpl(CDOObjectImpl).eDynamicIsSet(int, EStructuralFeature) line: 734
> ValueTableImpl(BasicEObjectImpl).eIsSet(int) line: 1257
> ValueTableImpl(BasicEObjectImpl).eIsSet(EStructuralFeature) line: 1241
> EContentsEList$FeatureIteratorImpl<E>.hasNext() line: 437
> CacheAdapter(ECrossReferenceAdapter).setTarget(EObject) line: 775
> CacheAdapter(ECrossReferenceAdapter).setTarget(Notifier) line: 752
> CacheAdapter.setTarget(Notifier) line: 360
>
>
>
> Thread [Worker-1] (Suspended)
> owns: InheritableThreadLocal<T> (id=78)
> owns: CDOTransactionImpl (id=82)
> owns: SoxRepositoryProject (id=83)
> waiting for: CacheAdapter$InverseCrossReferencer (id=80)
> owned by: Thread [main] (Suspended)
> waiting for: InheritableThreadLocal<T> (id=78)
> owned by: Thread [Worker-1] (Suspended)
> waiting for: CacheAdapter$InverseCrossReferencer (id=80)
> owned by: Thread [main] (Suspended)
> CacheAdapter.handleCrossReference(EObject) line: 341
> AssociationImpl(ElementImpl).eSetDeliver(boolean) line: 988
> CDOLegacyAdapter(CDOLegacyWrapper).revisionToInstance() line: 520
>
>
> Both locks are static so I think the situation could also occur when working with different models are processed at
> the same time.
>
> Any idea how to tackle this?
>
> Regards,
> Thorsten
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [Papyrus, CDO] Deadlock situation when same model is loaded in different CDOViews [message #1733946 is a reply to message #1733907] |
Thu, 02 June 2016 11:35 |
|
Hi, Eike,
The CacheAdapter is a component of the UML2 API. It is a static
singleton and elements of UML models automatically ensure that it is
attached to themselves and all contents reachable from them, which is
why all resource sets that have UML content have this adapter.
The CacheAdapter is crucial for acceptable performance of derived
feature and operation computations in the UML API and in the very
earliest days of the UML2 project it was determined that attempting to
have a distinct CacheAdapter per ResourceSet killed performance.
That said, applications can replace the CacheAdapter with a custom
implementation of their own that perhaps addresses either locking
issues or isn't quite a singleton.
HTH,
Christian
On 2016-06-02 06:55:25 +0000, Eike Stepper said:
> Hi Thorsten,
>
> I'm unfamiliar with this CacheAdapter. Where does it come from and,
> more importantly, why are the two CDOTransactions/ResourceSets use the
> same instance of this CacheAdapter?
>
> Cheers
> /Eike
>
> ----
> http://www.esc-net.de
> http://thegordian.blogspot.com
> http://twitter.com/eikestepper
>
>
>
>
>
> Am 01.06.2016 um 12:37 schrieb Thorsten Schlathölter:
>> Hi,
>> I found a deadlock situation in Papyrus in conjunction with CDO. If I
>> have the same model loaded in different CDOTransactions I get a
>> deadlock very reliably when I modify the model. This is due to the
>> CacheAdapter performing "handleCrossReference" which is synced on the
>> "inverseCrossReferencer" and the CDOLegacyAdapter performing
>> "revisionToInstance" which is synced on "recursionCounter".
>>
>> This are the stacks starting from the point where the threads aquire
>> theirs blocking lock:
>>
>>
>> Daemon System Thread [Attach Listener] (Suspended)
>> Daemon System Thread [Signal Dispatcher] (Suspended)
>> Daemon System Thread [Finalizer] (Suspended)
>> Daemon System Thread [Reference Handler] (Suspended)
>> Thread [main] (Suspended)
>> owns: CDOTransactionImpl (id=79)
>> owns: CacheAdapter$InverseCrossReferencer (id=80)
>> waiting for: InheritableThreadLocal<T> (id=78)
>> owned by: Thread [Worker-1] (Suspended)
>> waiting for: CacheAdapter$InverseCrossReferencer (id=80)
>> owned by: Thread [main] (Suspended)
>> waiting for: InheritableThreadLocal<T> (id=78)
>> CDOLegacyAdapter(CDOLegacyWrapper).revisionToInstance() line: 444
>> CDOLegacyAdapter(CDOLegacyWrapper).cdoInternalPostLoad() line: 369
>> CDOTransactionImpl(AbstractCDOView).cleanObject(InternalCDOObject,
>> InternalCDORevision) line: 1950
>> CDOTransactionImpl(AbstractCDOView).createObject(CDOID) line: 1859
>> CDOTransactionImpl(AbstractCDOView).getObject(CDOID, boolean) line: 1661
>> CDOTransactionImpl.getObject(CDOID, boolean) line: 1498
>> CDOTransactionImpl(AbstractCDOView).convertIDToObject(Object) line: 2140
>> CDOStoreImpl.convertIDToObject(InternalCDOView, EObject,
>> EStructuralFeature, int, Object) line: 897
>> CDOStoreImpl.convertToEMF(EObject, InternalCDORevision,
>> EStructuralFeature, int, Object) line: 860
>> CDOStoreImpl.isSet(InternalEObject, EStructuralFeature) line: 248
>> ValueTableImpl(CDOObjectImpl).eDynamicIsSet(int, EStructuralFeature) line: 734
>> ValueTableImpl(BasicEObjectImpl).eIsSet(int) line: 1257
>> ValueTableImpl(BasicEObjectImpl).eIsSet(EStructuralFeature) line: 1241
>> EContentsEList$FeatureIteratorImpl<E>.hasNext() line: 437
>> CacheAdapter(ECrossReferenceAdapter).setTarget(EObject) line: 775
>> CacheAdapter(ECrossReferenceAdapter).setTarget(Notifier) line: 752
>> CacheAdapter.setTarget(Notifier) line: 360
>>
>>
>>
>> Thread [Worker-1] (Suspended)
>> owns: InheritableThreadLocal<T> (id=78)
>> owns: CDOTransactionImpl (id=82)
>> owns: SoxRepositoryProject (id=83)
>> waiting for: CacheAdapter$InverseCrossReferencer (id=80)
>> owned by: Thread [main] (Suspended)
>> waiting for: InheritableThreadLocal<T> (id=78)
>> owned by: Thread [Worker-1] (Suspended)
>> waiting for: CacheAdapter$InverseCrossReferencer (id=80)
>> owned by: Thread [main] (Suspended)
>> CacheAdapter.handleCrossReference(EObject) line: 341
>> AssociationImpl(ElementImpl).eSetDeliver(boolean) line: 988
>> CDOLegacyAdapter(CDOLegacyWrapper).revisionToInstance() line: 520
>>
>>
>> Both locks are static so I think the situation could also occur when
>> working with different models are processed at the same time.
>>
>> Any idea how to tackle this?
>>
>> Regards,
>> Thorsten
|
|
|
Re: [Papyrus, CDO] Deadlock situation when same model is loaded in different CDOViews [message #1733950 is a reply to message #1733946] |
Thu, 02 June 2016 11:54 |
|
Hi Christian,
Thanks for the valuable infos. The problem that has been reported here is definitely because of nested snychronization
on two different, global singletons (CacheAdapter$InverseCrossReferencer and InheritableThreadLocal<T>).
Thorsten, I'm willing to play with a narrower replacement of CDO's singleton lock (e.g., the current CDOView). Please
submit a bugzilla.
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Am 02.06.2016 um 13:35 schrieb Christian W. Damus:
> Hi, Eike,
>
> The CacheAdapter is a component of the UML2 API. It is a static singleton and elements of UML models automatically
> ensure that it is attached to themselves and all contents reachable from them, which is why all resource sets that
> have UML content have this adapter.
>
> The CacheAdapter is crucial for acceptable performance of derived feature and operation computations in the UML API
> and in the very earliest days of the UML2 project it was determined that attempting to have a distinct CacheAdapter
> per ResourceSet killed performance.
>
> That said, applications can replace the CacheAdapter with a custom implementation of their own that perhaps addresses
> either locking issues or isn't quite a singleton.
>
> HTH,
>
> Christian
>
>
> On 2016-06-02 06:55:25 +0000, Eike Stepper said:
>
>> Hi Thorsten,
>>
>> I'm unfamiliar with this CacheAdapter. Where does it come from and, more importantly, why are the two
>> CDOTransactions/ResourceSets use the same instance of this CacheAdapter?
>>
>> Cheers
>> /Eike
>>
>> ----
>> http://www.esc-net.de
>> http://thegordian.blogspot.com
>> http://twitter.com/eikestepper
>>
>>
>>
>>
>>
>> Am 01.06.2016 um 12:37 schrieb Thorsten Schlathölter:
>>> Hi,
>>> I found a deadlock situation in Papyrus in conjunction with CDO. If I have the same model loaded in different
>>> CDOTransactions I get a deadlock very reliably when I modify the model. This is due to the CacheAdapter performing
>>> "handleCrossReference" which is synced on the "inverseCrossReferencer" and the CDOLegacyAdapter performing
>>> "revisionToInstance" which is synced on "recursionCounter".
>>>
>>> This are the stacks starting from the point where the threads aquire theirs blocking lock:
>>>
>>>
>>> Daemon System Thread [Attach Listener] (Suspended)
>>> Daemon System Thread [Signal Dispatcher] (Suspended)
>>> Daemon System Thread [Finalizer] (Suspended)
>>> Daemon System Thread [Reference Handler] (Suspended)
>>> Thread [main] (Suspended)
>>> owns: CDOTransactionImpl (id=79)
>>> owns: CacheAdapter$InverseCrossReferencer (id=80)
>>> waiting for: InheritableThreadLocal<T> (id=78)
>>> owned by: Thread [Worker-1] (Suspended)
>>> waiting for: CacheAdapter$InverseCrossReferencer (id=80)
>>> owned by: Thread [main] (Suspended)
>>> waiting for: InheritableThreadLocal<T> (id=78)
>>> CDOLegacyAdapter(CDOLegacyWrapper).revisionToInstance() line: 444
>>> CDOLegacyAdapter(CDOLegacyWrapper).cdoInternalPostLoad() line: 369
>>> CDOTransactionImpl(AbstractCDOView).cleanObject(InternalCDOObject, InternalCDORevision) line: 1950
>>> CDOTransactionImpl(AbstractCDOView).createObject(CDOID) line: 1859
>>> CDOTransactionImpl(AbstractCDOView).getObject(CDOID, boolean) line: 1661
>>> CDOTransactionImpl.getObject(CDOID, boolean) line: 1498
>>> CDOTransactionImpl(AbstractCDOView).convertIDToObject(Object) line: 2140
>>> CDOStoreImpl.convertIDToObject(InternalCDOView, EObject, EStructuralFeature, int, Object) line: 897
>>> CDOStoreImpl.convertToEMF(EObject, InternalCDORevision, EStructuralFeature, int, Object) line: 860
>>> CDOStoreImpl.isSet(InternalEObject, EStructuralFeature) line: 248
>>> ValueTableImpl(CDOObjectImpl).eDynamicIsSet(int, EStructuralFeature) line: 734
>>> ValueTableImpl(BasicEObjectImpl).eIsSet(int) line: 1257
>>> ValueTableImpl(BasicEObjectImpl).eIsSet(EStructuralFeature) line: 1241
>>> EContentsEList$FeatureIteratorImpl<E>.hasNext() line: 437
>>> CacheAdapter(ECrossReferenceAdapter).setTarget(EObject) line: 775
>>> CacheAdapter(ECrossReferenceAdapter).setTarget(Notifier) line: 752
>>> CacheAdapter.setTarget(Notifier) line: 360
>>>
>>>
>>>
>>> Thread [Worker-1] (Suspended)
>>> owns: InheritableThreadLocal<T> (id=78)
>>> owns: CDOTransactionImpl (id=82)
>>> owns: SoxRepositoryProject (id=83)
>>> waiting for: CacheAdapter$InverseCrossReferencer (id=80)
>>> owned by: Thread [main] (Suspended)
>>> waiting for: InheritableThreadLocal<T> (id=78)
>>> owned by: Thread [Worker-1] (Suspended)
>>> waiting for: CacheAdapter$InverseCrossReferencer (id=80)
>>> owned by: Thread [main] (Suspended)
>>> CacheAdapter.handleCrossReference(EObject) line: 341
>>> AssociationImpl(ElementImpl).eSetDeliver(boolean) line: 988
>>> CDOLegacyAdapter(CDOLegacyWrapper).revisionToInstance() line: 520
>>>
>>>
>>> Both locks are static so I think the situation could also occur when working with different models are processed at
>>> the same time.
>>>
>>> Any idea how to tackle this?
>>>
>>> Regards,
>>> Thorsten
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| | |
Goto Forum:
Current Time: Sun Nov 10 18:15:16 GMT 2024
Powered by FUDForum. Page generated in 0.06224 seconds
|