[omniORB] Deadlock in poa.cc and a question on (non-)standard behaviour

Vladimir Panov gbr at netel.bg
Thu Jun 26 19:44:03 BST 2003


I have a servant:

class S_i : public POA_S
{
	CORBA::ULong refCount;
         PortableServer::ObjectId_var objID;

	static PortableServer::POA_var poa;	// Some POA - not the root one, 
initialized OK.


public:
	S_i(void)
	{
	        this->refCount = 1;
         	this->objID = S_i::poa->activate_object(this);
	        this->_remove_ref();
	}

	~S_i(void)
	{
	}

	virtual void _add_ref(void)
	{
		this->refCount++;
	}

         virtual void _remove_ref(void)
	{
	        if (this->refCount == 1)
         	{
	                this->refCount--;
         	        try
                 	{
	                        S_i::poa->deactivate_object((const 
PortableServer::ObjectId_var)this->objID);
  	               }
         	        catch (...)
                 	{	// Don't care
	                }
         	}
	        else if (this->refCount == 0)
         	        delete this;
	        else
         	        this->refCount--;
	}
};

The servant activates itself in its constructor; implements server-side 
reference counting: when the reference count drops to 1 (the reference 
from the POA) it deactivates itself and then (as a result of the 
deactivation) it deletes itself.

This works OK for dynamic servants. But I have a static one - it is 
created and activated soon after ORB initialization, and should be (at 
least I think this way :-) deactivated and destroyed on ORB shutdown. 
But here is what happens:
1. I call orb->shutdown(true).
2. The POA deactivates the servant internally.
3. The POA calls _remove_ref(), the servant calls 
poa->deactivate_object() which throws OBJECT_NOT_EXIST_POANotInitialised.
Here is the log:

omniORB: Preparing to shutdown ORB.
omniORB: Destroying POA(RootPOA).
omniORB: Destroying POA(alabalaPOA).
omniORB: Deactivating all POA(alabalaPOA)'s objects.
omniORB: State root/alabalaPOA<0> (active) -> deactivating
omniORB: Waiting for requests to complete on POA(alabalaPOA).
omniORB: Requests on POA(alabalaPOA) completed.
omniORB: State root/alabalaPOA<0> (deactivating) -> etherealising
omniORB: Etherealising POA(alabalaPOA)'s objects.
omniORB: Removing root/alabalaPOA<0> (etherealising) from object table
omniORB: Object table entry root/alabalaPOA<0> (dead) deleted.
omniORB: throw OBJECT_NOT_EXIST from poa.cc:1137 
(NO,OBJECT_NOT_EXIST_POANotInitialised)

Is this the standard behaviour? Shouldn't the POA dereference its 
servants and then deactivate what's left?

------------------------------------------------------------------

No matter what are the answers to the questions above, this is what happens:
(poa.cc, line 1136-1137, function omniOrbPOA::deactivate_object)
   pd_lock.lock();
   CHECK_NOT_DESTROYED();

When the exception is thrown, pd_lock remains locked and later omniORB's 
shutdown deadlocks on it here:
(poa.cc, line 2146, function omniOrbPOA::do_destroy)




More information about the omniORB-list mailing list