RequestProcessingStrategyServantLocator.cpp

Go to the documentation of this file.
00001 #include "tao/ORB_Constants.h"
00002 #include "tao/PortableServer/ServantLocatorC.h"
00003 #include "tao/PortableServer/RequestProcessingStrategyServantLocator.h"
00004 #include "tao/PortableServer/Root_POA.h"
00005 #include "tao/PortableServer/POA_Current_Impl.h"
00006 #include "tao/PortableServer/Servant_Upcall.h"
00007 #include "tao/PortableServer/Non_Servant_Upcall.h"
00008 #include "tao/PortableServer/Servant_Base.h"
00009 
00010 ACE_RCSID (PortableServer,
00011            Request_Processing,
00012            "RequestProcessingStrategyServantLocator.cpp,v 1.8 2006/06/20 07:15:16 jwillemsen Exp")
00013 
00014 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
00015 
00016 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00017 
00018 namespace TAO
00019 {
00020   namespace Portable_Server
00021   {
00022     RequestProcessingStrategyServantLocator::RequestProcessingStrategyServantLocator (void)
00023     {
00024     }
00025 
00026     void
00027     RequestProcessingStrategyServantLocator::strategy_cleanup(
00028       ACE_ENV_SINGLE_ARG_DECL)
00029     {
00030       {
00031         Non_Servant_Upcall non_servant_upcall (*this->poa_);
00032         ACE_UNUSED_ARG (non_servant_upcall);
00033 
00034         this->servant_locator_ = PortableServer::ServantLocator::_nil ();
00035       }
00036 
00037       RequestProcessingStrategy::strategy_cleanup (ACE_ENV_SINGLE_ARG_PARAMETER);
00038       ACE_CHECK;
00039     }
00040 
00041     PortableServer::ServantManager_ptr
00042     RequestProcessingStrategyServantLocator::get_servant_manager (
00043       ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00044         ACE_THROW_SPEC ((CORBA::SystemException,
00045                          PortableServer::POA::WrongPolicy))
00046     {
00047       return PortableServer::ServantManager::_duplicate (this->servant_locator_.in ());
00048     }
00049 
00050     void
00051     RequestProcessingStrategyServantLocator::set_servant_manager (
00052       PortableServer::ServantManager_ptr imgr
00053       ACE_ENV_ARG_DECL)
00054         ACE_THROW_SPEC ((CORBA::SystemException,
00055                          PortableServer::POA::WrongPolicy))
00056     {
00057       // This operation sets the default servant manager associated with the
00058       // POA. This operation may only be invoked once after a POA has been
00059       // created. Attempting to set the servant manager after one has already
00060       // been set will result in the BAD_INV_ORDER system exception with
00061       // standard minor code 6 being raised (see 11.3.9.12 of the corba spec)
00062       if (!CORBA::is_nil (this->servant_locator_.in ()))
00063         {
00064           ACE_THROW (CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 6,
00065                                            CORBA::COMPLETED_NO));
00066         }
00067 
00068       this->servant_locator_ = PortableServer::ServantLocator::_narrow (imgr
00069                                                                         ACE_ENV_ARG_PARAMETER);
00070       ACE_CHECK;
00071 
00072       this->validate_servant_manager (this->servant_locator_.in () ACE_ENV_ARG_PARAMETER);
00073       ACE_CHECK;
00074     }
00075 
00076     TAO_SERVANT_LOCATION
00077     RequestProcessingStrategyServantLocator::locate_servant (
00078       const PortableServer::ObjectId &system_id,
00079       PortableServer::Servant &servant
00080       ACE_ENV_ARG_DECL)
00081     {
00082       TAO_SERVANT_LOCATION location = TAO_SERVANT_NOT_FOUND;
00083 
00084       location = this->poa_->servant_present (system_id,
00085                                               servant
00086                                               ACE_ENV_ARG_PARAMETER);
00087       ACE_CHECK_RETURN (TAO_SERVANT_NOT_FOUND);
00088 
00089       if (location == TAO_SERVANT_NOT_FOUND)
00090         {
00091           if (!CORBA::is_nil (this->servant_locator_.in ()))
00092             {
00093               location = TAO_SERVANT_MANAGER;
00094             }
00095         }
00096 
00097       return location;
00098     }
00099 
00100     PortableServer::Servant
00101     RequestProcessingStrategyServantLocator::locate_servant (
00102       const char *operation,
00103       const PortableServer::ObjectId &system_id,
00104       TAO::Portable_Server::Servant_Upcall &servant_upcall,
00105       TAO::Portable_Server::POA_Current_Impl &poa_current_impl,
00106       int &/*wait_occurred_restart_call*/
00107       ACE_ENV_ARG_DECL)
00108     {
00109       PortableServer::Servant servant = 0;
00110 
00111       servant = this->poa_->find_servant (system_id,
00112                                           servant_upcall,
00113                                           poa_current_impl
00114                                           ACE_ENV_ARG_PARAMETER);
00115       ACE_CHECK_RETURN (0);
00116 
00117       if (servant != 0)
00118         {
00119           return servant;
00120         }
00121 
00122       // If the POA has the USE_SERVANT_MANAGER policy, a servant manager
00123       // has been associated with the POA so the POA will invoke incarnate
00124       // or preinvoke on it to find a servant that may handle the
00125       // request. (The choice of method depends on the NON_RETAIN or
00126       // RETAIN policy of the POA.) If no servant manager has been
00127       // associated with the POA, the POA raises the OBJ_ADAPTER system
00128       // exception.
00129       //
00130       // If a servant manager is located and invoked, but the servant
00131       // manager is not directly capable of incarnating the object, it
00132       // (the servant manager) may deal with the circumstance in a variety
00133       // of ways, all of which are the application's responsibility.  Any
00134       // system exception raised by the servant manager will be returned
00135       // to the client in the reply. In addition to standard CORBA
00136       // exceptions, a servant manager is capable of raising a
00137       // ForwardRequest exception. This exception includes an object
00138       // reference.
00139       //
00140 
00141       this->validate_servant_manager (this->servant_locator_.in () ACE_ENV_ARG_PARAMETER);
00142       ACE_CHECK_RETURN (0);
00143 
00144       // No serialization of invocations of preinvoke or
00145       // postinvoke may be assumed; there may be multiple
00146       // concurrent invocations of preinvoke for the same
00147       // ObjectId.
00148       //
00149       // The same thread will be used to preinvoke the object,
00150       // process the request, and postinvoke the object.
00151 
00152       // @@ Note that it is possible for some other thread to
00153       // reset the servant locator once the lock is released.
00154       // However, this possiblility also exists for postinvoke()
00155       // which is also called outside the lock.
00156 
00157       // Release the object adapter lock.
00158       this->poa_->object_adapter().lock ().release ();
00159 
00160       // We have released the object adapter lock.  Record this
00161       // for later use.
00162       servant_upcall.state (TAO::Portable_Server::Servant_Upcall::OBJECT_ADAPTER_LOCK_RELEASED);
00163 
00164       PortableServer::ServantLocator::Cookie cookie = 0;
00165       servant =
00166         this->servant_locator_->preinvoke (poa_current_impl.object_id (),
00167                                            this->poa_,
00168                                            operation,
00169                                            cookie
00170                                            ACE_ENV_ARG_PARAMETER);
00171       ACE_CHECK_RETURN (0);
00172 
00173       if (servant == 0)
00174         {
00175           ACE_THROW_RETURN (CORBA::OBJ_ADAPTER (CORBA::OMGVMCID | 7,
00176                                                 CORBA::COMPLETED_NO),
00177                                                 0);
00178         }
00179 
00180       // Remember the cookie
00181       servant_upcall.locator_cookie (cookie);
00182 
00183       // Remember operation name.
00184       servant_upcall.operation (operation);
00185 
00186       // Success
00187       return servant;
00188     }
00189 
00190     void
00191     RequestProcessingStrategyServantLocator::cleanup_servant (
00192       PortableServer::Servant servant,
00193       const PortableServer::ObjectId &user_id
00194       ACE_ENV_ARG_DECL)
00195     {
00196       if (servant)
00197         {
00198           // ATTENTION: Trick locking here, see class header for details
00199           Non_Servant_Upcall non_servant_upcall (*this->poa_);
00200           ACE_UNUSED_ARG (non_servant_upcall);
00201 
00202           servant->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00203           ACE_CHECK;
00204         }
00205 
00206       // This operation causes the association of the Object Id specified
00207       // by the oid parameter and its servant to be removed from the
00208       // Active Object Map.
00209       int result = this->poa_->unbind_using_user_id (user_id);
00210 
00211       if (result != 0)
00212         {
00213           ACE_THROW (CORBA::OBJ_ADAPTER ());
00214         }
00215     }
00216 
00217     void
00218     RequestProcessingStrategyServantLocator::etherealize_objects (
00219       CORBA::Boolean /*etherealize_objects*/)
00220     {
00221     }
00222 
00223     void
00224     RequestProcessingStrategyServantLocator::post_invoke_servant_cleanup(
00225       const PortableServer::ObjectId &system_id,
00226       const TAO::Portable_Server::Servant_Upcall &servant_upcall)
00227     {
00228       // @todo This method seems to misbehave according to the corba spec, see
00229       // section 11.3.7.2. It says that when postinvoke raises an system
00230       // exception the methods normal return is overrriden, the request completes
00231       // with the exception
00232 
00233       if (!CORBA::is_nil (this->servant_locator_.in ()))
00234         {
00235           ACE_DECLARE_NEW_CORBA_ENV;
00236           ACE_TRY
00237             {
00238               servant_locator_->postinvoke (system_id,
00239                                             this->poa_,
00240                                             servant_upcall.operation (),
00241                                             servant_upcall.locator_cookie (),
00242                                             servant_upcall.servant ()
00243                                             ACE_ENV_ARG_PARAMETER);
00244               ACE_TRY_CHECK;
00245             }
00246           ACE_CATCHANY
00247             {
00248               // Ignore errors from servant locator ....
00249             }
00250           ACE_ENDTRY;
00251         }
00252     }
00253   }
00254 }
00255 
00256 TAO_END_VERSIONED_NAMESPACE_DECL
00257 
00258 #endif /* TAO_HAS_MINIMUM_POA == 0 */
00259 

Generated on Thu Nov 9 12:40:41 2006 for TAO_PortableServer by doxygen 1.3.6