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 "Servant_Upcall.cpp,v 1.9 2006/06/20 07:16:51 jwillemsen Exp")
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_ (),
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 ACE_ENV_ARG_DECL)
00057 {
00058 while (1)
00059 {
00060 int wait_occurred_restart_call = 0;
00061
00062 int result =
00063 this->prepare_for_upcall_i (key,
00064 operation,
00065 forward_to,
00066 wait_occurred_restart_call
00067 ACE_ENV_ARG_PARAMETER);
00068 ACE_CHECK_RETURN (TAO_Adapter::DS_FAILED);
00069
00070 if (result == TAO_Adapter::DS_FAILED &&
00071 wait_occurred_restart_call)
00072 {
00073
00074
00075
00076
00077
00078 this->upcall_cleanup ();
00079 continue;
00080 }
00081 else
00082 {
00083 return result;
00084 }
00085 }
00086 }
00087
00088 int
00089 Servant_Upcall::prepare_for_upcall_i (
00090 const TAO::ObjectKey &key,
00091 const char *operation,
00092 CORBA::Object_out forward_to,
00093 int &wait_occurred_restart_call
00094 ACE_ENV_ARG_DECL)
00095 {
00096
00097 int result = this->object_adapter_->lock ().acquire ();
00098 if (result == -1)
00099
00100 ACE_THROW_RETURN (CORBA::OBJ_ADAPTER (),
00101 TAO_Adapter::DS_FAILED);
00102
00103
00104
00105 this->state_ = OBJECT_ADAPTER_LOCK_ACQUIRED;
00106
00107
00108
00109
00110 this->object_adapter_->wait_for_non_servant_upcalls_to_complete (
00111 ACE_ENV_SINGLE_ARG_PARAMETER);
00112 ACE_CHECK_RETURN (TAO_Adapter::DS_FAILED);
00113
00114
00115 this->object_adapter_->locate_poa (key,
00116 this->system_id_,
00117 this->poa_
00118 ACE_ENV_ARG_PARAMETER);
00119 ACE_CHECK_RETURN (TAO_Adapter::DS_FAILED);
00120
00121
00122 this->poa_->check_state (ACE_ENV_SINGLE_ARG_PARAMETER);
00123 ACE_CHECK_RETURN (TAO_Adapter::DS_FAILED);
00124
00125
00126 this->current_context_.setup (this->poa_,
00127 key);
00128
00129
00130
00131 this->poa_->increment_outstanding_requests ();
00132
00133
00134 this->state_ = POA_CURRENT_SETUP;
00135
00136 ACE_TRY
00137 {
00138
00139 this->servant_ =
00140 this->poa_->locate_servant_i (operation,
00141 this->system_id_,
00142 *this,
00143 this->current_context_,
00144 wait_occurred_restart_call
00145 ACE_ENV_ARG_PARAMETER);
00146 ACE_TRY_CHECK;
00147
00148 if (wait_occurred_restart_call)
00149 return TAO_Adapter::DS_FAILED;
00150 }
00151 #if (TAO_HAS_MINIMUM_CORBA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
00152 ACE_CATCH (PortableServer::ForwardRequest, forward_request)
00153 {
00154 forward_to =
00155 CORBA::Object::_duplicate (forward_request.forward_reference.in ());
00156 return TAO_Adapter::DS_FORWARD;
00157 }
00158 #else
00159 ACE_CATCHANY
00160 {
00161 ACE_UNUSED_ARG (forward_to);
00162 ACE_RE_THROW;
00163 }
00164 #endif
00165 ACE_ENDTRY;
00166
00167
00168 this->current_context_.servant (this->servant_);
00169
00170
00171
00172 if (this->active_object_map_entry ())
00173 this->current_context_.priority (this->active_object_map_entry ()->priority_);
00174
00175 if (this->state_ != OBJECT_ADAPTER_LOCK_RELEASED)
00176 {
00177
00178 this->object_adapter_->lock ().release ();
00179
00180
00181
00182 this->state_ = OBJECT_ADAPTER_LOCK_RELEASED;
00183 }
00184
00185
00186 this->single_threaded_poa_setup (ACE_ENV_SINGLE_ARG_PARAMETER);
00187 ACE_CHECK_RETURN (TAO_Adapter::DS_FAILED);
00188
00189
00190 this->state_ = SERVANT_LOCK_ACQUIRED;
00191
00192
00193 return TAO_Adapter::DS_OK;
00194 }
00195
00196 void
00197 Servant_Upcall::pre_invoke_remote_request (
00198 TAO_ServerRequest &req
00199 ACE_ENV_ARG_DECL)
00200 {
00201 this->object_adapter_->servant_dispatcher_->pre_invoke_remote_request (
00202 this->poa (),
00203 this->priority (),
00204 req,
00205 this->pre_invoke_state_
00206 ACE_ENV_ARG_PARAMETER);
00207 ACE_CHECK;
00208 }
00209
00210 void
00211 Servant_Upcall::pre_invoke_collocated_request (
00212 ACE_ENV_SINGLE_ARG_DECL)
00213 {
00214 this->object_adapter_->servant_dispatcher_->pre_invoke_collocated_request (
00215 this->poa (),
00216 this->priority (),
00217 this->pre_invoke_state_
00218 ACE_ENV_ARG_PARAMETER);
00219 ACE_CHECK;
00220 }
00221
00222 void
00223 Servant_Upcall::post_invoke (void)
00224 {
00225 this->object_adapter_->servant_dispatcher_->post_invoke (
00226 this->poa (),
00227 this->pre_invoke_state_);
00228 }
00229
00230 Servant_Upcall::Pre_Invoke_State::Pre_Invoke_State (void)
00231 : state_ (NO_ACTION_REQUIRED),
00232 original_native_priority_ (0),
00233 original_CORBA_priority_ (0)
00234 {
00235 }
00236
00237 ::TAO_Root_POA *
00238 Servant_Upcall::lookup_POA (const TAO::ObjectKey &key
00239 ACE_ENV_ARG_DECL)
00240 {
00241
00242 int result = this->object_adapter_->lock ().acquire ();
00243 if (result == -1)
00244
00245 ACE_THROW_RETURN (CORBA::OBJ_ADAPTER (),
00246 0);
00247
00248
00249
00250 this->state_ = OBJECT_ADAPTER_LOCK_ACQUIRED;
00251
00252
00253
00254
00255 this->object_adapter_->wait_for_non_servant_upcalls_to_complete (
00256 ACE_ENV_SINGLE_ARG_PARAMETER);
00257 ACE_CHECK_RETURN (0);
00258
00259
00260 this->object_adapter_->locate_poa (key,
00261 this->system_id_,
00262 this->poa_
00263 ACE_ENV_ARG_PARAMETER);
00264 ACE_CHECK_RETURN (0);
00265
00266 return this->poa_;
00267 }
00268
00269 Servant_Upcall::~Servant_Upcall (void)
00270 {
00271 this->upcall_cleanup ();
00272 }
00273
00274 void
00275 Servant_Upcall::upcall_cleanup (void)
00276 {
00277 this->post_invoke ();
00278
00279 switch (this->state_)
00280 {
00281 case SERVANT_LOCK_ACQUIRED:
00282
00283 this->single_threaded_poa_cleanup ();
00284
00285
00286
00287 case OBJECT_ADAPTER_LOCK_RELEASED:
00288
00289
00290
00291 this->post_invoke_servant_cleanup ();
00292
00293
00294
00295
00296
00297
00298 this->object_adapter_->lock ().acquire ();
00299
00300
00301
00302
00303
00304 this->object_adapter_->wait_for_non_servant_upcalls_to_complete ();
00305
00306
00307 this->servant_cleanup ();
00308
00309
00310
00311 case POA_CURRENT_SETUP:
00312
00313 this->poa_cleanup ();
00314
00315
00316 this->current_context_.teardown ();
00317
00318
00319
00320 case OBJECT_ADAPTER_LOCK_ACQUIRED:
00321
00322
00323 this->object_adapter_->lock ().release ();
00324
00325
00326
00327 case INITIAL_STAGE:
00328 default:
00329
00330
00331 break;
00332 }
00333 }
00334
00335 void
00336 Servant_Upcall::post_invoke_servant_cleanup (void)
00337 {
00338 this->poa_->post_invoke_servant_cleanup (this->current_context_.object_id (),
00339 *this);
00340 }
00341
00342 void
00343 Servant_Upcall::single_threaded_poa_setup (ACE_ENV_SINGLE_ARG_DECL)
00344 {
00345 #if (TAO_HAS_MINIMUM_POA == 0)
00346
00347
00348
00349
00350
00351
00352
00353
00354 int result = this->poa_->enter();
00355
00356 if (result == -1)
00357
00358 ACE_THROW (CORBA::OBJ_ADAPTER ());
00359 #else
00360 ACE_ENV_ARG_NOT_USED;
00361 #endif
00362 }
00363
00364 void
00365 Servant_Upcall::single_threaded_poa_cleanup (void)
00366 {
00367 #if (TAO_HAS_MINIMUM_POA == 0)
00368 int result = 0;
00369
00370
00371 result = this->poa_->exit ();
00372
00373 ACE_UNUSED_ARG (result);
00374 #endif
00375 }
00376
00377 void
00378 Servant_Upcall::increment_servant_refcount (void)
00379 {
00380
00381 if (this->active_object_map_entry_ != 0)
00382 ++this->active_object_map_entry_->reference_count_;
00383 }
00384
00385 void
00386 Servant_Upcall::servant_cleanup (void)
00387 {
00388
00389 if (this->active_object_map_entry_ != 0)
00390 {
00391
00392 CORBA::UShort new_count =
00393 --this->active_object_map_entry_->reference_count_;
00394
00395 if (new_count == 0)
00396 {
00397 ACE_DECLARE_NEW_CORBA_ENV;
00398 ACE_TRY
00399 {
00400 this->poa_->cleanup_servant (
00401 this->active_object_map_entry_->servant_,
00402 this->active_object_map_entry_->user_id_
00403 ACE_ENV_ARG_PARAMETER);
00404
00405 ACE_TRY_CHECK;
00406 }
00407 ACE_CATCHALL
00408 {
00409
00410 }
00411 ACE_ENDTRY;
00412
00413 if (this->poa_->waiting_servant_deactivation() > 0 &&
00414 this->object_adapter_->enable_locking_)
00415 {
00416
00417 this->poa_->servant_deactivation_condition_.broadcast ();
00418 }
00419 }
00420 }
00421 }
00422
00423 void
00424 Servant_Upcall::poa_cleanup (void)
00425 {
00426
00427
00428
00429
00430
00431 CORBA::ULong outstanding_requests =
00432 this->poa_->decrement_outstanding_requests ();
00433
00434
00435 if (outstanding_requests == 0)
00436 {
00437
00438 if (this->object_adapter_->enable_locking_ &&
00439 this->poa_->wait_for_completion_pending_)
00440 {
00441
00442 this->poa_->outstanding_requests_condition_.broadcast ();
00443 }
00444
00445
00446
00447
00448 if (this->poa_->waiting_destruction_)
00449 {
00450 ACE_DECLARE_NEW_CORBA_ENV;
00451
00452 ACE_TRY
00453 {
00454 this->poa_->complete_destruction_i (ACE_ENV_SINGLE_ARG_PARAMETER);
00455 ACE_TRY_CHECK;
00456 }
00457 ACE_CATCHANY
00458 {
00459
00460 ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
00461 "TAO_POA::~complete_destruction_i");
00462 }
00463 ACE_ENDTRY;
00464 ACE_CHECK;
00465
00466 this->poa_ = 0;
00467 }
00468 }
00469 }
00470 }
00471 }
00472
00473 TAO_END_VERSIONED_NAMESPACE_DECL