[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