[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xmlbeans-dev
Subject:    [jira] Updated: (XMLBEANS-388) XmlBeans can Deadlock Threads
From:       "Paul Hepworth (JIRA)" <xmlbeans-dev () xml ! apache ! org>
Date:       2008-11-04 17:50:44
Message-ID: 887926316.1225821044612.JavaMail.jira () brutus
[Download RAW message or body]


     [ 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: dev-unsubscribe@xmlbeans.apache.org
For additional commands, e-mail: dev-help@xmlbeans.apache.org


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic