RequestProcessingStrategyDefaultServant.cpp

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

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