Home » Modeling » EMF » Deadlock in EMF TransactionImpl
|Re: Deadlock in EMF TransactionImpl [message #1444769 is a reply to message #1443915]
||Tue, 14 October 2014 14:27
|| Christian Damus
Registered: July 2009
It looks like the deadlock is between
* the main thread, which owns the domain's monitor and is seeking a
transaction's monitor, and
* Worker-0, which owns that transaction's monitor and is seeking the
This deadlock is entirely within the Transaction API. The change
recorder's assertWriting() method synchronizes on the domain and then
on the active transaction, whereas a transaction int its start() method
synchronizes on itself and then on its domain. One of these monitor
sequences is out of order, and I suspect it's the one in the
TransactionChangeRecorder::assertWriting() method. It should not be
synchronizing on the domain.
This needs a bug on the EMF Transaction project.
I can't believe it took so long to find this deadlock! It has been
there from the very beginning. Mind you, it is an unusual case, in
which a thread (main) is loading a resource in a resource set that has
a transaction active in another thread. That is actually a programming
error: the main thread should be loading the resource in a read-only
transaction, which would have ensured that there is no conflict with
the worker thread. So, if you fix that, your tests will not deadlock
again. *However*, the deadlock is still a bug because the editing
domain should never deadlock itself in this way.
|Re: Deadlock in EMF TransactionImpl [message #1446219 is a reply to message #1446162]
||Thu, 16 October 2014 14:15
|| Christian Damus
Registered: July 2009
See some replies in-line, below.
On 2014-10-16 12:50:45 +0000, Aurelien Pupier said:
> Hi Christian,
> do you mean that I need to use TransactionUtil.runExclusive when
> loading EMF Resource? If yes, it will solve my deadlock in the
> deadlock2 context that you mention.
Yes. The central design point of the transaction API is that *all*
access to a resource set must be performed in the context of a
transaction. Modifications to the logical contents of a resource set
must be in read-write transactions; all other access may be in
read-only transactions but must be in transactions nonetheless. This
provides an exclusive lock (there is provision for reader threads to
cooperatively share access, via the yield() and PrivilegedRunnable
APIs) to protect against corruption of the data structures in the EMF
run-time that do not support concurrent access.
> Should I also place myself in the main Thread?
No, that should not be necessary, as transactions provide exclusive
locking on any thread (even the UI thread).
> In the first deadlock file, GMF is calling a edtiingDomain.runExclusive
> itself when I call GraphicalEditpart.resolveSemanticElement() and it is
> at this time that it is happening. I would need to call also the
> GraphicalEditpart.resolveSemanticElement() in a the Runnable within the
That depends on what you know of the implementation of the edit part in
question. If it does all model access within read-only transactions,
itself, and your code makes no attempt to read information from the
model, then you shouldn't need a transaction. But, it wouldn't hurt,
because transactions can nest: the edit-part will have no trouble
creating its transactions if your client already has one open on the
> In this case, how do i know in which case I need to do it or not? Do
> you have some pointers on the subject? i read the javadoc and found
> "Runs an operation that requires exclusive access to my resource set,
> for reading" but which operations requires access to my resources to my
> resource set, for reading? isn't all operations?
If all your operations have the potential to access the model
information in a resource set, then yes, they all need transactions.
The problem that transactions solve is that every read of a
ResourceSet, Resource, or EObject potentially has side-effects that are
not safe when done concurrently by multiple threads:
* MyObject::getXyz() can resolve proxies, which replaces elements in an
EList with new instances
* resolving proxies can create and load Resource instances that didn't
* loading content can trigger Adapters that may access other features
of who knows what objects
But, none of this detracts from the fact that there is actually a
deadlock bug in the TransactionalEditingDomainImpl. It just so happens
that there's also a bug in your code ;-)
Current Time: Sun Aug 09 18:34:47 GMT 2020
Powered by FUDForum
. Page generated in 0.01842 seconds