Servant_Base.cpp

Go to the documentation of this file.
00001 // $Id: Servant_Base.cpp 79914 2007-11-01 10:51:19Z 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 79914 2007-11-01 10:51:19Z 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   else
00168     {
00169       PortableServer::POA_var poa = this->_default_POA ();
00170 
00171       CORBA::Object_var object = poa->servant_to_reference (this);
00172 
00173       // Get the stub object
00174       stub = object->_stubobj ();
00175 
00176       // Increment the reference count since <object> will zap its
00177       // stub object on deletion.
00178       stub->_incr_refcnt ();
00179 
00180       servant_orb = stub->orb_core ()->orb ();
00181     }
00182 
00183   stub->servant_orb (servant_orb);
00184   return stub;
00185 }
00186 
00187 void TAO_ServantBase::synchronous_upcall_dispatch (TAO_ServerRequest & req,
00188                                                    void * servant_upcall,
00189                                                    void * derived_this)
00190 {
00191   TAO_Skeleton skel;
00192   char const * const opname = req.operation ();
00193 
00194   // It seems that I might have missed s/g here.  What if
00195   // it is a one way that is SYNC_WITH_SERVER.
00196   // Add the following line to handle this reply send as well.
00197 
00198   // Handle the one ways that are SYNC_WITH_SERVER and not collocated
00199   if (req.sync_with_server () && !req.collocated ())
00200     {
00201       req.send_no_exception_reply ();
00202     }
00203 
00204   // Fetch the skeleton for this operation
00205   if (this->_find (opname,
00206                    skel,
00207                    static_cast <unsigned int> (req.operation_length())) == -1)
00208     {
00209       throw ::CORBA::BAD_OPERATION ();
00210     }
00211 
00212   CORBA::Boolean const send_reply =
00213     !req.sync_with_server ()
00214     && req.response_expected ()
00215     && !req.deferred_reply ();
00216 
00217   try
00218     {
00219       // Invoke the skeleton, it will demarshal the arguments, invoke
00220       // the right operation on the skeleton class, and marshal any
00221       // results.  De/marshaling will only occur in the uncollocated
00222       // case.
00223       skel (req, servant_upcall, derived_this);
00224 
00225       /*
00226        * Dispatch resolution specialization add hook.
00227        * Over-ridden with code to handle optimized dispatch.
00228        */
00229       //@@ TAO_DISPATCH_RESOLUTION_OPT_ADD_HOOK
00230 
00231       // It is our job to send the already marshaled reply, but only
00232       // send if it is expected and it has not already been sent
00233 
00234       // We send the reply only if it is NOT a SYNC_WITH_SERVER, a
00235       // response is expected and if the reply is not deferred.
00236       if (send_reply)
00237         {
00238           req.tao_send_reply ();
00239         }
00240     }
00241   catch (const ::CORBA::Exception& ex)
00242     {
00243       // If an exception was raised we should marshal it and send
00244       // the appropriate reply to the client
00245       if (send_reply)
00246         {
00247           if (req.collocated ())
00248             {
00249               // Report the exception to the collocated client.
00250               throw;
00251             }
00252           else
00253             req.tao_send_reply_exception (ex);
00254         }
00255     }
00256 
00257   return;
00258 }
00259 
00260 void TAO_ServantBase::asynchronous_upcall_dispatch (TAO_ServerRequest & req,
00261                                                     void * servant_upcall,
00262                                                     void * derived_this)
00263 {
00264   TAO_Skeleton skel;
00265   const char *opname = req.operation ();
00266 
00267   // It seems that I might have missed s/g here.  What if
00268   // it is a one way that is SYNC_WITH_SERVER.
00269   // Add the following line to handle this reply send as well.
00270 
00271   // Handle the one ways that are SYNC_WITH_SERVER
00272   if (req.sync_with_server ())
00273     {
00274       req.send_no_exception_reply ();
00275     }
00276 
00277   // Fetch the skeleton for this operation
00278   if (this->_find (opname,
00279                    skel,
00280                    static_cast <unsigned int> (req.operation_length())) == -1)
00281     {
00282       throw ::CORBA::BAD_OPERATION ();
00283     }
00284 
00285   try
00286     {
00287       // Invoke the skeleton, it will demarshal the arguments, invoke
00288       // the right operation on the skeleton class, and marshal any
00289       // results.  De/marshaling will only occur in the uncollocated
00290       // case.
00291       skel (req, servant_upcall, derived_this);
00292 
00293       // It is our job to send the already marshaled reply, but only
00294       // send if it is expected and it has not already been sent
00295 
00296       // Return immediately. Do not send a reply; this is an
00297       // asynchronous upcall. (unless, of course there is a system
00298       // exception.
00299 
00300     }
00301   catch (const ::CORBA::Exception& ex)
00302     {
00303       // If an exception was raised we should marshal it and send
00304       // the appropriate reply to the client
00305       req.tao_send_reply_exception (ex);
00306     }
00307 
00308   return;
00309 }
00310 
00311 void
00312 TAO_ServantBase::_add_ref (void)
00313 {
00314   ++this->ref_count_;
00315 }
00316 
00317 void
00318 TAO_ServantBase::_remove_ref (void)
00319 {
00320   long const new_count = --this->ref_count_;
00321 
00322   if (new_count == 0)
00323     delete this;
00324 }
00325 
00326 CORBA::ULong
00327 TAO_ServantBase::_refcount_value (void) const
00328 {
00329   return static_cast<CORBA::ULong> (this->ref_count_.value ());
00330 }
00331 
00332 TAO_END_VERSIONED_NAMESPACE_DECL

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