[omniORB] omniORBpy & omniORB 3.0 Object Deactivation from It's Own Method?

Randy Wiser randyw@amc.com
Tue, 09 May 2000 14:11:44 -0700


I've modified the enclosed echo example (uses standard IDL not enclosed) as a test of object deactivation, using a recent version of omniORBpy and omniORB 3.0 from the CVS repository (and I happen to build and run this using Python 1.6a2+, but I hope that is not important, as I suspect the same will happen using Python 1.5.2).

What I'm trying to do is get the POA to release it's reference to an unneeded object, so the memory can be reclaimed.  This seems to work fine with the latest versions of omniORBpy and omniORB 3.0 (or 2.8) from Python code running external to the object that is being deleted/deactivated.

When I try to do the same (directly or indirectly) from a method of the object that is being reclaimed, deactivation does not seem to happen, if I'm using the latest version of omniORBpy and the release version of omniORB 2.8.  The method returns normally without deactivation happening, apparently.

If I try again using omniORB 3.0 (still from the server's address space), then I can get deactivation to happen, but only with the threading workaround in the enclosed file.  If the file is run as-is (no workaround) execution (as traced by IDLE) seems to enter one of the omniORBpy libraries and never return.

Question: Am I doing something forbidden, or is there some problem with poa.deactivate_object() when called from the object being deactivated?

I'm trying to follow the recommended practice of having delete() methods on the objects themselves, instead of on the factory that creates an object.

Thanks in advance for any light you can shed on this.

- Randy
#!/usr/bin/env python

import sys, thread, time
from omniORB import CORBA, PortableServer

# Import the skeletons for the Example module
import POA__GlobalIDL

# Initialise the ORB
orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID)

# Find the POA
poa = orb.resolve_initial_references("RootPOA")

# Activate the POA
poaManager = poa._get_the_POAManager()
poaManager.activate()

objID = None # placeholder

def delayCall(secs, func, argTuple=None):
    time.sleep(secs)
    apply(func, argTuple)

# Define an implementation of the Echo interface
class Echo_i (POA__GlobalIDL.Echo):
    def __init__(self):
        print "Echo_i created."

    def __del__(self):
        print "Echo_i deleted."

    def echoString(self, mesg):
        print "echoString() called with message:", mesg
        print "echoString() deactivating myself."

        # Uncomment next line and comment out following line and it works.(???)
##        thread.start_new_thread(delayCall, (0, poa.deactivate_object, (objID,)))

        # deactivate_object() hangs, apparently in one of the omniORB libraries.
        poa.deactivate_object(objID)
        return mesg

# Create an instance of it
ei = Echo_i()

# Create an object reference, and implicitly activate the object
eo = ei._this()

objID = poa.reference_to_id(eo) # Save reference in global for use by echoString.

del ei  # Delete a Python reference to echo instance (omniORB still holds one).

eo.echoString('First call should succeed and deactivate object.')

time.sleep(0.1) # Give other thread (if any) time to deactivate_object()

print 'Next line should raise omniORB.CORBA.OBJECT_NOT_EXIST'
eo.echoString('Other calls should fail with OBJECT_NOT_EXIST.')

time.sleep(1)   # Wait a second before exiting.

# End file localtest.py