Go to the documentation of this file.00001
00002
00003 #include "tao/PortableServer/Object_Adapter.h"
00004 #include "tao/PortableServer/Servant_Upcall.h"
00005 #include "tao/PortableServer/Root_POA.h"
00006 #include "tao/PortableServer/Default_Servant_Dispatcher.h"
00007 #include "tao/PortableServer/Collocated_Object_Proxy_Broker.h"
00008 #include "tao/PortableServer/Active_Object_Map_Entry.h"
00009 #include "tao/PortableServer/ForwardRequestC.h"
00010
00011
00012 #include "tao/ORB.h"
00013 #include "tao/ORB_Core.h"
00014 #include "tao/debug.h"
00015
00016 #if !defined (__ACE_INLINE__)
00017 # include "tao/PortableServer/Servant_Upcall.inl"
00018 #endif
00019
00020 #include "ace/OS_NS_string.h"
00021
00022 ACE_RCSID (PortableServer,
00023 Servant_Upcall,
00024 "$Id: Servant_Upcall.cpp 77293 2007-02-21 14:48:22Z johnnyw $")
00025
00026 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00027
00028 namespace TAO
00029 {
00030 namespace Portable_Server
00031 {
00032 Servant_Upcall::Servant_Upcall (TAO_ORB_Core *oc)
00033 : object_adapter_ (0),
00034 poa_ (0),
00035 servant_ (0),
00036 state_ (INITIAL_STAGE),
00037 system_id_ (TAO_POA_OBJECT_ID_BUF_SIZE, 0, system_id_buf_),
00038 user_id_ (0),
00039 current_context_ (),
00040 #if (TAO_HAS_MINIMUM_POA == 0)
00041 cookie_ (0),
00042 operation_ (0),
00043 #endif
00044 active_object_map_entry_ (0)
00045 {
00046 TAO_Object_Adapter *object_adapter =
00047 dynamic_cast<TAO_Object_Adapter *>(oc->poa_adapter ());
00048 this->object_adapter_ = object_adapter;
00049 }
00050
00051 int
00052 Servant_Upcall::prepare_for_upcall (
00053 const TAO::ObjectKey &key,
00054 const char *operation,
00055 CORBA::Object_out forward_to)
00056 {
00057 while (1)
00058 {
00059 bool wait_occurred_restart_call = false;
00060
00061 int result =
00062 this->prepare_for_upcall_i (key,
00063 operation,
00064 forward_to,
00065 wait_occurred_restart_call);
00066
00067 if (result == TAO_Adapter::DS_FAILED &&
00068 wait_occurred_restart_call)
00069 {
00070
00071
00072
00073
00074
00075 this->upcall_cleanup ();
00076 continue;
00077 }
00078 else
00079 {
00080 return result;
00081 }
00082 }
00083 }
00084
00085 int
00086 Servant_Upcall::prepare_for_upcall_i (
00087 const TAO::ObjectKey &key,
00088 const char *operation,
00089 CORBA::Object_out forward_to,
00090 bool &wait_occurred_restart_call)
00091 {
00092
00093 int result = this->object_adapter_->lock ().acquire ();
00094 if (result == -1)
00095
00096 throw ::CORBA::OBJ_ADAPTER ();
00097
00098
00099
00100 this->state_ = OBJECT_ADAPTER_LOCK_ACQUIRED;
00101
00102
00103
00104
00105 this->object_adapter_->wait_for_non_servant_upcalls_to_complete ();
00106
00107
00108 this->object_adapter_->locate_poa (key, this->system_id_, this->poa_);
00109
00110
00111 this->poa_->check_state ();
00112
00113
00114 this->current_context_.setup (this->poa_, key);
00115
00116
00117
00118 this->poa_->increment_outstanding_requests ();
00119
00120
00121 this->state_ = POA_CURRENT_SETUP;
00122
00123 #if (TAO_HAS_MINIMUM_CORBA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
00124 try
00125 {
00126 #endif
00127
00128 this->servant_ =
00129 this->poa_->locate_servant_i (operation,
00130 this->system_id_,
00131 *this,
00132 this->current_context_,
00133 wait_occurred_restart_call);
00134
00135 if (wait_occurred_restart_call)
00136 return TAO_Adapter::DS_FAILED;
00137 #if (TAO_HAS_MINIMUM_CORBA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
00138 }
00139 catch (const ::PortableServer::ForwardRequest& forward_request)
00140 {
00141 forward_to =
00142 CORBA::Object::_duplicate (forward_request.forward_reference.in ());
00143 return TAO_Adapter::DS_FORWARD;
00144 }
00145 #else
00146 ACE_UNUSED_ARG (forward_to);
00147 #endif
00148
00149
00150 this->current_context_.servant (this->servant_);
00151
00152
00153
00154 if (this->active_object_map_entry ())
00155 this->current_context_.priority (this->active_object_map_entry ()->priority_);
00156
00157 if (this->state_ != OBJECT_ADAPTER_LOCK_RELEASED)
00158 {
00159
00160 this->object_adapter_->lock ().release ();
00161
00162
00163
00164 this->state_ = OBJECT_ADAPTER_LOCK_RELEASED;
00165 }
00166
00167
00168 this->single_threaded_poa_setup ();
00169
00170
00171 this->state_ = SERVANT_LOCK_ACQUIRED;
00172
00173
00174 return TAO_Adapter::DS_OK;
00175 }
00176
00177 void
00178 Servant_Upcall::pre_invoke_remote_request (TAO_ServerRequest &req)
00179 {
00180 this->object_adapter_->servant_dispatcher_->pre_invoke_remote_request (
00181 this->poa (),
00182 this->priority (),
00183 req,
00184 this->pre_invoke_state_);
00185 }
00186
00187 void
00188 Servant_Upcall::pre_invoke_collocated_request (void)
00189 {
00190 this->object_adapter_->servant_dispatcher_->pre_invoke_collocated_request (
00191 this->poa (),
00192 this->priority (),
00193 this->pre_invoke_state_);
00194 }
00195
00196 void
00197 Servant_Upcall::post_invoke (void)
00198 {
00199 this->object_adapter_->servant_dispatcher_->post_invoke (
00200 this->poa (),
00201 this->pre_invoke_state_);
00202 }
00203
00204 Servant_Upcall::Pre_Invoke_State::Pre_Invoke_State (void)
00205 : state_ (NO_ACTION_REQUIRED),
00206 original_native_priority_ (0),
00207 original_CORBA_priority_ (0)
00208 {
00209 }
00210
00211 ::TAO_Root_POA *
00212 Servant_Upcall::lookup_POA (const TAO::ObjectKey &key)
00213 {
00214
00215 if (this->object_adapter_->lock ().acquire () == -1)
00216
00217 throw ::CORBA::OBJ_ADAPTER ();
00218
00219
00220
00221 this->state_ = OBJECT_ADAPTER_LOCK_ACQUIRED;
00222
00223
00224
00225
00226 this->object_adapter_->wait_for_non_servant_upcalls_to_complete ();
00227
00228
00229 this->object_adapter_->locate_poa (key, this->system_id_, this->poa_);
00230
00231 return this->poa_;
00232 }
00233
00234 Servant_Upcall::~Servant_Upcall (void)
00235 {
00236 this->upcall_cleanup ();
00237 }
00238
00239 void
00240 Servant_Upcall::upcall_cleanup (void)
00241 {
00242 this->post_invoke ();
00243
00244 switch (this->state_)
00245 {
00246 case SERVANT_LOCK_ACQUIRED:
00247
00248 this->single_threaded_poa_cleanup ();
00249
00250
00251
00252 case OBJECT_ADAPTER_LOCK_RELEASED:
00253
00254
00255
00256 this->post_invoke_servant_cleanup ();
00257
00258
00259
00260
00261
00262
00263 this->object_adapter_->lock ().acquire ();
00264
00265
00266
00267
00268
00269 this->object_adapter_->wait_for_non_servant_upcalls_to_complete_no_throw ();
00270
00271
00272 this->servant_cleanup ();
00273
00274
00275
00276 case POA_CURRENT_SETUP:
00277
00278 this->poa_cleanup ();
00279
00280
00281 this->current_context_.teardown ();
00282
00283
00284
00285 case OBJECT_ADAPTER_LOCK_ACQUIRED:
00286
00287
00288 this->object_adapter_->lock ().release ();
00289
00290
00291
00292 case INITIAL_STAGE:
00293 default:
00294
00295
00296 break;
00297 }
00298 }
00299
00300 void
00301 Servant_Upcall::post_invoke_servant_cleanup (void)
00302 {
00303 this->poa_->post_invoke_servant_cleanup (this->current_context_.object_id (),
00304 *this);
00305 }
00306
00307 void
00308 Servant_Upcall::single_threaded_poa_setup (void)
00309 {
00310 #if (TAO_HAS_MINIMUM_POA == 0)
00311
00312
00313
00314
00315
00316
00317
00318
00319 if (this->poa_->enter() == -1)
00320
00321 throw ::CORBA::OBJ_ADAPTER ();
00322 #endif
00323 }
00324
00325 void
00326 Servant_Upcall::single_threaded_poa_cleanup (void)
00327 {
00328 #if (TAO_HAS_MINIMUM_POA == 0)
00329
00330 int const result = this->poa_->exit ();
00331
00332 ACE_UNUSED_ARG (result);
00333 #endif
00334 }
00335
00336 void
00337 Servant_Upcall::increment_servant_refcount (void)
00338 {
00339
00340 if (this->active_object_map_entry_ != 0)
00341 ++this->active_object_map_entry_->reference_count_;
00342 }
00343
00344 void
00345 Servant_Upcall::servant_cleanup (void)
00346 {
00347
00348 if (this->active_object_map_entry_ != 0)
00349 {
00350
00351 CORBA::UShort const new_count =
00352 --this->active_object_map_entry_->reference_count_;
00353
00354 if (new_count == 0)
00355 {
00356 try
00357 {
00358 this->poa_->cleanup_servant (
00359 this->active_object_map_entry_->servant_,
00360 this->active_object_map_entry_->user_id_);
00361
00362 }
00363 catch (...)
00364 {
00365
00366 }
00367
00368 if (this->poa_->waiting_servant_deactivation() > 0 &&
00369 this->object_adapter_->enable_locking_)
00370 {
00371
00372 this->poa_->servant_deactivation_condition_.broadcast ();
00373 }
00374 }
00375 }
00376 }
00377
00378 void
00379 Servant_Upcall::poa_cleanup (void)
00380 {
00381
00382
00383
00384
00385
00386 CORBA::ULong outstanding_requests =
00387 this->poa_->decrement_outstanding_requests ();
00388
00389
00390 if (outstanding_requests == 0)
00391 {
00392
00393 if (this->object_adapter_->enable_locking_ &&
00394 this->poa_->wait_for_completion_pending_)
00395 {
00396
00397 this->poa_->outstanding_requests_condition_.broadcast ();
00398 }
00399
00400
00401
00402
00403 if (this->poa_->waiting_destruction_)
00404 {
00405 try
00406 {
00407 this->poa_->complete_destruction_i ();
00408 }
00409 catch (const ::CORBA::Exception& ex)
00410 {
00411
00412 ex._tao_print_exception ("TAO_POA::~complete_destruction_i");
00413 }
00414
00415 this->poa_ = 0;
00416 }
00417 }
00418 }
00419 }
00420 }
00421
00422 TAO_END_VERSIONED_NAMESPACE_DECL