[omniORB] omniOrbPOA deadlock

David Riddoch djr@uk.research.att.com
Thu, 12 Jul 2001 10:23:33 +0100 (BST)


Hi Renzo,

You are right that these actions cause a deadlock, but this has nothing to
do with the fact that the `identity' of an object switches to remote if it
is not activated locally.  That is just a performance issue, and was done
for reasons of simplicity (it meant I could ignore lots of special cases).

The deadlock arises because the POA holds servant_activator_lock whenever
it makes an up-call into a ServantActivator.  Thus if you are in an
up-call, and cause another, you try to take the lock a second time.  Why
do we take the lock while making an up-call?  Because the spec (CORBA 2.3
11.3.5) says that invocations of incarnate() and etherealize() must be
serealised and mutually exclusive.

Note that having a single lock, as we do in omniORB, is not ideal, because
there is no requirement for serealising invocations to distinct
ServantActivators.  However, if in your implementation of incarnate() or
etherealize() you cause another call to incarnate() on the same
ServantActivator, then you should expect it to deadlock, and that will
always be the case.  The spec just doesn't allow you to do that.

Doing something that leads to an etherealize() shouldn't be a problem,
because etherealisations are queued up on a separate worker thread and
happen as and when.

So the only thing that omniORB does that it arguably shouldn't, is
deadlock if you are in a ServantActivator up-call, and do something in
that up-call that leads to incarnate() being called on another
ServantActivator in a different POA.  This could be solved by having a
servant_activator_lock per-POA, at the expense of increasing the per-POA
state.

Hope that helps,
David


On Mon, 9 Jul 2001, Renzo Tomaselli wrote:

> Hi all,
>     there seems to be a deadlock in poa.cc which is due to the actual usage
> of servant_activator_lock.
> The sequence is:
> 
> 1. A servant is deactivated and this invokes an etherealize method on its
> servant activator. Before this occurrs,
> the method omniOrbPOA::Etherealiser::doit() locks servant_activator_lock.
> 2. During etherealization some cleanup is performed by app. code; this
> involves activating another servant through its servant activator. Although
> colocated, the involved objref identity is remote, so that a receiving
> thread wrapper must dispatch the request.
> 3. This is done in omniOrbPOA::dispatch_to_sa() method, which int turn tries
> to lock servant_activator_lock and at this point we are blocked forever.
> 
> All of this seems due to the strange identity switch of objrefs when the
> connected servant is deactivated: they switch from local to remote, so that
> next invokation goes through the normal marshalling procedure of remote
> objects and it calls back, although objref and servant are colocated.
> I feel this influences performance of servants managed by a servant
> activator, and even worse by servant locators. Beside the actual deadlock
> off course.
> Cheers,
>                                              Renzo Tomaselli