Invocation_Adapter.cpp

Go to the documentation of this file.
00001 //Invocation_Adapter.cpp,v 1.27 2006/06/07 09:04:55 jwillemsen Exp
00002 
00003 #include "tao/Invocation_Adapter.h"
00004 #include "tao/Profile_Transport_Resolver.h"
00005 #include "tao/operation_details.h"
00006 #include "tao/Stub.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/Synch_Invocation.h"
00009 #include "tao/debug.h"
00010 #include "tao/Collocated_Invocation.h"
00011 #include "tao/Transport.h"
00012 #include "tao/Transport_Mux_Strategy.h"
00013 #include "tao/Collocation_Proxy_Broker.h"
00014 #include "tao/GIOP_Utils.h"
00015 #if !defined (__ACE_INLINE__)
00016 # include "tao/Invocation_Adapter.inl"
00017 #endif /* __ACE_INLINE__ */
00018 
00019 
00020 ACE_RCSID (tao,
00021            Invocation_Adapter,
00022            "Invocation_Adapter.cpp,v 1.27 2006/06/07 09:04:55 jwillemsen Exp")
00023 
00024 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00025 
00026 namespace TAO
00027 {
00028   Invocation_Adapter::~Invocation_Adapter (void)
00029   {
00030   }
00031 
00032   void
00033   Invocation_Adapter::invoke (TAO::Exception_Data *ex_data,
00034                               unsigned long ex_count
00035                               ACE_ENV_ARG_DECL)
00036   {
00037     // Should stub object be refcounted here?
00038     TAO_Stub *stub =
00039       this->get_stub (ACE_ENV_SINGLE_ARG_PARAMETER);
00040     ACE_CHECK;
00041 
00042     TAO_Operation_Details op_details (this->operation_,
00043                                       this->op_len_,
00044                                       this->number_args_ > 1,
00045                                       this->args_,
00046                                       this->number_args_,
00047                                       ex_data,
00048                                       ex_count);
00049 
00050     this->invoke_i (stub,
00051                     op_details
00052                     ACE_ENV_ARG_PARAMETER);
00053     ACE_CHECK;
00054   }
00055 
00056   void
00057   Invocation_Adapter::invoke_i (TAO_Stub *stub,
00058                                 TAO_Operation_Details &details
00059                                 ACE_ENV_ARG_DECL)
00060   {
00061     // Cache the target to a local variable.
00062     CORBA::Object_var effective_target =
00063       CORBA::Object::_duplicate (this->target_);
00064 
00065     // Initial state
00066     TAO::Invocation_Status status = TAO_INVOKE_START;
00067 
00068     ACE_Time_Value *max_wait_time = 0;
00069 
00070     while (status == TAO_INVOKE_START ||
00071            status == TAO_INVOKE_RESTART)
00072       {
00073         // Default we go to remote
00074         Collocation_Strategy strat = TAO_CS_REMOTE_STRATEGY;
00075 
00076         // If we have a collocated proxy broker we look if we maybe
00077         // can use a collocated invocation.  Similarly, if the
00078         // target object reference contains a pointer to a servant,
00079         // the object reference also refers to a collocated object.
00080         if (cpb_ != 0 || effective_target->_servant () != 0)
00081           {
00082             strat =
00083               TAO_ORB_Core::collocation_strategy (effective_target.in ()
00084                                                   ACE_ENV_ARG_PARAMETER);
00085             ACE_CHECK;
00086           }
00087 
00088         if (strat == TAO_CS_REMOTE_STRATEGY ||
00089             strat == TAO_CS_LAST)
00090           {
00091             status =
00092               this->invoke_remote_i (stub,
00093                                      details,
00094                                      effective_target,
00095                                      max_wait_time
00096                                      ACE_ENV_ARG_PARAMETER);
00097             ACE_CHECK;
00098           }
00099         else
00100           {
00101             if (strat == TAO_CS_THRU_POA_STRATEGY)
00102               {
00103                 (void) this->set_response_flags (stub,
00104                                                  details);
00105               }
00106 
00107             status =
00108               this->invoke_collocated_i (stub,
00109                                          details,
00110                                          effective_target,
00111                                          strat
00112                                          ACE_ENV_ARG_PARAMETER);
00113             ACE_CHECK;
00114           }
00115 
00116         if (status == TAO_INVOKE_RESTART)
00117           {
00118             details.reset_request_service_info ();
00119             details.reset_reply_service_info ();
00120 
00121             if (TAO_debug_level > 2)
00122               {
00123                 ACE_DEBUG ((LM_DEBUG,
00124                   "TAO (%P|%t) - Invocation_Adapter::invoke_i, "
00125                   "handling forwarded locations \n"));
00126               }
00127           }
00128       }
00129   }
00130 
00131   bool
00132   Invocation_Adapter::get_timeout (TAO_Stub *stub,
00133                                    ACE_Time_Value &timeout)
00134   {
00135     bool has_timeout = false;
00136     this->target_->orb_core ()->call_timeout_hook (stub,
00137                                                    has_timeout,
00138                                                    timeout);
00139 
00140     return has_timeout;
00141   }
00142 
00143   TAO_Stub *
00144   Invocation_Adapter::get_stub (ACE_ENV_SINGLE_ARG_DECL) const
00145   {
00146     TAO_Stub * const stub =
00147       this->target_->_stubobj ();
00148 
00149     if (stub == 0)
00150       ACE_THROW_RETURN (CORBA::INTERNAL (
00151                           CORBA::SystemException::_tao_minor_code (
00152                             TAO::VMCID,
00153                             EINVAL),
00154                           CORBA::COMPLETED_NO),
00155                         stub);
00156 
00157     return stub;
00158   }
00159 
00160   Invocation_Status
00161   Invocation_Adapter::invoke_collocated_i (TAO_Stub *stub,
00162                                            TAO_Operation_Details &details,
00163                                            CORBA::Object_var &effective_target,
00164                                            Collocation_Strategy strat
00165                                            ACE_ENV_ARG_DECL)
00166   {
00167     // To make a collocated call we must have a collocated proxy broker, the
00168     // invoke_i() will make sure that we only come here when we have one
00169     ACE_ASSERT (cpb_ != 0
00170                 || (strat == TAO_CS_THRU_POA_STRATEGY
00171                     && effective_target->_servant () != 0));
00172 
00173     // Initial state
00174     TAO::Invocation_Status status = TAO_INVOKE_START;
00175 
00176     Collocated_Invocation coll_inv (this->target_,
00177                                     effective_target.in (),
00178                                     stub,
00179                                     details,
00180                                     this->type_ == TAO_TWOWAY_INVOCATION);
00181 
00182     status =
00183       coll_inv.invoke (this->cpb_,
00184                        strat
00185                        ACE_ENV_ARG_PARAMETER);
00186     ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00187 
00188     if (status == TAO_INVOKE_RESTART &&
00189         coll_inv.is_forwarded ())
00190       {
00191         effective_target =
00192             coll_inv.steal_forwarded_reference ();
00193 
00194 #if TAO_HAS_INTERCEPTORS == 1
00195         const bool is_permanent_forward =
00196             (coll_inv.reply_status() == TAO_GIOP_LOCATION_FORWARD_PERM);
00197 #else
00198         const bool is_permanent_forward = false;
00199 #endif
00200 
00201         (void) this->object_forwarded (effective_target,
00202                                        stub,
00203                                        is_permanent_forward
00204                                        ACE_ENV_ARG_PARAMETER);
00205         ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00206       }
00207 
00208     return status;
00209   }
00210 
00211   void
00212   Invocation_Adapter::set_response_flags (
00213     TAO_Stub *stub,
00214     TAO_Operation_Details &details)
00215   {
00216     switch (this->type_)
00217       {
00218       case TAO_ONEWAY_INVOCATION:
00219         {
00220           // Grab the syncscope policy from the ORB.
00221           Messaging::SyncScope sync_scope;
00222 
00223           bool has_synchronization = false;
00224 
00225           stub->orb_core ()->call_sync_scope_hook (stub,
00226                                                    has_synchronization,
00227                                                    sync_scope);
00228           if (has_synchronization)
00229             details.response_flags (CORBA::Octet (sync_scope));
00230           else
00231             details.response_flags (
00232               CORBA::Octet (Messaging::SYNC_WITH_TRANSPORT));
00233           break;
00234         }
00235       case TAO_TWOWAY_INVOCATION:
00236         {
00237           // @@note: Need to change this to something better. Too many
00238           // hash defines meaning the same things.
00239           details.response_flags (TAO_TWOWAY_RESPONSE_FLAG);
00240           break;
00241         }
00242       }
00243 
00244     return;
00245   }
00246 
00247   Invocation_Status
00248   Invocation_Adapter::invoke_remote_i (TAO_Stub *stub,
00249                                        TAO_Operation_Details &details,
00250                                        CORBA::Object_var &effective_target,
00251                                        ACE_Time_Value *&max_wait_time
00252                                        ACE_ENV_ARG_DECL)
00253   {
00254     ACE_Time_Value tmp_wait_time;
00255     bool is_timeout  =
00256       this->get_timeout (stub,
00257                          tmp_wait_time);
00258 
00259     if (is_timeout)
00260       max_wait_time = &tmp_wait_time;
00261 
00262     (void) this->set_response_flags (stub,
00263                                      details);
00264 
00265     // Create the resolver which will pick (or create) for us a
00266     // transport and a profile from the effective_target.
00267     Profile_Transport_Resolver resolver (
00268       effective_target.in (),
00269       stub,
00270       (details.response_flags () != Messaging::SYNC_NONE));
00271 
00272     resolver.resolve (max_wait_time
00273                       ACE_ENV_ARG_PARAMETER);
00274     ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00275 
00276     // Update the request id now that we have a transport
00277     details.request_id (resolver.transport ()->tms ()->request_id ());
00278 
00279     if (this->type_ == TAO_ONEWAY_INVOCATION)
00280       {
00281         return this->invoke_oneway (details,
00282                                     effective_target,
00283                                     resolver,
00284                                     max_wait_time
00285                                     ACE_ENV_ARG_PARAMETER);
00286       }
00287     else if (this->type_ == TAO_TWOWAY_INVOCATION)
00288       {
00289         return this->invoke_twoway (details,
00290                                     effective_target,
00291                                     resolver,
00292                                     max_wait_time
00293                                     ACE_ENV_ARG_PARAMETER);
00294       }
00295 
00296     return TAO_INVOKE_FAILURE;
00297   }
00298 
00299   Invocation_Status
00300   Invocation_Adapter::invoke_twoway (TAO_Operation_Details &details,
00301                                      CORBA::Object_var &effective_target,
00302                                      Profile_Transport_Resolver &r,
00303                                      ACE_Time_Value *&max_wait_time
00304                                      ACE_ENV_ARG_DECL)
00305   {
00306     // Simple sanity check
00307     if (this->mode_ != TAO_SYNCHRONOUS_INVOCATION ||
00308         this->type_ != TAO_TWOWAY_INVOCATION)
00309       {
00310         ACE_THROW_RETURN (CORBA::INTERNAL (
00311             CORBA::SystemException::_tao_minor_code (
00312                 TAO::VMCID,
00313                 EINVAL),
00314             CORBA::COMPLETED_NO),
00315                           TAO_INVOKE_FAILURE);
00316       }
00317 
00318     TAO::Synch_Twoway_Invocation synch (this->target_,
00319                                         r,
00320                                         details);
00321 
00322     Invocation_Status status =
00323       synch.remote_twoway (max_wait_time
00324                            ACE_ENV_ARG_PARAMETER);
00325     ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00326 
00327     if (status == TAO_INVOKE_RESTART &&
00328         synch.is_forwarded ())
00329       {
00330         effective_target =
00331           synch.steal_forwarded_reference ();
00332 
00333 #if TAO_HAS_INTERCEPTORS == 1
00334         const bool is_permanent_forward =
00335             (synch.reply_status() == TAO_GIOP_LOCATION_FORWARD_PERM);
00336 #else
00337         const bool is_permanent_forward = false;
00338 #endif
00339 
00340         this->object_forwarded (effective_target,
00341                                 r.stub (),
00342                                 is_permanent_forward
00343                                 ACE_ENV_ARG_PARAMETER);
00344         ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00345       }
00346 
00347     return status;
00348   }
00349 
00350   Invocation_Status
00351   Invocation_Adapter::invoke_oneway (TAO_Operation_Details &details,
00352                                      CORBA::Object_var &effective_target,
00353                                      Profile_Transport_Resolver &r,
00354                                      ACE_Time_Value *&max_wait_time
00355                                      ACE_ENV_ARG_DECL)
00356   {
00357     TAO::Synch_Oneway_Invocation synch (this->target_,
00358                                         r,
00359                                         details);
00360 
00361     Invocation_Status s =
00362       synch.remote_oneway (max_wait_time
00363                            ACE_ENV_ARG_PARAMETER);
00364     ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00365 
00366     if (s == TAO_INVOKE_RESTART &&
00367         synch.is_forwarded ())
00368       {
00369         effective_target =
00370           synch.steal_forwarded_reference ();
00371 
00372 #if TAO_HAS_INTERCEPTORS == 1
00373         const bool is_permanent_forward =
00374             (synch.reply_status() == TAO_GIOP_LOCATION_FORWARD_PERM);
00375 #else
00376         const bool is_permanent_forward = false;
00377 #endif
00378         this->object_forwarded (effective_target,
00379                                 r.stub (),
00380                                 is_permanent_forward
00381                                 ACE_ENV_ARG_PARAMETER);
00382         ACE_CHECK_RETURN (TAO_INVOKE_FAILURE);
00383       }
00384 
00385     return s;
00386   }
00387 
00388   void
00389   Invocation_Adapter::object_forwarded (CORBA::Object_var &effective_target,
00390                                         TAO_Stub *stub,
00391                                         CORBA::Boolean permanent_forward
00392                                         ACE_ENV_ARG_DECL)
00393   {
00394     // The object pointer has to be changed to a TAO_Stub pointer
00395     // in order to obtain the profiles.
00396     TAO_Stub *stubobj =
00397       effective_target->_stubobj ();
00398 
00399     if (stubobj == 0)
00400       ACE_THROW (CORBA::INTERNAL (
00401         CORBA::SystemException::_tao_minor_code (
00402           TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
00403           errno),
00404         CORBA::COMPLETED_NO));
00405 
00406 
00407     // Reset the profile in the stubs
00408     stub->add_forward_profiles (stubobj->base_profiles (), permanent_forward);
00409 
00410     if (stub->next_profile () == 0)
00411       ACE_THROW (CORBA::TRANSIENT (
00412         CORBA::SystemException::_tao_minor_code (
00413           TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
00414           errno),
00415         CORBA::COMPLETED_NO));
00416 
00417     return;
00418   }
00419 } // End namespace TAO
00420 
00421 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 11:54:14 2006 for TAO by doxygen 1.3.6