Servant_Base.cpp

Go to the documentation of this file.
00001 // Servant_Base.cpp,v 1.56 2006/03/10 07:19:16 jtc Exp
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/Environment.h"
00013 #include "tao/TAO_Server_Request.h"
00014 #include "tao/IFR_Client_Adapter.h"
00015 
00016 #include "ace/Dynamic_Service.h"
00017 #include "ace/OS_NS_string.h"
00018 
00019 //@@ TAO_SERVANT_BASE_INCLUDE_ADD_HOOK
00020 
00021 ACE_RCSID (PortableServer,
00022            Servant_Base,
00023            "Servant_Base.cpp,v 1.56 2006/03/10 07:19:16 jtc Exp")
00024 
00025 #if !defined (__ACE_INLINE__)
00026 # include "tao/PortableServer/Servant_Base.i"
00027 #endif /* ! __ACE_INLINE__ */
00028 
00029 #if defined (ACE_ENABLE_TIMEPROBES)
00030 
00031 static const char *TAO_Servant_Base_Timeprobe_Description[] =
00032 {
00033   "Servant_Base::_find - start",
00034   "Servant_Base::_find - end"
00035 };
00036 
00037 enum
00038   {
00039     TAO_SERVANT_BASE_FIND_START = 700,
00040     TAO_SERVANT_BASE_FIND_END
00041   };
00042 
00043 // Setup Timeprobes
00044 ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Servant_Base_Timeprobe_Description,
00045                                   TAO_SERVANT_BASE_FIND_START);
00046 
00047 #endif /* ACE_ENABLE_TIMEPROBES */
00048 
00049 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00050 
00051 TAO_ServantBase::TAO_ServantBase (void)
00052   : TAO_Abstract_ServantBase ()
00053   , ref_count_ (1)
00054   , optable_ (0)
00055 {
00056 }
00057 
00058 TAO_ServantBase::TAO_ServantBase (const TAO_ServantBase &rhs)
00059   : TAO_Abstract_ServantBase ()
00060   , ref_count_ (1)
00061   , optable_ (rhs.optable_)
00062 {
00063 }
00064 
00065 TAO_ServantBase &
00066 TAO_ServantBase::operator= (const TAO_ServantBase &rhs)
00067 {
00068   this->optable_ = rhs.optable_;
00069   return *this;
00070 }
00071 
00072 TAO_ServantBase::~TAO_ServantBase (void)
00073 {
00074 }
00075 
00076 PortableServer::POA_ptr
00077 TAO_ServantBase::_default_POA (ACE_ENV_SINGLE_ARG_DECL)
00078 {
00079   CORBA::Object_var object =
00080     TAO_ORB_Core_instance ()->root_poa (ACE_ENV_SINGLE_ARG_PARAMETER);
00081   ACE_CHECK_RETURN (PortableServer::POA::_nil ());
00082 
00083   return PortableServer::POA::_narrow (object.in ()
00084                                        ACE_ENV_ARG_PARAMETER);
00085 }
00086 
00087 CORBA::Boolean
00088 TAO_ServantBase::_is_a (const char *logical_type_id
00089                         ACE_ENV_ARG_DECL_NOT_USED)
00090 {
00091   static char const id[] = "IDL:omg.org/CORBA/Object:1.0";
00092   return ACE_OS::strcmp (logical_type_id, id) == 0;
00093 }
00094 
00095 CORBA::Boolean
00096 TAO_ServantBase::_non_existent (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00097 {
00098   return false;
00099 }
00100 
00101 CORBA::InterfaceDef_ptr
00102 TAO_ServantBase::_get_interface (ACE_ENV_SINGLE_ARG_DECL)
00103 {
00104   TAO_IFR_Client_Adapter *adapter =
00105     ACE_Dynamic_Service<TAO_IFR_Client_Adapter>::instance (
00106         TAO_ORB_Core::ifr_client_adapter_name ()
00107       );
00108 
00109   if (adapter == 0)
00110     {
00111       ACE_THROW_RETURN (CORBA::INTF_REPOS (),
00112                         0);
00113     }
00114 
00115   // This doesn't take multiple ORBs into account, but it's being
00116   // used only to resolve the IFR, so we should be ok.
00117   return adapter->get_interface (TAO_ORB_Core_instance ()->orb (),
00118                                  this->_interface_repository_id ()
00119                                  ACE_ENV_ARG_PARAMETER);
00120 }
00121 
00122 CORBA::Object_ptr
00123 TAO_ServantBase::_get_component (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00124 {
00125   return CORBA::Object::_nil ();
00126 }
00127 
00128 char *
00129 TAO_ServantBase::_repository_id (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00130 {
00131   return CORBA::string_dup (this->_interface_repository_id ());
00132 }
00133 
00134 int
00135 TAO_ServantBase::_find (const char *opname,
00136                         TAO_Skeleton& skelfunc,
00137                         const size_t length)
00138 {
00139   ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_BASE_FIND_START);
00140   return this->optable_->find (opname, skelfunc, length);
00141 }
00142 
00143 int
00144 TAO_ServantBase::_find (const char *opname,
00145                         TAO_Collocated_Skeleton& skelfunc,
00146                         TAO::Collocation_Strategy st,
00147                         const size_t length)
00148 {
00149   ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_BASE_FIND_START);
00150   return this->optable_->find (opname, skelfunc, st, length);
00151 }
00152 
00153 TAO_Stub *
00154 TAO_ServantBase::_create_stub (ACE_ENV_SINGLE_ARG_DECL)
00155 {
00156   TAO_Stub *stub = 0;
00157 
00158   TAO::Portable_Server::POA_Current_Impl *poa_current_impl =
00159     static_cast<TAO::Portable_Server::POA_Current_Impl *>
00160                     (TAO_TSS_Resources::instance ()->poa_current_impl_);
00161 
00162   CORBA::ORB_ptr servant_orb = 0;
00163 
00164   if (poa_current_impl != 0
00165       && this == poa_current_impl->servant ())
00166     {
00167       servant_orb = poa_current_impl->orb_core ().orb () ;
00168 
00169       stub =
00170         poa_current_impl->poa ()->key_to_stub (
00171             poa_current_impl->object_key (),
00172             this->_interface_repository_id (),
00173             poa_current_impl->priority ()
00174             ACE_ENV_ARG_PARAMETER
00175           );
00176       ACE_CHECK_RETURN (0);
00177     }
00178   else
00179     {
00180       PortableServer::POA_var poa =
00181         this->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER);
00182       ACE_CHECK_RETURN (0);
00183 
00184       CORBA::Object_var object =
00185         poa->servant_to_reference (this ACE_ENV_ARG_PARAMETER);
00186       ACE_CHECK_RETURN (0);
00187 
00188       // Get the stub object
00189       stub = object->_stubobj ();
00190 
00191       // Increment the reference count since <object> will zap its
00192       // stub object on deletion.
00193       stub->_incr_refcnt ();
00194 
00195       servant_orb = stub->orb_core ()->orb ();
00196     }
00197 
00198   stub->servant_orb (servant_orb);
00199   return stub;
00200 }
00201 
00202 void TAO_ServantBase::synchronous_upcall_dispatch (TAO_ServerRequest & req,
00203                                                    void * servant_upcall,
00204                                                    void * derived_this
00205                                                    ACE_ENV_ARG_DECL)
00206 {
00207   TAO_Skeleton skel;
00208   char const * const opname = req.operation ();
00209 
00210   // It seems that I might have missed s/g here.  What if
00211   // it is a one way that is SYNC_WITH_SERVER.
00212   // Add the following line to handle this reply send as well.
00213 
00214   // Handle the one ways that are SYNC_WITH_SERVER and not collocated
00215   if (req.sync_with_server () && !req.collocated ())
00216     {
00217       req.send_no_exception_reply ();
00218     }
00219 
00220   // Fetch the skeleton for this operation
00221   if (this->_find (opname,
00222                    skel,
00223                    static_cast <unsigned int> (req.operation_length())) == -1)
00224     {
00225       ACE_THROW (CORBA::BAD_OPERATION ());
00226     }
00227 
00228   CORBA::Boolean const send_reply =
00229     !req.sync_with_server ()
00230     && req.response_expected ()
00231     && !req.deferred_reply ();
00232 
00233   ACE_TRY
00234     {
00235       // Invoke the skeleton, it will demarshal the arguments, invoke
00236       // the right operation on the skeleton class, and marshal any
00237       // results.  De/marshaling will only occur in the uncollocated
00238       // case.
00239       skel (req,
00240             servant_upcall,
00241             derived_this
00242             ACE_ENV_ARG_PARAMETER);
00243       ACE_TRY_CHECK;
00244 
00245       /*
00246        * Dispatch resolution specialization add hook.
00247        * Over-ridden with code to handle optimized dispatch.
00248        */
00249       //@@ TAO_DISPATCH_RESOLUTION_OPT_ADD_HOOK
00250 
00251       // It is our job to send the already marshaled reply, but only
00252       // send if it is expected and it has not already been sent
00253 
00254       // We send the reply only if it is NOT a SYNC_WITH_SERVER, a
00255       // response is expected and if the reply is not deferred.
00256       if (send_reply)
00257         {
00258           req.tao_send_reply ();
00259         }
00260     }
00261   ACE_CATCHANY
00262     {
00263       // If an exception was raised we should marshal it and send
00264       // the appropriate reply to the client
00265       if (send_reply)
00266         {
00267           if (req.collocated ())
00268             {
00269               // Report the exception to the collocated client.
00270               ACE_RE_THROW;
00271             }
00272           else
00273             req.tao_send_reply_exception (ACE_ANY_EXCEPTION);
00274         }
00275     }
00276   ACE_ENDTRY;
00277   ACE_CHECK;
00278 
00279   return;
00280 }
00281 
00282 void TAO_ServantBase::asynchronous_upcall_dispatch (TAO_ServerRequest & req,
00283                                                     void * servant_upcall,
00284                                                     void * derived_this
00285                                                     ACE_ENV_ARG_DECL)
00286 {
00287   TAO_Skeleton skel;
00288   const char *opname = req.operation ();
00289 
00290   // It seems that I might have missed s/g here.  What if
00291   // it is a one way that is SYNC_WITH_SERVER.
00292   // Add the following line to handle this reply send as well.
00293 
00294   // Handle the one ways that are SYNC_WITH_SERVER
00295   if (req.sync_with_server ())
00296     {
00297       req.send_no_exception_reply ();
00298     }
00299 
00300   // Fetch the skeleton for this operation
00301   if (this->_find (opname,
00302                    skel,
00303                    static_cast <unsigned int> (req.operation_length())) == -1)
00304     {
00305       ACE_THROW (CORBA::BAD_OPERATION ());
00306     }
00307 
00308   ACE_TRY
00309     {
00310       // Invoke the skeleton, it will demarshal the arguments, invoke
00311       // the right operation on the skeleton class, and marshal any
00312       // results.  De/marshaling will only occur in the uncollocated
00313       // case.
00314       skel (req,
00315             servant_upcall,
00316             derived_this
00317             ACE_ENV_ARG_PARAMETER);
00318       ACE_TRY_CHECK;
00319 
00320       // It is our job to send the already marshaled reply, but only
00321       // send if it is expected and it has not already been sent
00322 
00323       // Return immediately. Do not send a reply; this is an
00324       // asynchronous upcall. (unless, of course there is a system
00325       // exception.
00326 
00327     }
00328   ACE_CATCHANY
00329     {
00330       // If an exception was raised we should marshal it and send
00331       // the appropriate reply to the client
00332       req.tao_send_reply_exception (ACE_ANY_EXCEPTION);
00333     }
00334   ACE_ENDTRY;
00335   ACE_CHECK;
00336 
00337   return;
00338 }
00339 
00340 void
00341 TAO_ServantBase::_add_ref (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00342 {
00343   ++this->ref_count_;
00344 }
00345 
00346 void
00347 TAO_ServantBase::_remove_ref (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00348 {
00349   long const new_count = --this->ref_count_;
00350 
00351   if (new_count == 0)
00352     delete this;
00353 }
00354 
00355 CORBA::ULong
00356 TAO_ServantBase::_refcount_value (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) const
00357 {
00358   return static_cast<CORBA::ULong> (this->ref_count_.value ());
00359 }
00360 
00361 // -------------------------------------------------------------------
00362 
00363 TAO_ServantBase_var::TAO_ServantBase_var (const TAO_ServantBase_var &b)
00364   : ptr_ (b.ptr_)
00365 {
00366   if (this->ptr_ != 0)
00367     {
00368       ACE_TRY_NEW_ENV
00369         {
00370           this->ptr_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00371           ACE_TRY_CHECK;
00372         }
00373       ACE_CATCHALL
00374         {
00375           ACE_RE_THROW;
00376         }
00377       ACE_ENDTRY;
00378     }
00379 }
00380 
00381 TAO_ServantBase_var::~TAO_ServantBase_var (void)
00382 {
00383   if (this->ptr_ != 0)
00384     {
00385       // We should not allow exceptions to pass through
00386       ACE_TRY_NEW_ENV
00387         {
00388           this->ptr_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00389           ACE_TRY_CHECK;
00390         }
00391       ACE_CATCHALL
00392         {
00393         }
00394       ACE_ENDTRY;
00395     }
00396 }
00397 
00398 TAO_ServantBase_var &
00399 TAO_ServantBase_var::operator= (TAO_ServantBase *p)
00400 {
00401   if (this->ptr_ == p)
00402     return *this;
00403 
00404   ACE_TRY_NEW_ENV
00405     {
00406       if (this->ptr_ != 0)
00407         {
00408           this->ptr_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00409           ACE_TRY_CHECK;
00410         }
00411     }
00412   ACE_CATCHALL
00413     {
00414       ACE_RE_THROW;
00415     }
00416   ACE_ENDTRY;
00417 
00418   this->ptr_ = p;
00419 
00420   return *this;
00421 }
00422 
00423 TAO_ServantBase_var &
00424 TAO_ServantBase_var::operator= (const TAO_ServantBase_var &b)
00425 {
00426   if (this->ptr_ != b.ptr_)
00427     {
00428       ACE_TRY_NEW_ENV
00429         {
00430           if (this->ptr_ != 0)
00431             {
00432               this->ptr_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00433               ACE_TRY_CHECK;
00434             }
00435 
00436           if ((this->ptr_ = b.ptr_) != 0)
00437             {
00438               this->ptr_->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00439               ACE_TRY_CHECK;
00440             }
00441         }
00442       ACE_CATCHALL
00443         {
00444           ACE_RE_THROW;
00445         }
00446       ACE_ENDTRY;
00447     }
00448 
00449   return *this;
00450 }
00451 
00452 TAO_ServantBase *&
00453 TAO_ServantBase_var::out (void)
00454 {
00455   ACE_TRY_NEW_ENV
00456     {
00457       if (this->ptr_ != 0)
00458         {
00459           this->ptr_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
00460           ACE_TRY_CHECK;
00461         }
00462     }
00463   ACE_CATCHALL
00464     {
00465       ACE_RE_THROW;
00466     }
00467   ACE_ENDTRY;
00468 
00469   this->ptr_ = 0;
00470 
00471   return this->ptr_;
00472 }
00473 
00474 TAO_ServantBase *
00475 TAO_ServantBase_var::_retn (void)
00476 {
00477   TAO_ServantBase *retval = this->ptr_;
00478   this->ptr_ = 0;
00479   return retval;
00480 }
00481 
00482 TAO_END_VERSIONED_NAMESPACE_DECL

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