RequestProcessingStrategyServantLocator.cpp

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

Generated on Tue Feb 2 17:40:54 2010 for TAO_PortableServer by  doxygen 1.4.7