[omniNotify] Re: [omniORB] Deleting a StructuredPushConsumer

Jon Dyte jon at totient.demon.co.uk
Tue Jun 15 22:35:05 BST 2004


Hi Fred

you are activating the eventObserver object via _this which will put it in the
RootPOA. When you delete event observer the ORB is complaining that there
is still a reference in the active object map.

I think you need a servant activator, but you still manually do the 
activation, but use the etherealise method to safely destroy the 
event_observer. It was not immediately obvious to me that you could use a 
servant manager but do the activation yrself, but close reading of 
Henning/Vinoski and an experiment showed this was possible and useful.

To fix this I would try:

1) make sure MyObserver also inherits from RefCountServantBase
2) create a child poa with the policies applicable for a servant activator
some code something like this
// rootpoa contains RootPOA
    CORBA::PolicyList policies(1);
    policies.length(1);
policies[0]=rootpoa->create_request_processing_policy(PortableServer::USE_SERVANT_MANAGER);

    PortableServer::POA_var childpoa =
        rootpoa->create_POA("ActivatorTest", 
PortableServer::POAManager::_nil(),policies);

    // clean up policies
    for (CORBA::ULong i = 0; i != policies.length (); ++i)
    {
        policies[i]->destroy();
    }

    // activate childpos manager
    PortableServer::POAManager_var childpoamgr = childpoa->the_POAManager();
    childpoamgr->activate();

3) you will need to define a servant activator, however you are not going to 
use the incarnate method (this is from the omni orb servnat manager example)
class MyActivator_i : public POA_PortableServer::ServantActivator,
                      public PortableServer::RefCountServantBase
{
public:
  virtual ~MyActivator_i()
  { cout << "MyActivator_i::~MyActivator_i()" << endl; }

  PortableServer::Servant
  incarnate(const PortableServer::ObjectId& oid,
            PortableServer::POA_ptr adapter)
  {
    throw CORBA::OBJECT_NOT_EXIST();
  }

  void
  etherealize(const PortableServer::ObjectId& oid,
              PortableServer::POA_ptr adapter,
              PortableServer::Servant the_servant,
              CORBA::Boolean cleanup_in_progress,
              CORBA::Boolean remaining_activations)
  {
    cout << "MyActivator_i::etherealize()" << endl;
    the_servant->_remove_ref();
  }
};

4) you need to set this activator as servant manager on  the child poa you 
created in step 3
MyActivator_i* sa = new MyActivator_i;
      PortableServer::ObjectId_var id = rootpoa->activate_object(sa);
      PortableServer::ServantActivator_var saref = sa->_this();
      sa->_remove_ref();

      // Register the servant activator with our new poa.
      childpoa->set_servant_manager(saref);

5) now when you construct event observer you do the following
event_observer = new MyObserver ;
CosNotifyComm::StructuredPushConsumer_var push_consumer ;
         CosNotifyChannelAdmin::StructuredProxyPushSupplier_var 
structured_proxy ;

PortableServer::ObjectId_var oid = childpoa->activate_object(event_observer);
// after activation, the POA increments reference count.
event_observer->_remove_ref();
CORBA::Object_var obj = childpoa->id_to_reference(oid);
push_consumer = CosNotifyComm::StructuredPushConsumer::_narrow(obj);

now rather than delete the event_observer directly you can use something like
childpoa->deactivate_object(*(childpoa->servant_to_id(even_observer)));

this will cause etherealise to be called on the activator for this object
when the orb determines it is safe. This in turn will call _remove_ref
on the event_observer, and as the refcount should be zero the destructor
will be called.

I hope this is helpful (and correct). It's worth having a look at
the servant_manager example in omniOrb and the chapters on servant manager in 
Henning/Vinoski

let me know if it works....

Jon
On Friday 11 June 2004 14:51, Frederic Prin wrote:
> Hi,
>
> I get an error message when deleting a StructuredPushConsumer instance
> that I create like this:
> event_observer = new MyObserver ;
>  /* My observer inherit from StructuredPushConsumer and overide the
> push_structured_event method*/
>
>         CosNotifyComm::StructuredPushConsumer_var push_consumer ;
>         CosNotifyChannelAdmin::StructuredProxyPushSupplier_var
> structured_proxy ;
>
> 	push_consumer = eventObserver->_this() ;
> 	structured_proxy =
> 			{ /* pseudo code */
> 				generic_proxy = consumer_admin
>
> ->obtain_notification_push_supplier(
> CosNotifyChannelAdmin::STRUCTURED_EVENT,
>
> proxy_id ) ;
> 				structured_proxy =
>
> CosNotifyChannelAdmin::StructuredProxyPushSupplier::_narrow(
> generic_proxy ) ;
>
> structured_proxy->connect_structured_push_consumer( pushConsumer ) ;
> 				Return structured_proxy;
> 			}
>
> 			/* Store all objects in *_Var vector */
> 			mEventObserverConsumerList.push_back(
> push_consumer ) ;
> 			mEventObserverProxyList.push_back(
> structured_proxy ) ;
> 			mEventObserverPtrList.push_back( eventObserver )
> ;
>
>
> 			/* From here I receive events successfully */
>
> Then before the ORB is shutdown I do not need ne more this consumer so I
> remove it like this:
> (StructuredPushConsumer s are stored in vector of
> StructuredPushConsumer_Var)
>
>
>
> mEventObserverConsumerList[i]->disconnect_structured_push_consumer() ;
>             mEventObserverProxyList[i]->remove_all_filters();
>
> mEventObserverProxyList[i]->disconnect_structured_push_supplier() ;
>
>             mEventObserverConsumerList.erase(
> mEventObserverConsumerList.begin() + i ) ;
>             mEventObserverProxyList.erase(
> mEventObserverProxyList.begin() + i ) ;
>
>
>
> Then I do not need this event handler anymore, so I
> delete event_observer ;
>
> When the delete is executed I get this error message:
>
> 	omniORB: ERROR -- A servant has been deleted that is still
> activated.
> 	      id: root<33554432> (active)
>
> Is someone get an idea why I get this message ?
> I try some CORBA::release on mEventObserverConsumerList[i] but it fails
> (ref count becomes <0)
> If I delete event_observer after my main servant is destroyed and orb is
> shutdown, it works.
>
> Is it forbiden to delete StructuredPushConsumer instance while the ORB
> is running (not shutdown) ?
>
> Thanks for your help
>
> Fred
>
>
>                               (
>      Frédéric Prin          )
>      Senior Software Engineer /
>           S I L V A C O      (
>      Grenoble REsearch CEnter \
>      Tel 04 56 38 10 33        )
>     __________________________/___
>    /__/__/__/__/__/__/__/__/__/__/
>   /__/__/__/__/__/__/__/__/_____/
>  /__/__/__/__/__/__/__/__/__/__/




More information about the omninotify-list mailing list