00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "tao/Stub.h"
00012 #include "tao/Profile.h"
00013 #include "tao/ORB_Core.h"
00014 #include "tao/Client_Strategy_Factory.h"
00015 #include "tao/Remote_Object_Proxy_Broker.h"
00016 #include "tao/Transport_Queueing_Strategies.h"
00017 #include "tao/debug.h"
00018 #include "tao/Policy_Manager.h"
00019 #include "tao/Policy_Set.h"
00020 #include "tao/SystemException.h"
00021 #include "tao/CDR.h"
00022
00023 #if !defined (__ACE_INLINE__)
00024 # include "tao/Stub.inl"
00025 #endif
00026
00027 #include "ace/Auto_Ptr.h"
00028 #include "ace/CORBA_macros.h"
00029
00030 ACE_RCSID (tao,
00031 TAO_Stub,
00032 "$Id: Stub.cpp 86232 2009-07-24 21:52:20Z dai_y $")
00033
00034 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00035
00036 TAO_Stub::TAO_Stub (const char *repository_id,
00037 const TAO_MProfile &profiles,
00038 TAO_ORB_Core *orb_core)
00039 : type_id (repository_id)
00040 , orb_core_ (orb_core)
00041 , orb_ ()
00042 , is_collocated_ (false)
00043 , servant_orb_ ()
00044 , collocated_servant_ (0)
00045 , object_proxy_broker_ (the_tao_remote_object_proxy_broker ())
00046 , base_profiles_ ((CORBA::ULong) 0)
00047 , forward_profiles_ (0)
00048 , forward_profiles_perm_ (0)
00049 , profile_in_use_ (0)
00050 , profile_lock_ptr_ (0)
00051 , profile_success_ (false)
00052 , refcount_ (1)
00053 #if (TAO_HAS_CORBA_MESSAGING == 1)
00054 , policies_ (0)
00055 #endif
00056 , ior_info_ (0)
00057 , forwarded_ior_info_ (0)
00058 , collocation_opt_ (orb_core->optimize_collocation_objects ())
00059 , forwarded_on_exception_ (false)
00060 {
00061 if (this->orb_core_.get() == 0)
00062 {
00063 if (TAO_debug_level > 0)
00064 {
00065 ACE_DEBUG ((LM_DEBUG,
00066 ACE_TEXT ("TAO: (%P|%t) TAO_Stub created with default ")
00067 ACE_TEXT ("ORB core\n")));
00068 }
00069
00070 this->orb_core_.reset (TAO_ORB_Core_instance ());
00071 }
00072
00073
00074
00075
00076 (void) this->orb_core_->_incr_refcnt ();
00077
00078
00079 this->orb_ = CORBA::ORB::_duplicate (this->orb_core_->orb ());
00080
00081 this->profile_lock_ptr_ =
00082 this->orb_core_->client_factory ()->create_profile_lock ();
00083
00084 this->base_profiles (profiles);
00085 }
00086
00087 TAO_Stub::~TAO_Stub (void)
00088 {
00089 ACE_ASSERT (this->refcount_ == 0);
00090
00091 if (this->forward_profiles_)
00092 reset_profiles ();
00093
00094
00095 delete this->forward_profiles_perm_;
00096
00097 if (this->profile_in_use_ != 0)
00098 {
00099
00100 this->profile_in_use_->_decr_refcnt ();
00101 this->profile_in_use_ = 0;
00102 }
00103
00104 delete this->profile_lock_ptr_;
00105
00106 #if (TAO_HAS_CORBA_MESSAGING == 1)
00107 delete this->policies_;
00108 #endif
00109
00110 delete this->ior_info_;
00111
00112 delete this->forwarded_ior_info_;
00113 }
00114
00115 void
00116 TAO_Stub::add_forward_profiles (const TAO_MProfile &mprofiles,
00117 const CORBA::Boolean permanent_forward)
00118 {
00119
00120
00121 ACE_MT (ACE_GUARD (ACE_Lock,
00122 guard,
00123 *this->profile_lock_ptr_));
00124
00125 if (permanent_forward)
00126 {
00127
00128 this->forward_profiles_perm_ = 0;
00129
00130 this->reset_forward ();
00131 }
00132
00133 TAO_MProfile *now_pfiles = this->forward_profiles_;
00134 if (now_pfiles == 0)
00135 now_pfiles = &this->base_profiles_;
00136
00137 ACE_NEW (this->forward_profiles_,
00138 TAO_MProfile (mprofiles));
00139
00140 if (permanent_forward)
00141
00142 this->forward_profiles_perm_ = this->forward_profiles_;
00143
00144
00145 this->profile_in_use_->forward_to (this->forward_profiles_);
00146
00147
00148 this->forward_profiles_->forward_from (now_pfiles);
00149
00150
00151 this->forward_profiles_->rewind ();
00152
00153
00154
00155 this->profile_success_ = false;
00156 }
00157
00158 int
00159 TAO_Stub::create_ior_info (IOP::IOR *&ior_info, CORBA::ULong &index)
00160 {
00161
00162
00163 ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
00164 guard,
00165 *this->profile_lock_ptr_,
00166 -1));
00167
00168 IOP::IOR *tmp_info = 0;
00169
00170 if (this->forward_profiles_ != 0)
00171 {
00172 if (this->forwarded_ior_info_ == 0)
00173 {
00174 this->get_profile_ior_info (*this->forward_profiles_, tmp_info);
00175
00176 this->forwarded_ior_info_ = tmp_info;
00177 }
00178
00179
00180
00181 for (CORBA::ULong i = 0;
00182 i < this->forward_profiles_->profile_count ();
00183 ++i)
00184 {
00185 if (this->forward_profiles_->get_profile (i)
00186 == this->profile_in_use_)
00187 {
00188 ior_info = this->forwarded_ior_info_;
00189 index = i;
00190 return 0;
00191 }
00192 }
00193 }
00194
00195
00196 if (this->ior_info_ == 0)
00197 {
00198 this->get_profile_ior_info (this->base_profiles_, tmp_info);
00199
00200 this->ior_info_ = tmp_info;
00201 }
00202
00203
00204 for (CORBA::ULong ind = 0;
00205 ind < this->base_profiles_.profile_count ();
00206 ++ind)
00207 {
00208 if (this->base_profiles_.get_profile (ind) == this->profile_in_use_)
00209 {
00210 index = ind;
00211 ior_info = this->ior_info_;
00212 return 0;
00213 }
00214 }
00215
00216
00217 return -1;
00218 }
00219
00220 const TAO::ObjectKey &
00221 TAO_Stub::object_key (void) const
00222 {
00223
00224 if (this->profile_in_use_)
00225 return this->profile_in_use_->object_key ();
00226
00227 if (this->forward_profiles_)
00228 {
00229
00230 ACE_Guard<ACE_Lock> obj (*this->profile_lock_ptr_);
00231
00232 if (obj.locked () != 0 && this->forward_profiles_ != 0)
00233 return this->forward_profiles_->get_profile (0)->object_key ();
00234 }
00235
00236
00237 return this->base_profiles_.get_profile (0)->object_key ();
00238 }
00239
00240 int
00241 TAO_Stub::get_profile_ior_info (TAO_MProfile &profiles, IOP::IOR *&ior_info)
00242 {
00243 ACE_NEW_THROW_EX (ior_info,
00244 IOP::IOR (),
00245 CORBA::NO_MEMORY ());
00246
00247
00248 CORBA::ULong const count = profiles.profile_count ();
00249
00250
00251 ior_info->profiles.length (count);
00252
00253
00254
00255 for (CORBA::ULong index = 0; index < count; ++index)
00256 {
00257 TAO_Profile *prof = profiles.get_profile (index);
00258
00259 IOP::TaggedProfile *tp = prof->create_tagged_profile ();
00260
00261 if (tp == 0)
00262 throw ::CORBA::NO_MEMORY ();
00263 ior_info->profiles[index] = *tp;
00264 }
00265
00266 return 0;
00267 }
00268
00269 void
00270 TAO_Stub::is_collocated (CORBA::Boolean collocated)
00271 {
00272 if (this->is_collocated_ != collocated)
00273 {
00274 if (collocated &&
00275 _TAO_Object_Proxy_Broker_Factory_function_pointer != 0)
00276 {
00277 this->object_proxy_broker_ =
00278 _TAO_Object_Proxy_Broker_Factory_function_pointer ();
00279 }
00280 else
00281 {
00282 this->object_proxy_broker_ = the_tao_remote_object_proxy_broker ();
00283 }
00284 this->is_collocated_ = collocated;
00285 }
00286 }
00287
00288
00289
00290
00291
00292
00293 CORBA::ULong
00294 TAO_Stub::hash (CORBA::ULong max)
00295 {
00296
00297 return this->base_profiles_.hash (max);
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 CORBA::Boolean
00309 TAO_Stub::is_equivalent (CORBA::Object_ptr other_obj)
00310 {
00311 if (CORBA::is_nil (other_obj))
00312 return false;
00313
00314 TAO_Profile * const other_profile = other_obj->_stubobj ()->profile_in_use_;
00315 TAO_Profile * const this_profile = this->profile_in_use_;
00316
00317 if (other_profile == 0 || this_profile == 0)
00318 return false;
00319
00320
00321 return this_profile->is_equivalent (other_profile);
00322 }
00323
00324
00325
00326 TAO_Profile *
00327 TAO_Stub::set_profile_in_use_i (TAO_Profile *pfile)
00328 {
00329 TAO_Profile *const old = this->profile_in_use_;
00330
00331
00332
00333 if (pfile && (pfile->_incr_refcnt () == 0))
00334 {
00335 ACE_ERROR_RETURN ((LM_ERROR,
00336 ACE_TEXT ("(%P|%t) unable to increment profile ref!\n")),
00337 0);
00338 }
00339
00340 this->profile_in_use_ = pfile;
00341
00342 if (old)
00343 old->_decr_refcnt ();
00344
00345 return this->profile_in_use_;
00346 }
00347
00348 void
00349 TAO_Stub::forward_back_one (void)
00350 {
00351 TAO_MProfile *from = forward_profiles_->forward_from ();
00352
00353
00354 if (this->forward_profiles_ != this->forward_profiles_perm_)
00355 delete this->forward_profiles_;
00356
00357
00358
00359 if (from == &this->base_profiles_)
00360 {
00361 this->base_profiles_.get_current_profile ()->forward_to (0);
00362 this->forward_profiles_ = 0;
00363 }
00364 else
00365 {
00366 from->get_current_profile ()->forward_to (0);
00367 this->forward_profiles_ = from;
00368 }
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 #if (TAO_HAS_CORBA_MESSAGING == 1)
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 CORBA::Policy_ptr
00402 TAO_Stub::get_policy (CORBA::PolicyType type)
00403 {
00404
00405
00406
00407 CORBA::Policy_var result;
00408 if (this->policies_ != 0)
00409 {
00410 result = this->policies_->get_policy (type);
00411 }
00412
00413 if (CORBA::is_nil (result.in ()))
00414 {
00415 result = this->orb_core_->get_policy_including_current (type);
00416 }
00417
00418 return result._retn ();
00419 }
00420
00421 CORBA::Policy_ptr
00422 TAO_Stub::get_cached_policy (TAO_Cached_Policy_Type type)
00423 {
00424
00425
00426
00427 CORBA::Policy_var result;
00428 if (this->policies_ != 0)
00429 {
00430 result = this->policies_->get_cached_policy (type);
00431 }
00432
00433 if (CORBA::is_nil (result.in ()))
00434 {
00435 result = this->orb_core_->get_cached_policy_including_current (type);
00436 }
00437
00438 return result._retn ();
00439 }
00440
00441 TAO_Stub *
00442 TAO_Stub::set_policy_overrides (const CORBA::PolicyList & policies,
00443 CORBA::SetOverrideType set_add)
00444 {
00445
00446 auto_ptr<TAO_Policy_Set> policy_manager (
00447 new TAO_Policy_Set (TAO_POLICY_OBJECT_SCOPE));
00448
00449 if (set_add == CORBA::SET_OVERRIDE)
00450 {
00451 policy_manager->set_policy_overrides (policies, set_add);
00452 }
00453 else if (this->policies_ == 0)
00454 {
00455 policy_manager->set_policy_overrides (policies, CORBA::SET_OVERRIDE);
00456 }
00457 else
00458 {
00459 policy_manager->copy_from (this->policies_);
00460
00461 policy_manager->set_policy_overrides (policies, set_add);
00462 }
00463
00464 TAO_Stub* stub = this->orb_core_->create_stub (this->type_id.in (),
00465 this->base_profiles_);
00466
00467 stub->policies_ = policy_manager.release ();
00468
00469
00470 stub->servant_orb (this->servant_orb_var ().in ());
00471
00472 return stub;
00473 }
00474
00475 CORBA::PolicyList *
00476 TAO_Stub::get_policy_overrides (const CORBA::PolicyTypeSeq &types)
00477 {
00478 if (this->policies_ == 0)
00479 {
00480 CORBA::PolicyList *policy_list_ptr = 0;
00481 ACE_NEW_THROW_EX (policy_list_ptr,
00482 CORBA::PolicyList (),
00483 CORBA::NO_MEMORY ());
00484
00485 return policy_list_ptr;
00486 }
00487 else
00488 {
00489 return this->policies_->get_policy_overrides (types);
00490 }
00491 }
00492 #endif
00493
00494 CORBA::Boolean
00495 TAO_Stub::marshal (TAO_OutputCDR &cdr)
00496 {
00497
00498
00499
00500 if ((cdr << this->type_id.in()) == 0)
00501 return 0;
00502
00503 if ( ! this->forward_profiles_perm_)
00504 {
00505 const TAO_MProfile& mprofile = this->base_profiles_;
00506
00507 CORBA::ULong const profile_count = mprofile.profile_count ();
00508 if ((cdr << profile_count) == 0)
00509 return 0;
00510
00511
00512
00513 for (CORBA::ULong i = 0; i < profile_count; ++i)
00514 {
00515 const TAO_Profile* p = mprofile.get_profile (i);
00516 if (p->encode (cdr) == 0)
00517 return 0;
00518 }
00519 }
00520 else
00521 {
00522 ACE_MT (ACE_GUARD_RETURN (ACE_Lock,
00523 guard,
00524 *this->profile_lock_ptr_,
00525 0));
00526
00527 ACE_ASSERT(this->forward_profiles_ !=0);
00528
00529
00530
00531 const TAO_MProfile& mprofile =
00532 this->forward_profiles_perm_
00533 ? *(this->forward_profiles_perm_)
00534 : this->base_profiles_;
00535
00536 CORBA::ULong const profile_count = mprofile.profile_count ();
00537 if ((cdr << profile_count) == 0)
00538 return 0;
00539
00540
00541
00542 for (CORBA::ULong i = 0; i < profile_count; ++i)
00543 {
00544 const TAO_Profile* p = mprofile.get_profile (i);
00545 if (p->encode (cdr) == 0)
00546 return 0;
00547 }
00548
00549
00550 }
00551
00552 return (CORBA::Boolean) cdr.good_bit ();
00553 }
00554
00555 void
00556 TAO_Stub::_incr_refcnt (void)
00557 {
00558 ++this->refcount_;
00559 }
00560
00561 void
00562 TAO_Stub::_decr_refcnt (void)
00563 {
00564 if (--this->refcount_ == 0)
00565 delete this;
00566 }
00567
00568 TAO_END_VERSIONED_NAMESPACE_DECL