Starting with the CORBA 2.2, the Basic Object Adapter (BOA) has been deprecated in favor of the Portable Object Adapter (POA). This document explains the changes required to migrate CORBA applications based on the BOA to use TAO's POA implementation, which is the only Object Adapter supported by TAO.
For more information on the benefits of the POA please see the Object Interconnection columns written by Doug Schmidt and Steve Vinoski.
POA_init
is replaced with
resolve_initial_references("RootPOA")
followed
by a _narrow
operation.PortableServer::ServantBase
.
The implications of this are (a) if you want a object reference for
that, you must use the _this
method.activate_object*
methods on a POA or calling
_this
on the servant; with the latest you have no
control on the ObjectId (which sometimes is good), and the POA
must support the right policies (the RootPOA does).const char*
parameter to set they object id, this is not needed now, in fact
in many cases they use to pass this argument to the skeleton
class: this will fail now.The new POA/servant reference counting rules of the CORBA 2.3 spec are somewhat tricky. Here are two main reasons why:
The solution to this is to make sure that the servant is deleted after the POA is deleted or make sure that the servant is deactivated from the POA before the servant is deleted.
The correct implementation is:class TAO_Export TAO_Thread_Policy : public POA_PortableServer::ThreadPolicy { void destroy (CORBA_Environment &ACE_TRY_ENV); }; void TAO_Thread_Policy::destroy (CORBA::Environment &ACE_TRY_ENV) { PortableServer::POA_var poa = this->_default_POA (ACE_TRY_ENV); ACE_CHECK; PortableServer::ObjectId_var id = poa->servant_to_id (this, ACE_TRY_ENV); ACE_CHECK; poa->deactivate_object (id.in (), ACE_TRY_ENV); ACE_CHECK; // Commit suicide: must have been dynamically allocated. delete this; }
One additional step required is to make the POA responsible for the servant after it has been registered with the POA:class TAO_Export TAO_Thread_Policy : public virtual PortableServer::RefCountServantBase, public virtual POA_PortableServer::ThreadPolicy { void destroy (CORBA_Environment &ACE_TRY_ENV); }; void TAO_Thread_Policy::destroy (CORBA::Environment &ACE_TRY_ENV) { // // Remove self from POA. Because of reference counting, the POA // will automatically delete the servant when all pending requests // on this servant are complete. // PortableServer::POA_var poa = this->_default_POA (ACE_TRY_ENV); ACE_CHECK; PortableServer::ObjectId_var id = poa->servant_to_id (this, ACE_TRY_ENV); ACE_CHECK; poa->deactivate_object (id.in (), ACE_TRY_ENV); ACE_CHECK; }
If you use the above approach of multiple inheritance, you must add the following to your header file:// Register with the POA. PortableServer::ThreadPolicy_var result = new_thread_policy->_this (ACE_TRY_ENV); // Give ownership of this servant to the POA. new_thread_policy->_remove_ref (ACE_TRY_ENV);
To see the above example in detail, checkout TAO/examples/POA/Reference_Counted_Servant and/or POA.cpp and POA.h.// This is to remove "inherits via dominance" warnings from MSVC. // MSVC is being a little too paranoid. #if defined (_MSC_VER) # pragma warning (disable : 4250) #endif /* _MSC_VER */