RequestProcessingStrategyDefaultServant.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 #include "tao/ORB_Constants.h"
00004 #include "tao/TSS_Resources.h"
00005 #include "tao/PortableServer/RequestProcessingStrategyDefaultServant.h"
00006 #include "tao/PortableServer/Non_Servant_Upcall.h"
00007 #include "tao/PortableServer/Root_POA.h"
00008 #include "tao/PortableServer/ServantManagerC.h"
00009 #include "tao/PortableServer/Servant_Base.h"
00010 #include "tao/PortableServer/POA_Current_Impl.h"
00011 
00012 ACE_RCSID (PortableServer,
00013            Request_Processing,
00014            "RequestProcessingStrategyDefaultServant.cpp,v 1.12 2006/06/20 07:15:16 jwillemsen Exp")
00015 
00016 #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
00017 
00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 namespace TAO
00021 {
00022   namespace Portable_Server
00023   {
00024     RequestProcessingStrategyDefaultServant::RequestProcessingStrategyDefaultServant (void)
00025       : default_servant_ (0)
00026     {
00027     }
00028 
00029     void
00030     RequestProcessingStrategyDefaultServant::strategy_cleanup(
00031       ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00032     {
00033       this->default_servant_ = 0;
00034     }
00035 
00036     PortableServer::ServantManager_ptr
00037     RequestProcessingStrategyDefaultServant::get_servant_manager (
00038       ACE_ENV_SINGLE_ARG_DECL)
00039         ACE_THROW_SPEC ((CORBA::SystemException,
00040                          PortableServer::POA::WrongPolicy))
00041     {
00042       ACE_THROW_RETURN (PortableServer::POA::WrongPolicy (),
00043                         PortableServer::ServantManager::_nil ());
00044     }
00045 
00046     void
00047     RequestProcessingStrategyDefaultServant::set_servant_manager (
00048       PortableServer::ServantManager_ptr /*imgr*/
00049       ACE_ENV_ARG_DECL)
00050         ACE_THROW_SPEC ((CORBA::SystemException,
00051                          PortableServer::POA::WrongPolicy))
00052     {
00053       ACE_THROW (PortableServer::POA::WrongPolicy ());
00054     }
00055 
00056     PortableServer::Servant
00057     RequestProcessingStrategyDefaultServant::get_servant (
00058       ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00059         ACE_THROW_SPEC ((CORBA::SystemException,
00060                          PortableServer::POA::WrongPolicy))
00061     {
00062       // This operation returns the default servant associated with the
00063       // POA.
00064       return this->default_servant_.in ();
00065     }
00066 
00067     void
00068     RequestProcessingStrategyDefaultServant::set_servant (
00069       PortableServer::Servant servant
00070       ACE_ENV_ARG_DECL)
00071         ACE_THROW_SPEC ((CORBA::SystemException,
00072                          PortableServer::POA::WrongPolicy))
00073     {
00074       // This operation registers the specified servant with the POA as
00075       // the default servant. This servant will be used for all requests
00076       // for which no servant is found in the Active Object Map.
00077       this->default_servant_ = servant;
00078 
00079       // The implementation of set_servant will invoke _add_ref at least
00080       // once on the Servant argument before returning. When the POA no
00081       // longer needs the Servant, it will invoke _remove_ref on it the
00082       // same number of times.
00083       if (servant != 0)
00084         {
00085           // A recursive thread lock without using a recursive thread
00086           // lock.  Non_Servant_Upcall has a magic constructor and
00087           // destructor.  We unlock the Object_Adapter lock for the
00088           // duration of the servant activator upcalls; reacquiring once
00089           // the upcalls complete.  Even though we are releasing the lock,
00090           // other threads will not be able to make progress since
00091           // <Object_Adapter::non_servant_upcall_in_progress_> has been
00092           // set.
00093           Non_Servant_Upcall non_servant_upcall (*this->poa_);
00094           ACE_UNUSED_ARG (non_servant_upcall);
00095 
00096           servant->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00097           ACE_CHECK;
00098         }
00099     }
00100 
00101     TAO_SERVANT_LOCATION
00102     RequestProcessingStrategyDefaultServant::locate_servant (
00103       const PortableServer::ObjectId & system_id,
00104       PortableServer::Servant & servant
00105       ACE_ENV_ARG_DECL)
00106     {
00107       TAO_SERVANT_LOCATION location = TAO_SERVANT_NOT_FOUND;
00108 
00109       location = this->poa_->servant_present (system_id,
00110                                               servant
00111                                               ACE_ENV_ARG_PARAMETER);
00112       ACE_CHECK_RETURN (TAO_SERVANT_NOT_FOUND);
00113 
00114       if (location == TAO_SERVANT_NOT_FOUND)
00115         {
00116           if (this->default_servant_.in () != 0)
00117             {
00118               location = TAO_DEFAULT_SERVANT;
00119             }
00120         }
00121 
00122       return location;
00123     }
00124 
00125     PortableServer::Servant
00126     RequestProcessingStrategyDefaultServant::locate_servant (
00127       const char * /*operation*/,
00128       const PortableServer::ObjectId & system_id,
00129       TAO::Portable_Server::Servant_Upcall &servant_upcall,
00130       TAO::Portable_Server::POA_Current_Impl &poa_current_impl,
00131       int & /*wait_occurred_restart_call*/
00132       ACE_ENV_ARG_DECL)
00133     {
00134       PortableServer::Servant servant = 0;
00135 
00136       servant = this->poa_->find_servant (system_id,
00137                                           servant_upcall,
00138                                           poa_current_impl
00139                                           ACE_ENV_ARG_PARAMETER);
00140       ACE_CHECK_RETURN (0);
00141 
00142       if (servant == 0)
00143         {
00144           // If the POA has the USE_DEFAULT_SERVANT policy, a default servant
00145           // has been associated with the POA so the POA will invoke the
00146           // appropriate method on that servant. If no servant has been
00147           // associated with the POA, the POA raises the OBJ_ADAPTER system
00148           // exception.
00149           PortableServer::Servant default_servant = this->default_servant_.in ();
00150           if (default_servant == 0)
00151             {
00152               ACE_THROW_RETURN (CORBA::OBJ_ADAPTER (CORBA::OMGVMCID | 3,
00153                                                     CORBA::COMPLETED_NO),
00154                                                     0);
00155             }
00156           else
00157             {
00158               // Success
00159               servant = default_servant;
00160             }
00161         }
00162 
00163         return servant;
00164     }
00165 
00166     PortableServer::Servant
00167     RequestProcessingStrategyDefaultServant::system_id_to_servant (
00168       const PortableServer::ObjectId &system_id
00169       ACE_ENV_ARG_DECL)
00170     {
00171       PortableServer::Servant servant = this->default_servant_.in ();
00172 
00173       if (servant == 0)
00174         {
00175           servant = this->poa_->find_servant (system_id
00176                                               ACE_ENV_ARG_PARAMETER);
00177           ACE_CHECK_RETURN (0);
00178         }
00179 
00180       return servant;
00181     }
00182 
00183     PortableServer::Servant
00184     RequestProcessingStrategyDefaultServant::id_to_servant (
00185       const PortableServer::ObjectId & /*id*/
00186       ACE_ENV_ARG_DECL)
00187         ACE_THROW_SPEC ((CORBA::SystemException,
00188                          PortableServer::POA::ObjectNotActive,
00189                          PortableServer::POA::WrongPolicy))
00190     {
00191       PortableServer::Servant servant = this->default_servant_.in ();
00192 
00193       if (servant == 0)
00194         {
00195           /*
00196            * If using default servant request processing strategy but
00197            * no default servant is available, we will raise the
00198            * ObjectNotActive system exception.
00199            */
00200           ACE_THROW_RETURN (PortableServer::POA::ObjectNotActive (),
00201                             0);
00202         }
00203 
00204       return servant;
00205     }
00206 
00207     void
00208     RequestProcessingStrategyDefaultServant::cleanup_servant (
00209       PortableServer::Servant servant,
00210       const PortableServer::ObjectId &user_id
00211       ACE_ENV_ARG_DECL)
00212     {
00213       if (servant)
00214         {
00215           // ATTENTION: Trick locking here, see class header for details
00216           Non_Servant_Upcall non_servant_upcall (*this->poa_);
00217           ACE_UNUSED_ARG (non_servant_upcall);
00218 
00219           servant->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00220           ACE_CHECK;
00221         }
00222 
00223       // This operation causes the association of the Object Id specified
00224       // by the oid parameter and its servant to be removed from the
00225       // Active Object Map.
00226       int result = this->poa_->unbind_using_user_id (user_id);
00227 
00228       if (result != 0)
00229         {
00230           ACE_THROW (CORBA::OBJ_ADAPTER ());
00231         }
00232     }
00233 
00234     void
00235     RequestProcessingStrategyDefaultServant::etherealize_objects (
00236       CORBA::Boolean /*etherealize_objects*/)
00237     {
00238     }
00239 
00240     PortableServer::ObjectId *
00241     RequestProcessingStrategyDefaultServant::servant_to_id (
00242       PortableServer::Servant servant
00243       ACE_ENV_ARG_DECL)
00244         ACE_THROW_SPEC ((CORBA::SystemException,
00245                          PortableServer::POA::ServantNotActive,
00246                          PortableServer::POA::WrongPolicy))
00247     {
00248       PortableServer::Servant default_servant = this->default_servant_.in ();
00249 
00250       if (default_servant != 0 &&
00251           default_servant == servant)
00252         {
00253           // If they are the same servant, then check if we are in an
00254           // upcall.
00255           TAO::Portable_Server::POA_Current_Impl *poa_current_impl =
00256             static_cast <TAO::Portable_Server::POA_Current_Impl *>
00257                         (TAO_TSS_Resources::instance ()->poa_current_impl_);
00258           // If we are in an upcall on the default servant, return the
00259           // ObjectId associated with the current invocation.
00260           if (poa_current_impl != 0 &&
00261               servant == poa_current_impl->servant ())
00262             {
00263               return poa_current_impl->get_object_id ();
00264             }
00265         }
00266 
00267       return this->poa_->servant_to_user_id (servant ACE_ENV_ARG_PARAMETER);
00268     }
00269 
00270     void
00271     RequestProcessingStrategyDefaultServant::post_invoke_servant_cleanup(
00272       const PortableServer::ObjectId &/*system_id*/,
00273       const TAO::Portable_Server::Servant_Upcall &/*servant_upcall*/)
00274     {
00275     }
00276 
00277     ::PortableServer::RequestProcessingPolicyValue
00278     RequestProcessingStrategyDefaultServant::type() const
00279     {
00280       return ::PortableServer::USE_DEFAULT_SERVANT;
00281     }
00282   }
00283 }
00284 
00285 TAO_END_VERSIONED_NAMESPACE_DECL
00286 
00287 #endif /* TAO_HAS_MINIMUM_POA == 0 */
00288 

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