Migrating CORBA Applications from BOA to POA

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.

Contents

Client-side Changes

Server-side Changes

Reference counting Servants

The new POA/servant reference counting rules of the CORBA 2.3 spec are somewhat tricky. Here are two main reasons why:

  1. If a servant is deleted without deactivating from the POA, the application will crash because the POA will try to access the still registered (but now non-existent) servant when the POA is destroyed.

    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.

  2. You cannot delete a servant which is the target of the current upcall/request. A good example of this is the typical destroy() method, usually written like this:
    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;
    }
    
    The correct implementation is:
    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;
    }
    
    One additional step required is to make the POA responsible for the servant after it has been registered with the POA:
    // 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);
    
    If you use the above approach of multiple inheritance, you must add the following to your header file:
    // 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 */
    
    To see the above example in detail, checkout TAO/examples/POA/Reference_Counted_Servant and/or POA.cpp and POA.h.

PrismTech TOP
[top]