[
https://issues.apache.org/jira/browse/XMLBEANS-388?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Paul Hepworth updated XMLBEANS-388:
-----------------------------------
Description:
The situation can occur when calling a setter on an XmlObject which
synchronizes on Locale A, to set an XmlObject which synchronizes on Locale B at
the same time as calling a setter on an XmlObject which synchronizes on Locale
B to set an XmlObject which synchronizes on Locale A.
The code within XmlObjectBase is fine, but the problem lies in the generated
code compiled from a schema.
The code that is generated contains a synchronized block on the monitor (Locale
A or B depending on the object), and then delegates to the XmlObjectBase set
method, which detects that you need to lock more than 1 Locale and so acquires
a GlobalLock and then synchronizes on both monitors.
As another thread can be doing the reverse, you can end up with 2 threads, one
with Locale A locked, and one with Locale B locked. The first one then acquires
a GlobalLock, but can never obtain a lock on the other Locale.
The attached code can produce the following:
run:
[java] Thread:main:RUNNABLE:true
[java] java.lang.Thread.dumpThreads:-2
[java] java.lang.Thread.getAllStackTraces:1487
[java] Deadlock.main:21
[java] Thread:Signal Dispatcher:RUNNABLE:true
[java] Thread:Finalizer:WAITING:true
[java] java.lang.Object.wait:-2
[java] java.lang.ref.ReferenceQueue.remove:116
[java] java.lang.ref.ReferenceQueue.remove:132
[java] java.lang.ref.Finalizer$FinalizerThread.run:159
[java] Thread:Reference Handler:WAITING:true
[java] java.lang.Object.wait:-2
[java] java.lang.Object.wait:485
[java] java.lang.ref.Reference$ReferenceHandler.run:116
[java] Thread:Attach Listener:RUNNABLE:true
[java] Thread:Thread-0:WAITING:true
[java] java.lang.Object.wait:-2
[java] java.lang.Object.wait:485
[java] org.apache.xmlbeans.impl.common.Mutex.acquire:33
[java] org.apache.xmlbeans.impl.common.GlobalLock.acquire:27
[java] org.apache.xmlbeans.impl.values.XmlObjectBase.set:2049
[java] noNamespace.impl.ObjectBTypeImpl.setObjectA:-1
[java] MyThread.run:49
[java] Thread:Thread-1:BLOCKED:true
[java] org.apache.xmlbeans.impl.values.XmlObjectBase.set:2054
[java] noNamespace.impl.ObjectATypeImpl.setObjectB:-1
[java] MyThread.run:48
[java] Java Result: 1
As you can see, one thread is waiting on the GlobalLock, and the other has the
lock and is waiting for a lock on the other Locale (XmlObjectBase.set:2054).
was:
The situation can occur when calling a setter on an XmlObject which
synchronizes on Locale A, to set an XmlObject which synchronizes on Locale B at
the same time as calling a setter on an XmlObject which synchronizes on Locale
B to set an XmlObject which synchronizes on Locale A.
The code within XmlObjectBase is fine, but the problem lies in the generated
code compiled from a schema.
The code that is generated contains a synchronized block on the monitor (Locale
A or B depending on the object), and then delegates to the XmlObjectBase set
method, which detects that you need to lock more than 1 Locale and so acquires
a GlobalLock and then synchronizes on both monitors.
As another thread can be doing the reverse, you can end up with 2 threads, one
with Locale A locked, and one with Locale B locked. The first one then acquires
a GlobalLock, but can never obtain a lock on the other Locale.
The attached code can produce the following:
run:
[java] Thread:main:RUNNABLE:true
[java] java.lang.Thread.dumpThreads:-2
[java] java.lang.Thread.getAllStackTraces:1487
[java] Deadlock.main:21
[java] Thread:Signal Dispatcher:RUNNABLE:true
[java] Thread:Finalizer:WAITING:true
[java] java.lang.Object.wait:-2
[java] java.lang.ref.ReferenceQueue.remove:116
[java] java.lang.ref.ReferenceQueue.remove:132
[java] java.lang.ref.Finalizer$FinalizerThread.run:159
[java] Thread:Reference Handler:WAITING:true
[java] java.lang.Object.wait:-2
[java] java.lang.Object.wait:485
[java] java.lang.ref.Reference$ReferenceHandler.run:116
[java] Thread:Attach Listener:RUNNABLE:true
[java] Thread:Thread-0:WAITING:true
[java] java.lang.Object.wait:-2
[java] java.lang.Object.wait:485
[java] org.apache.xmlbeans.impl.common.Mutex.acquire:33
[java] org.apache.xmlbeans.impl.common.GlobalLock.acquire:27
[java] org.apache.xmlbeans.impl.values.XmlObjectBase.set:2049
[java] noNamespace.impl.ObjectBTypeImpl.setObjectA:-1
[java] MyThread.run:49
[java] Thread:Thread-1:BLOCKED:true
[java] org.apache.xmlbeans.impl.values.XmlObjectBase.set:2054
[java] noNamespace.impl.ObjectATypeImpl.setObjectB:-1
[java] MyThread.run:48
[java] Java Result: 1
As you can see, one thread is waiting on the GlobalLock, and the other has the
lock and is waiting for a lock on the other Locale (XmlObjectBase.set:2049).
Updated the line number.
> XmlBeans can Deadlock Threads
> -----------------------------
>
> Key: XMLBEANS-388
> URL: https://issues.apache.org/jira/browse/XMLBEANS-388
> Project: XMLBeans
> Issue Type: Bug
> Components: XmlObject
> Affects Versions: Version 2.3, Version 2.3.1, Version 2.4
> Environment: Windows XP, Java 1.6
> Reporter: Paul Hepworth
> Attachments: XmlBeansDeadlock.zip
>
>
> The situation can occur when calling a setter on an XmlObject which
> synchronizes on Locale A, to set an XmlObject which synchronizes on Locale B
> at the same time as calling a setter on an XmlObject which synchronizes on
> Locale B to set an XmlObject which synchronizes on Locale A.
> The code within XmlObjectBase is fine, but the problem lies in the generated
> code compiled from a schema.
> The code that is generated contains a synchronized block on the monitor
> (Locale A or B depending on the object), and then delegates to the
> XmlObjectBase set method, which detects that you need to lock more than 1
> Locale and so acquires a GlobalLock and then synchronizes on both monitors.
> As another thread can be doing the reverse, you can end up with 2 threads,
> one with Locale A locked, and one with Locale B locked. The first one then
> acquires a GlobalLock, but can never obtain a lock on the other Locale.
> The attached code can produce the following:
> run:
> [java] Thread:main:RUNNABLE:true
> [java] java.lang.Thread.dumpThreads:-2
> [java] java.lang.Thread.getAllStackTraces:1487
> [java] Deadlock.main:21
> [java] Thread:Signal Dispatcher:RUNNABLE:true
> [java] Thread:Finalizer:WAITING:true
> [java] java.lang.Object.wait:-2
> [java] java.lang.ref.ReferenceQueue.remove:116
> [java] java.lang.ref.ReferenceQueue.remove:132
> [java] java.lang.ref.Finalizer$FinalizerThread.run:159
> [java] Thread:Reference Handler:WAITING:true
> [java] java.lang.Object.wait:-2
> [java] java.lang.Object.wait:485
> [java] java.lang.ref.Reference$ReferenceHandler.run:116
> [java] Thread:Attach Listener:RUNNABLE:true
> [java] Thread:Thread-0:WAITING:true
> [java] java.lang.Object.wait:-2
> [java] java.lang.Object.wait:485
> [java] org.apache.xmlbeans.impl.common.Mutex.acquire:33
> [java] org.apache.xmlbeans.impl.common.GlobalLock.acquire:27
> [java] org.apache.xmlbeans.impl.values.XmlObjectBase.set:2049
> [java] noNamespace.impl.ObjectBTypeImpl.setObjectA:-1
> [java] MyThread.run:49
> [java] Thread:Thread-1:BLOCKED:true
> [java] org.apache.xmlbeans.impl.values.XmlObjectBase.set:2054
> [java] noNamespace.impl.ObjectATypeImpl.setObjectB:-1
> [java] MyThread.run:48
> [java] Java Result: 1
> As you can see, one thread is waiting on the GlobalLock, and the other has
> the lock and is waiting for a lock on the other Locale
> (XmlObjectBase.set:2054).
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]