Servant_Base.cpp

Go to the documentation of this file.
00001 // $Id: Servant_Base.cpp 79124 2007-07-31 12:39:37Z johnnyw $
00002 
00003 #include "tao/PortableServer/Servant_Base.h"
00004 #include "tao/PortableServer/Root_POA.h"
00005 #include "tao/PortableServer/Operation_Table.h"
00006 #include "tao/PortableServer/POA_Current_Impl.h"
00007 
00008 #include "tao/Timeprobe.h"
00009 #include "tao/ORB_Core.h"
00010 #include "tao/TSS_Resources.h"
00011 #include "tao/Stub.h"
00012 #include "tao/TAO_Server_Request.h"
00013 #include "tao/IFR_Client_Adapter.h"
00014 
00015 #include "ace/Dynamic_Service.h"
00016 #include "ace/OS_NS_string.h"
00017 
00018 //@@ TAO_SERVANT_BASE_INCLUDE_ADD_HOOK
00019 
00020 ACE_RCSID (PortableServer,
00021            Servant_Base,
00022            "$Id: Servant_Base.cpp 79124 2007-07-31 12:39:37Z johnnyw $")
00023 
00024 #if !defined (__ACE_INLINE__)
00025 # include "tao/PortableServer/Servant_Base.inl"
00026 #endif /* ! __ACE_INLINE__ */
00027 
00028 #if defined (ACE_ENABLE_TIMEPROBES)
00029 
00030 static const char *TAO_Servant_Base_Timeprobe_Description[] =
00031 {
00032   "Servant_Base::_find - start",
00033   "Servant_Base::_find - end"
00034 };
00035 
00036 enum
00037   {
00038     TAO_SERVANT_BASE_FIND_START = 700,
00039     TAO_SERVANT_BASE_FIND_END
00040   };
00041 
00042 // Setup Timeprobes
00043 ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Servant_Base_Timeprobe_Description,
00044                                   TAO_SERVANT_BASE_FIND_START);
00045 
00046 #endif /* ACE_ENABLE_TIMEPROBES */
00047 
00048 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00049 
00050 TAO_ServantBase::TAO_ServantBase (void)
00051   : TAO_Abstract_ServantBase ()
00052   , ref_count_ (1)
00053   , optable_ (0)
00054 {
00055 }
00056 
00057 TAO_ServantBase::TAO_ServantBase (const TAO_ServantBase &rhs)
00058   : TAO_Abstract_ServantBase ()
00059   , ref_count_ (1)
00060   , optable_ (rhs.optable_)
00061 {
00062 }
00063 
00064 TAO_ServantBase &
00065 TAO_ServantBase::operator= (const TAO_ServantBase &rhs)
00066 {
00067   this->optable_ = rhs.optable_;
00068   return *this;
00069 }
00070 
00071 TAO_ServantBase::~TAO_ServantBase (void)
00072 {
00073 }
00074 
00075 PortableServer::POA_ptr
00076 TAO_ServantBase::_default_POA (void)
00077 {
00078   CORBA::Object_var object = TAO_ORB_Core_instance ()->root_poa ();
00079 
00080   return PortableServer::POA::_narrow (object.in ());
00081 }
00082 
00083 CORBA::Boolean
00084 TAO_ServantBase::_is_a (const char *logical_type_id)
00085 {
00086   static char const id[] = "IDL:omg.org/CORBA/Object:1.0";
00087   return ACE_OS::strcmp (logical_type_id, id) == 0;
00088 }
00089 
00090 CORBA::Boolean
00091 TAO_ServantBase::_non_existent (void)
00092 {
00093   return false;
00094 }
00095 
00096 CORBA::InterfaceDef_ptr
00097 TAO_ServantBase::_get_interface (void)
00098 {
00099   TAO_IFR_Client_Adapter *adapter =
00100     ACE_Dynamic_Service<TAO_IFR_Client_Adapter>::instance (
00101         TAO_ORB_Core::ifr_client_adapter_name ());
00102 
00103   if (adapter == 0)
00104     {
00105       throw ::CORBA::INTF_REPOS ();
00106     }
00107 
00108   // This doesn't take multiple ORBs into account, but it's being
00109   // used only to resolve the IFR, so we should be ok.
00110   return adapter->get_interface (TAO_ORB_Core_instance ()->orb (),
00111                                  this->_interface_repository_id ());
00112 }
00113 
00114 CORBA::Object_ptr
00115 TAO_ServantBase::_get_component (void)
00116 {
00117   return CORBA::Object::_nil ();
00118 }
00119 
00120 char *
00121 TAO_ServantBase::_repository_id (void)
00122 {
00123   return CORBA::string_dup (this->_interface_repository_id ());
00124 }
00125 
00126 int
00127 TAO_ServantBase::_find (const char *opname,
00128                         TAO_Skeleton& skelfunc,
00129                         const size_t length)
00130 {
00131   ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_BASE_FIND_START);
00132   return this->optable_->find (opname, skelfunc, length);
00133 }
00134 
00135 int
00136 TAO_ServantBase::_find (const char *opname,
00137                         TAO_Collocated_Skeleton& skelfunc,
00138                         TAO::Collocation_Strategy st,
00139                         const size_t length)
00140 {
00141   ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_BASE_FIND_START);
00142   return this->optable_->find (opname, skelfunc, st, length);
00143 }
00144 
00145 TAO_Stub *
00146 TAO_ServantBase::_create_stub (void)
00147 {
00148   TAO_Stub *stub = 0;
00149 
00150   TAO::Portable_Server::POA_Current_Impl *poa_current_impl =
00151     static_cast<TAO::Portable_Server::POA_Current_Impl *>
00152                     (TAO_TSS_Resources::instance ()->poa_current_impl_);
00153 
00154   CORBA::ORB_ptr servant_orb = 0;
00155 
00156   if (poa_current_impl != 0
00157       && this == poa_current_impl->servant ())
00158     {
00159       servant_orb = poa_current_impl->orb_core ().orb () ;
00160 
00161       stub =
00162         poa_current_impl->poa ()->key_to_stub (
00163             poa_current_impl->object_key (),
00164             this->_interface_repository_id (),
00165             poa_current_impl->priority ()
00166           );
00167     }
00168   else
00169     {
00170       PortableServer::POA_var poa = this->_default_POA ();
00171 
00172       CORBA::Object_var object = poa->servant_to_reference (this);
00173 
00174       // Get the stub object
00175       stub = object->_stubobj ();
00176 
00177       // Increment the reference count since <object> will zap its
00178       // stub object on deletion.
00179       stub->_incr_refcnt ();
00180 
00181       servant_orb = stub->orb_core ()->orb ();
00182     }
00183 
00184   stub->servant_orb (servant_orb);
00185   return stub;
00186 }
00187 
00188 void TAO_ServantBase::synchronous_upcall_dispatch (TAO_ServerRequest & req,
00189                                                    void * servant_upcall,
00190                                                    void * derived_this)
00191 {
00192   TAO_Skeleton skel;
00193   char const * const opname = req.operation ();
00194 
00195   // It seems that I might have missed s/g here.  What if
00196   // it is a one way that is SYNC_WITH_SERVER.
00197   // Add the following line to handle this reply send as well.
00198 
00199   // Handle the one ways that are SYNC_WITH_SERVER and not collocated
00200   if (req.sync_with_server () && !req.collocated ())
00201     {
00202       req.send_no_exception_reply ();
00203     }
00204 
00205   // Fetch the skeleton for this operation
00206   if (this->_find (opname,
00207                    skel,
00208                    static_cast <unsigned int> (req.operation_length())) == -1)
00209     {
00210       throw ::CORBA::BAD_OPERATION ();
00211     }
00212 
00213   CORBA::Boolean const send_reply =
00214     !req.sync_with_server ()
00215     && req.response_expected ()
00216     && !req.deferred_reply ();
00217 
00218   try
00219     {
00220       // Invoke the skeleton, it will demarshal the arguments, invoke
00221       // the right operation on the skeleton class, and marshal any
00222       // results.  De/marshaling will only occur in the uncollocated
00223       // case.
00224       skel (req, servant_upcall, derived_this);
00225 
00226       /*
00227        * Dispatch resolution specialization add hook.
00228        * Over-ridden with code to handle optimized dispatch.
00229        */
00230       //@@ TAO_DISPATCH_RESOLUTION_OPT_ADD_HOOK
00231 
00232       // It is our job to send the already marshaled reply, but only
00233       // send if it is expected and it has not already been sent
00234 
00235       // We send the reply only if it is NOT a SYNC_WITH_SERVER, a
00236       // response is expected and if the reply is not deferred.
00237       if (send_reply)
00238         {
00239           req.tao_send_reply ();
00240         }
00241     }
00242   catch (const ::CORBA::Exception& ex)
00243     {
00244       // If an exception was raised we should marshal it and send
00245       // the appropriate reply to the client
00246       if (send_reply)
00247         {
00248           if (req.collocated ())
00249             {
00250               // Report the exception to the collocated client.
00251               throw;
00252             }
00253           else
00254             req.tao_send_reply_exception (ex);
00255         }
00256     }
00257 
00258   return;
00259 }
00260 
00261 void TAO_ServantBase::asynchronous_upcall_dispatch (TAO_ServerRequest & req,
00262                                                     void * servant_upcall,
00263                                                     void * derived_this)
00264 {
00265   TAO_Skeleton skel;
00266   const char *opname = req.operation ();
00267 
00268   // It seems that I might have missed s/g here.  What if
00269   // it is a one way that is SYNC_WITH_SERVER.
00270   // Add the following line to handle this reply send as well.
00271 
00272   // Handle the one ways that are SYNC_WITH_SERVER
00273   if (req.sync_with_server ())
00274     {
00275       req.send_no_exception_reply ();
00276     }
00277 
00278   // Fetch the skeleton for this operation
00279   if (this->_find (opname,
00280                    skel,
00281                    static_cast <unsigned int> (req.operation_length())) == -1)
00282     {
00283       throw ::CORBA::BAD_OPERATION ();
00284     }
00285 
00286   try
00287     {
00288       // Invoke the skeleton, it will demarshal the arguments, invoke
00289       // the right operation on the skeleton class, and marshal any
00290       // results.  De/marshaling will only occur in the uncollocated
00291       // case.
00292       skel (req, servant_upcall, derived_this);
00293 
00294       // It is our job to send the already marshaled reply, but only
00295       // send if it is expected and it has not already been sent
00296 
00297       // Return immediately. Do not send a reply; this is an
00298       // asynchronous upcall. (unless, of course there is a system
00299       // exception.
00300 
00301     }
00302   catch (const ::CORBA::Exception& ex)
00303     {
00304       // If an exception was raised we should marshal it and send
00305       // the appropriate reply to the client
00306       req.tao_send_reply_exception (ex);
00307     }
00308 
00309   return;
00310 }
00311 
00312 void
00313 TAO_ServantBase::_add_ref (void)
00314 {
00315   ++this->ref_count_;
00316 }
00317 
00318 void
00319 TAO_ServantBase::_remove_ref (void)
00320 {
00321   long const new_count = --this->ref_count_;
00322 
00323   if (new_count == 0)
00324     delete this;
00325 }
00326 
00327 CORBA::ULong
00328 TAO_ServantBase::_refcount_value (void) const
00329 {
00330   return static_cast<CORBA::ULong> (this->ref_count_.value ());
00331 }
00332 
00333 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 13:23:44 2008 for TAO_PortableServer by doxygen 1.3.6