00001
00002
00003 #include "ImR_Locator_i.h"
00004 #include "utils.h"
00005 #include "Iterator.h"
00006 #include "INS_Locator.h"
00007
00008 #include "orbsvcs/Time_Utilities.h"
00009
00010 #include "tao/IORTable/IORTable.h"
00011 #include "tao/PortableServer/PortableServer.h"
00012 #include "tao/ORB_Core.h"
00013 #include "tao/default_ports.h"
00014 #include "tao/Messaging/Messaging.h"
00015 #include "tao/AnyTypeCode/Any.h"
00016
00017 #include "ace/ARGV.h"
00018 #include "ace/OS_NS_sys_time.h"
00019 #include "ace/Vector_T.h"
00020
00021 static const int DEFAULT_START_LIMIT = 1;
00022
00023 static const int PING_RETRY_SCHEDULE[] = {0, 10, 100, 500, 1000, 1000, 1000, 1000, 5000, 5000};
00024
00025 static const ACE_Time_Value DEFAULT_SERVER_TIMEOUT (0, 10 * 1000);
00026
00027
00028
00029
00030 static const ACE_Time_Value DEFAULT_SHUTDOWN_TIMEOUT (0, 5000 * 1000);
00031
00032 static PortableServer::POA_ptr
00033 createPersistentPOA (PortableServer::POA_ptr root_poa, const char* poa_name ACE_ENV_ARG_DECL) {
00034
00035 PortableServer::LifespanPolicy_var life =
00036 root_poa->create_lifespan_policy (PortableServer::PERSISTENT ACE_ENV_ARG_PARAMETER);
00037 ACE_CHECK_RETURN (PortableServer::POA::_nil ());
00038
00039 PortableServer::IdAssignmentPolicy_var assign =
00040 root_poa->create_id_assignment_policy (PortableServer::USER_ID ACE_ENV_ARG_PARAMETER);
00041 ACE_CHECK_RETURN (PortableServer::POA::_nil ());
00042
00043 CORBA::PolicyList pols;
00044 pols.length (2);
00045 pols[0] = PortableServer::LifespanPolicy::_duplicate (life.in ());
00046 pols[1] = PortableServer::IdAssignmentPolicy::_duplicate (assign.in ());
00047
00048 PortableServer::POAManager_var mgr = root_poa->the_POAManager ();
00049 PortableServer::POA_var poa =
00050 root_poa->create_POA (poa_name, mgr.in (), pols ACE_ENV_ARG_PARAMETER);
00051 ACE_CHECK_RETURN (PortableServer::POA::_nil ());
00052
00053 life->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00054 ACE_CHECK_RETURN (PortableServer::POA::_nil ());
00055 assign->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00056 ACE_CHECK_RETURN (PortableServer::POA::_nil ());
00057
00058 return poa._retn ();
00059 }
00060
00061 ImR_Locator_i::ImR_Locator_i (void)
00062 : forwarder_ (*this)
00063 , ins_locator_ (0)
00064 , debug_ (0)
00065 , read_only_ (false)
00066 {
00067
00068
00069
00070 INS_Locator* locator;
00071 ACE_NEW (locator,
00072 INS_Locator (*this));
00073 ins_locator_ = locator;
00074 }
00075
00076 ImR_Locator_i::~ImR_Locator_i (void)
00077 {
00078
00079
00080
00081
00082
00083 }
00084
00085 int
00086 ImR_Locator_i::init_with_orb (CORBA::ORB_ptr orb, Options& opts ACE_ENV_ARG_DECL)
00087 {
00088 orb_ = CORBA::ORB::_duplicate (orb);
00089 debug_ = opts.debug ();
00090 read_only_ = opts.readonly ();
00091 startup_timeout_ = opts.startup_timeout ();
00092 ping_interval_ = opts.ping_interval ();
00093
00094 CORBA::Object_var obj =
00095 this->orb_->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER);
00096 ACE_CHECK_RETURN (-1);
00097 this->root_poa_ = PortableServer::POA::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
00098 ACE_CHECK_RETURN (-1);
00099 ACE_ASSERT (! CORBA::is_nil (this->root_poa_.in ()));
00100
00101 this->forwarder_.init (orb ACE_ENV_ARG_PARAMETER);
00102 this->adapter_.init (& this->forwarder_);
00103
00104
00105
00106 root_poa_->the_activator (&this->adapter_ ACE_ENV_ARG_PARAMETER);
00107 ACE_CHECK_RETURN (-1);
00108
00109
00110 this->imr_poa_ = createPersistentPOA (this->root_poa_.in (),
00111 "ImplRepo_Service" ACE_ENV_ARG_PARAMETER);
00112 ACE_CHECK_RETURN (-1);
00113 ACE_ASSERT (! CORBA::is_nil (this->imr_poa_.in ()));
00114
00115 waiter_svt_.debug (debug_ > 1);
00116 PortableServer::ObjectId_var id = PortableServer::string_to_ObjectId ("ImR_AsyncStartupWaiter");
00117 this->imr_poa_->activate_object_with_id (id.in (), &waiter_svt_ ACE_ENV_ARG_PARAMETER);
00118 ACE_CHECK_RETURN (-1);
00119 obj = this->imr_poa_->id_to_reference (id.in () ACE_ENV_ARG_PARAMETER);
00120 ACE_CHECK_RETURN (-1);
00121 if (startup_timeout_ > ACE_Time_Value::zero)
00122 {
00123 obj = set_timeout_policy (obj.in (), startup_timeout_);
00124 }
00125 waiter_ = ImplementationRepository::AsyncStartupWaiter::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
00126 ACE_CHECK_RETURN (-1);
00127
00128 id = PortableServer::string_to_ObjectId ("ImplRepo_Service");
00129 this->imr_poa_->activate_object_with_id (id.in (), this ACE_ENV_ARG_PARAMETER);
00130 ACE_CHECK_RETURN (-1);
00131
00132 obj = this->imr_poa_->id_to_reference (id.in () ACE_ENV_ARG_PARAMETER);
00133 ACE_CHECK_RETURN (-1);
00134 CORBA::String_var ior = this->orb_->object_to_string (obj.in () ACE_ENV_ARG_PARAMETER);
00135 ACE_CHECK_RETURN (-1);
00136
00137
00138 obj = orb->resolve_initial_references ("IORTable" ACE_ENV_ARG_PARAMETER);
00139 ACE_CHECK_RETURN (-1);
00140 IORTable::Table_var ior_table = IORTable::Table::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
00141 ACE_CHECK_RETURN (-1);
00142 ACE_ASSERT (! CORBA::is_nil (ior_table.in ()));
00143 ior_table->bind ("ImplRepoService", ior.in () ACE_ENV_ARG_PARAMETER);
00144 ACE_CHECK_RETURN (-1);
00145 ior_table->bind ("ImR", ior.in () ACE_ENV_ARG_PARAMETER);
00146 ACE_CHECK_RETURN (-1);
00147 ior_table->set_locator (this->ins_locator_.in () ACE_ENV_ARG_PARAMETER);
00148 ACE_CHECK_RETURN (-1);
00149
00150
00151 if (opts.multicast ())
00152 {
00153 ACE_Reactor* reactor = orb->orb_core ()->reactor ();
00154 if (this->setup_multicast (reactor, ior.in ()) != 0)
00155 return -1;
00156 }
00157
00158
00159
00160
00161
00162 int init_result =
00163 this->repository_.init (opts);
00164 if (init_result == -1)
00165 {
00166 ACE_ERROR_RETURN ((LM_ERROR, "Repository failed to initialize\n"), -1);
00167 }
00168
00169
00170 PortableServer::POAManager_var poaman =
00171 this->root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
00172 ACE_CHECK_RETURN (-1);
00173 poaman->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
00174 ACE_CHECK_RETURN (-1);
00175 poaman = this->imr_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
00176 ACE_CHECK_RETURN (-1);
00177 poaman->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
00178 ACE_CHECK_RETURN (-1);
00179
00180
00181 if (opts.ior_filename ().length () > 0)
00182 {
00183 FILE* fp = ACE_OS::fopen (opts.ior_filename ().c_str (), "w");
00184 if (fp == 0)
00185 {
00186 ACE_ERROR_RETURN ((LM_ERROR,
00187 "ImR: Could not open file: %s\n", opts.ior_filename ().c_str ()), -1);
00188 }
00189 ACE_OS::fprintf (fp, "%s", ior.in ());
00190 ACE_OS::fclose (fp);
00191 }
00192
00193 return 0;
00194 }
00195
00196 int
00197 ImR_Locator_i::init (Options& opts ACE_ENV_ARG_DECL)
00198 {
00199 ACE_CString cmdline = opts.cmdline ();
00200 cmdline += " -orbcollocation no -orbuseimr 0";
00201 ACE_ARGV av (cmdline.c_str ());
00202 int argc = av.argc ();
00203 char** argv = av.argv ();
00204
00205 CORBA::ORB_var orb = CORBA::ORB_init (argc, argv, "TAO_ImR_Locator" ACE_ENV_ARG_PARAMETER);
00206 ACE_CHECK_RETURN (-1);
00207 int err = this->init_with_orb (orb.in (), opts ACE_ENV_ARG_PARAMETER);
00208 ACE_CHECK_RETURN (-1);
00209 return err;
00210 }
00211
00212 int
00213 ImR_Locator_i::run (ACE_ENV_SINGLE_ARG_DECL)
00214 {
00215 if (debug_ > 0)
00216 {
00217 ACE_DEBUG ((LM_DEBUG, "Implementation Repository: Running\n"
00218 "\tPing Interval : %dms\n"
00219 "\tStartup Timeout : %ds\n"
00220 "\tPersistence : %s\n"
00221 "\tMulticast : %s\n"
00222 "\tDebug : %d\n"
00223 "\tLocked : %s\n\n",
00224 ping_interval_.msec (),
00225 startup_timeout_.sec (),
00226 repository_.repo_mode (),
00227 ior_multicast_.reactor () != 0 ? "Enabled" : "Disabled",
00228 debug (),
00229 read_only_ ? "True" : "False"));
00230 }
00231 this->auto_start_servers (ACE_ENV_SINGLE_ARG_PARAMETER);
00232 ACE_CHECK_RETURN (-1);
00233
00234 this->orb_->run (ACE_ENV_SINGLE_ARG_PARAMETER);
00235 ACE_CHECK_RETURN (-1);
00236 return 0;
00237 }
00238
00239 void
00240 ImR_Locator_i::shutdown (CORBA::Boolean activators, CORBA::Boolean servers ACE_ENV_ARG_DECL)
00241 ACE_THROW_SPEC ((CORBA::SystemException))
00242 {
00243 if (servers != 0 && this->repository_.servers ().current_size () > 0)
00244 {
00245
00246 ACE_ERROR ((LM_ERROR, "ImR: Shutdown of all servers not implemented.\n"));
00247 }
00248 if (activators != 0 && this->repository_.activators ().current_size () > 0)
00249 {
00250 ACE_Vector<ImplementationRepository::Activator_var> acts;
00251 Locator_Repository::AIMap::ENTRY* entry = 0;
00252 Locator_Repository::AIMap::ITERATOR it (this->repository_.activators ());
00253 for (;it.next (entry) != 0; it.advance ())
00254 {
00255 Activator_Info_Ptr info = entry->int_id_;
00256 ACE_ASSERT (! info.null ());
00257 connect_activator (*info);
00258 if (! CORBA::is_nil (info->activator.in ()))
00259 acts.push_back (info->activator);
00260 }
00261
00262 int shutdown_errs = 0;
00263
00264 for (size_t i = 0; i < acts.size (); ++i)
00265 {
00266 ACE_TRY
00267 {
00268 acts[i]->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
00269 ACE_TRY_CHECK;
00270 acts[i] = ImplementationRepository::Activator::_nil ();
00271 }
00272 ACE_CATCHANY
00273 {
00274 ++shutdown_errs;
00275 if (debug_ > 1)
00276 {
00277 ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR: shutdown activator");
00278 }
00279 }
00280 ACE_ENDTRY;
00281 ACE_CHECK;
00282 }
00283 if (debug_ > 0 && shutdown_errs > 0)
00284 {
00285 ACE_DEBUG ((LM_DEBUG, "ImR: Some activators could not be shut down.\n"));
00286 }
00287 }
00288
00289
00290 shutdown (false ACE_ENV_ARG_PARAMETER);
00291 }
00292
00293 void
00294 ImR_Locator_i::shutdown (bool wait_for_completion ACE_ENV_ARG_DECL)
00295 {
00296 this->orb_->shutdown (wait_for_completion ACE_ENV_ARG_PARAMETER);
00297 }
00298
00299 int
00300 ImR_Locator_i::fini (ACE_ENV_SINGLE_ARG_DECL)
00301 {
00302 ACE_TRY
00303 {
00304 if (debug_ > 1)
00305 ACE_DEBUG ((LM_DEBUG, "ImR: Shutting down...\n"));
00306
00307 teardown_multicast ();
00308
00309 this->root_poa_->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
00310 ACE_TRY_CHECK;
00311
00312 this->orb_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00313 ACE_TRY_CHECK;
00314
00315 if (debug_ > 0)
00316 ACE_DEBUG ((LM_DEBUG, "ImR: Shut down successfully.\n"));
00317 }
00318 ACE_CATCHANY
00319 {
00320 ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR_Locator_i::fini");
00321 ACE_RE_THROW;
00322 }
00323 ACE_ENDTRY;
00324 ACE_CHECK_RETURN (-1);
00325 return 0;
00326 }
00327
00328 void
00329 ImR_Locator_i::teardown_multicast ()
00330 {
00331 ACE_Reactor* r = ior_multicast_.reactor ();
00332 if (r != 0) {
00333 r->remove_handler (&ior_multicast_, ACE_Event_Handler::READ_MASK);
00334 ior_multicast_.reactor (0);
00335 }
00336 }
00337
00338 int
00339 ImR_Locator_i::setup_multicast (ACE_Reactor* reactor, const char* ior)
00340 {
00341 ACE_ASSERT (reactor != 0);
00342 ACE_ASSERT (ior != 0);
00343 #if defined (ACE_HAS_IP_MULTICAST)
00344
00345 TAO_ORB_Core* core = TAO_ORB_Core_instance ();
00346
00347 ACE_CString mde (core->orb_params ()->mcast_discovery_endpoint ());
00348
00349 if (mde.length () != 0)
00350 {
00351 if (this->ior_multicast_.init (ior,
00352 mde.c_str (), TAO_SERVICEID_IMPLREPOSERVICE) == -1)
00353 {
00354 return -1;
00355 }
00356 }
00357 else
00358 {
00359
00360 CORBA::UShort port =
00361 core->orb_params ()->service_port (TAO::MCAST_IMPLREPOSERVICE);
00362 if (port == 0)
00363 {
00364
00365 const char* port_number = ACE_OS::getenv ("ImplRepoServicePort");
00366
00367 if (port_number != 0)
00368 port = static_cast<CORBA::UShort> (ACE_OS::atoi (port_number));
00369 }
00370 if (port == 0)
00371 port = TAO_DEFAULT_IMPLREPO_SERVER_REQUEST_PORT;
00372
00373 if (this->ior_multicast_.init (ior, port,
00374 ACE_DEFAULT_MULTICAST_ADDR, TAO_SERVICEID_IMPLREPOSERVICE) == -1)
00375 {
00376 return -1;
00377 }
00378 }
00379
00380
00381 if (reactor->register_handler (&this->ior_multicast_,
00382 ACE_Event_Handler::READ_MASK) == -1)
00383 {
00384 if (debug_ >= 1)
00385 ACE_DEBUG ((LM_DEBUG, "ImR: cannot register Event handler\n"));
00386 return -1;
00387 }
00388 #else
00389 ACE_UNUSED_ARG (reactor);
00390 ACE_UNUSED_ARG (ior);
00391 #endif
00392 return 0;
00393 }
00394
00395 CORBA::Long
00396 ImR_Locator_i::register_activator (const char* aname,
00397 ImplementationRepository::Activator_ptr activator
00398 ACE_ENV_ARG_DECL)
00399 ACE_THROW_SPEC ((CORBA::SystemException))
00400 {
00401 ACE_ASSERT (aname != 0);
00402 ACE_ASSERT (! CORBA::is_nil (activator));
00403
00404
00405
00406 this->unregister_activator_i (aname);
00407 ACE_CHECK_RETURN (0);
00408
00409 CORBA::String_var ior =
00410 this->orb_->object_to_string (activator ACE_ENV_ARG_PARAMETER);
00411 ACE_CHECK_RETURN (-1);
00412
00413 CORBA::Long token = ACE_OS::gettimeofday ().msec ();
00414
00415 int err = this->repository_.add_activator (aname, token, ior.in (), activator);
00416 ACE_ASSERT (err == 0);
00417 ACE_UNUSED_ARG (err);
00418
00419 if (this->debug_ > 0)
00420 ACE_DEBUG ((LM_DEBUG, "ImR: Activator registered for %s.\n", aname));
00421
00422 return token;
00423 }
00424
00425 void
00426 ImR_Locator_i::unregister_activator (const char* aname,
00427 CORBA::Long token
00428 ACE_ENV_ARG_DECL)
00429 ACE_THROW_SPEC ((CORBA::SystemException))
00430 {
00431 ACE_ASSERT (aname != 0);
00432 Activator_Info_Ptr info = this->get_activator (aname);
00433
00434 if (! info.null ())
00435 {
00436 if (info->token != token && this->debug_ > 0)
00437 {
00438 ACE_DEBUG ((LM_DEBUG, "ImR: Ignoring unregister activator:%s. Wrong token.\n", aname));
00439 return;
00440 }
00441
00442 this->unregister_activator_i (aname);
00443 ACE_CHECK;
00444
00445 if (this->debug_ > 0)
00446 ACE_DEBUG ((LM_DEBUG, "ImR: Activator %s unregistered.\n", aname));
00447 }
00448 else
00449 {
00450 if (this->debug_ > 0)
00451 ACE_DEBUG ((LM_DEBUG, "ImR: Ignoring unregister activator:%s. Unknown activator.\n", aname));
00452 }
00453 }
00454
00455 void
00456 ImR_Locator_i::unregister_activator_i (const char* aname)
00457 {
00458 ACE_ASSERT (aname != 0);
00459 int err = this->repository_.remove_activator (aname);
00460 ACE_UNUSED_ARG (err);
00461 }
00462
00463 void
00464 ImR_Locator_i::notify_child_death (const char* name ACE_ENV_ARG_DECL_NOT_USED)
00465 ACE_THROW_SPEC ((CORBA::SystemException))
00466 {
00467 ACE_ASSERT (name != 0);
00468
00469 if (this->debug_ > 1)
00470 ACE_DEBUG ((LM_DEBUG, "ImR: Server has died <%s>.\n", name));
00471
00472 Server_Info_Ptr info = this->repository_.get_server (name);
00473 if (! info.null ())
00474 {
00475 info->ior = "";
00476 info->partial_ior = "";
00477
00478 int err = this->repository_.update_server (*info);
00479 ACE_ASSERT (err == 0);
00480 ACE_UNUSED_ARG (err);
00481 }
00482 else
00483 {
00484 if (this->debug_ > 1)
00485 ACE_DEBUG ((LM_DEBUG,
00486 "ImR: Failed to find server in repository.\n"));
00487 }
00488 }
00489
00490 void
00491 ImR_Locator_i::activate_server (const char* server ACE_ENV_ARG_DECL)
00492 ACE_THROW_SPEC ((CORBA::SystemException,
00493 ImplementationRepository::NotFound,
00494 ImplementationRepository::CannotActivate))
00495 {
00496 if (debug_ > 1)
00497 ACE_DEBUG ((LM_DEBUG, "ImR: Manually activating server <%s>\n", server));
00498
00499
00500
00501 activate_server_by_name (server, true ACE_ENV_ARG_PARAMETER);
00502 }
00503
00504 char*
00505 ImR_Locator_i::activate_server_by_name (const char* name, bool manual_start ACE_ENV_ARG_DECL)
00506 ACE_THROW_SPEC ((CORBA::SystemException,
00507 ImplementationRepository::NotFound,
00508 ImplementationRepository::CannotActivate))
00509 {
00510
00511
00512 ACE_ASSERT (name != 0);
00513
00514 Server_Info_Ptr info = this->repository_.get_server (name);
00515 if (info.null ())
00516 {
00517 ACE_ERROR ((LM_ERROR, "ImR: Cannot find info for server <%s>\n", name));
00518 ACE_THROW_RETURN (ImplementationRepository::NotFound (), 0);
00519 }
00520
00521 return activate_server_i (*info, manual_start ACE_ENV_ARG_PARAMETER);
00522 }
00523
00524 char*
00525 ImR_Locator_i::activate_server_by_object (const char* object_name ACE_ENV_ARG_DECL)
00526 ACE_THROW_SPEC ((CORBA::SystemException,
00527 ImplementationRepository::NotFound,
00528 ImplementationRepository::CannotActivate))
00529 {
00530 ACE_ASSERT (object_name != 0);
00531
00532
00533
00534 ACE_CString server_name (object_name);
00535 ssize_t pos = server_name.find ('/');
00536 if (pos != ACE_CString::npos)
00537 server_name = server_name.substr (pos + 1);
00538
00539 return activate_server_by_name (server_name.c_str (), false ACE_ENV_ARG_PARAMETER);
00540 }
00541
00542 char*
00543 ImR_Locator_i::activate_server_i (Server_Info& info, bool manual_start ACE_ENV_ARG_DECL)
00544 ACE_THROW_SPEC ((CORBA::SystemException,
00545 ImplementationRepository::NotFound,
00546 ImplementationRepository::CannotActivate))
00547 {
00548 if (info.activation_mode == ImplementationRepository::PER_CLIENT)
00549 {
00550 return activate_perclient_server_i (info, manual_start ACE_ENV_ARG_PARAMETER);
00551 }
00552
00553 while (true)
00554 {
00555 if (is_alive (info))
00556 {
00557 if (debug_ > 1)
00558 {
00559 ACE_DEBUG ((LM_DEBUG, "ImR: Successfully activated <%s> at \n\t%s\n",
00560 info.name.c_str (), info.partial_ior.c_str ()));
00561 }
00562 info.start_count = 0;
00563
00564 waiter_svt_.unblock_all (info.name.c_str ());
00565
00566 return CORBA::string_dup (info.partial_ior.c_str ());
00567 }
00568
00569 info.reset ();
00570
00571 if (! info.starting && info.start_count >= info.start_limit)
00572 {
00573 if (this->debug_ > 0)
00574 {
00575 ACE_DEBUG ((LM_DEBUG,
00576 "ImR: Cannot Activate <%s>.\n", info.name.c_str ()));
00577 }
00578
00579 waiter_svt_.unblock_all (info.name.c_str ());
00580
00581 ACE_THROW_RETURN (ImplementationRepository::CannotActivate
00582 (CORBA::string_dup ("Cannot start server.")), 0);
00583 }
00584
00585
00586 ImplementationRepository::StartupInfo_var si =
00587 start_server (info, manual_start ACE_ENV_ARG_PARAMETER);
00588 ACE_CHECK_RETURN (0);
00589 }
00590 }
00591
00592 char*
00593 ImR_Locator_i::activate_perclient_server_i (Server_Info info, bool manual_start ACE_ENV_ARG_DECL)
00594 ACE_THROW_SPEC ((CORBA::SystemException,
00595 ImplementationRepository::NotFound,
00596 ImplementationRepository::CannotActivate))
00597 {
00598 do
00599 {
00600 ImplementationRepository::StartupInfo* psi =
00601 start_server (info, manual_start ACE_ENV_ARG_PARAMETER);
00602 ACE_CHECK_RETURN (0);
00603
00604 if (psi != 0)
00605 {
00606 ImplementationRepository::StartupInfo_var si = psi;
00607 ACE_ASSERT (info.name == si->name.in ());
00608 info.partial_ior = si->partial_ior.in ();
00609 info.ior = si->ior.in ();
00610
00611 if (is_alive (info))
00612 {
00613 if (debug_ > 1)
00614 {
00615 ACE_DEBUG ((LM_DEBUG, "ImR: Successfully activated <%s> at \n\t%s\n",
00616 info.name.c_str (), info.partial_ior.c_str ()));
00617 }
00618 return CORBA::string_dup (info.partial_ior.c_str ());
00619 }
00620 info.reset ();
00621 }
00622 } while (info.start_count < info.start_limit);
00623
00624 if (this->debug_ > 0)
00625 {
00626 ACE_DEBUG ((LM_DEBUG,
00627 "ImR: Cannot Activate <%s>.\n", info.name.c_str ()));
00628 }
00629 ACE_THROW_RETURN (ImplementationRepository::CannotActivate
00630 (CORBA::string_dup ("Cannot start server.")), 0);
00631 }
00632
00633 ImplementationRepository::StartupInfo*
00634 ImR_Locator_i::start_server (Server_Info& info, bool manual_start ACE_ENV_ARG_DECL)
00635 ACE_THROW_SPEC ((CORBA::SystemException,
00636 ImplementationRepository::NotFound,
00637 ImplementationRepository::CannotActivate))
00638 {
00639 if (info.activation_mode == ImplementationRepository::MANUAL && ! manual_start)
00640 {
00641 if (debug_ > 0)
00642 ACE_DEBUG ((LM_DEBUG, "ImR: Cannot start server <%s>. ActivationMode=MANUAL\n", info.name.c_str ()));
00643 ACE_THROW_RETURN (ImplementationRepository::CannotActivate
00644 (CORBA::string_dup ("Cannot implicitly activate MANUAL server.")), 0);
00645 }
00646 if (info.cmdline.length () == 0)
00647 {
00648 if (debug_ > 0)
00649 ACE_DEBUG ((LM_DEBUG, "ImR: Cannot start server <%s>."
00650 " No command line.\n", info.name.c_str ()));
00651 ACE_THROW_RETURN (ImplementationRepository::CannotActivate
00652 (CORBA::string_dup ("No command line registered for server.")), 0);
00653 }
00654
00655 Activator_Info_Ptr ainfo = get_activator (info.activator);
00656
00657 if (ainfo.null () || CORBA::is_nil (ainfo->activator.in ()))
00658 {
00659 if (debug_ > 0)
00660 ACE_DEBUG ((LM_DEBUG, "ImR: Cannot start server <%s>. "
00661 "Activator <%s> not found.\n", info.name.c_str (), info.activator.c_str ()));
00662 ACE_THROW_RETURN (ImplementationRepository::CannotActivate
00663 (CORBA::string_dup ("No activator registered for server.")), 0);
00664 }
00665
00666 ACE_TRY
00667 {
00668 ++ info.waiting_clients;
00669
00670 if (info.waiting_clients <= 1 || info.activation_mode == ImplementationRepository::PER_CLIENT)
00671 {
00672 info.starting = true;
00673 ++info.start_count;
00674 ACE_ASSERT (info.start_count <= info.start_limit);
00675 if (this->debug_ > 0)
00676 {
00677 ACE_DEBUG ((LM_DEBUG, "ImR: Starting server <%s>. Attempt %d/%d.\n",
00678 info.name.c_str (), info.start_count, info.start_limit));
00679 }
00680 ainfo->activator->start_server (
00681 info.name.c_str (),
00682 info.cmdline.c_str (),
00683 info.dir.c_str (),
00684 info.env_vars
00685 ACE_ENV_ARG_PARAMETER);
00686 ACE_TRY_CHECK;
00687 }
00688
00689 if (info.partial_ior.length () == 0)
00690 {
00691 if (this->debug_ > 0)
00692 {
00693 ACE_DEBUG ((LM_DEBUG, "ImR: Waiting for <%s> to start...\n", info.name.c_str ()));
00694 }
00695
00696 ImplementationRepository::StartupInfo_var si =
00697 waiter_->wait_for_startup (info.name.c_str () ACE_ENV_ARG_PARAMETER);
00698 ACE_TRY_CHECK;
00699
00700 -- info.waiting_clients;
00701 info.starting = false;
00702
00703 return si._retn ();
00704 }
00705 else
00706 {
00707 if (this->debug_ > 0)
00708 {
00709 ACE_DEBUG ((LM_DEBUG, "ImR: <%s> Skipping wait. Already started.\n", info.name.c_str ()));
00710 }
00711 -- info.waiting_clients;
00712 info.starting = false;
00713 }
00714 }
00715 ACE_CATCH (CORBA::TIMEOUT, ex)
00716 {
00717 -- info.waiting_clients;
00718 info.starting = false;
00719
00720
00721
00722 if (info.partial_ior.length () == 0)
00723 {
00724 if (debug_ > 0)
00725 ACE_DEBUG ((LM_DEBUG, "ImR : Timeout waiting for <%s> to start.\n", info.name.c_str ()));
00726 info.reset ();
00727 }
00728 }
00729 ACE_CATCH (ImplementationRepository::CannotActivate, ex)
00730 {
00731 -- info.waiting_clients;
00732 info.starting = false;
00733 info.reset ();
00734 if (debug_ > 0)
00735 ACE_DEBUG ((LM_DEBUG, "ImR: Activator cannot start <%s>.\n", info.name.c_str ()));
00736 }
00737 ACE_CATCHANY
00738 {
00739 -- info.waiting_clients;
00740 info.starting = false;
00741 if (debug_ > 0)
00742 ACE_DEBUG ((LM_DEBUG, "ImR: Unexpected exception while starting <%s>.\n", info.name.c_str ()));
00743 if (debug_ > 1)
00744 ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "");
00745 ainfo->reset ();
00746 info.reset ();
00747 }
00748 ACE_ENDTRY;
00749 return 0;
00750 }
00751
00752 CORBA::Object_ptr
00753 ImR_Locator_i::set_timeout_policy (CORBA::Object_ptr obj, const ACE_Time_Value& to)
00754 {
00755 CORBA::Object_var ret (CORBA::Object::_duplicate (obj));
00756
00757 ACE_TRY_NEW_ENV
00758 {
00759 TimeBase::TimeT timeout;
00760 ORBSVCS_Time::Time_Value_to_TimeT (timeout, to);
00761 CORBA::Any tmp;
00762 tmp <<= timeout;
00763
00764 CORBA::PolicyList policies (1);
00765 policies.length (1);
00766 policies[0] = orb_->create_policy (Messaging::RELATIVE_RT_TIMEOUT_POLICY_TYPE, tmp ACE_ENV_ARG_PARAMETER);
00767 ACE_TRY_CHECK;
00768
00769 ret = obj->_set_policy_overrides (policies, CORBA::ADD_OVERRIDE ACE_ENV_ARG_PARAMETER);
00770 ACE_TRY_CHECK;
00771
00772 policies[0]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00773 ACE_TRY_CHECK;
00774
00775 if (CORBA::is_nil (ret.in ()))
00776 {
00777 if (this->debug_ > 0)
00778 {
00779 ACE_DEBUG ((LM_DEBUG, "ImR: Unable to set timeout policy.\n"));
00780 }
00781 ret = CORBA::Object::_duplicate (obj);
00782 }
00783 }
00784 ACE_CATCHANY
00785 {
00786 ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR_Locator_i::set_timeout_policy ()");
00787 }
00788 ACE_ENDTRY;
00789
00790 return ret._retn ();
00791 }
00792
00793 void
00794 ImR_Locator_i::add_or_update_server (const char* server,
00795 const ImplementationRepository::StartupOptions &options
00796 ACE_ENV_ARG_DECL)
00797 ACE_THROW_SPEC ((CORBA::SystemException,
00798 ImplementationRepository::NotFound))
00799 {
00800 ACE_ASSERT (server != 0);
00801
00802 if (this->read_only_)
00803 {
00804 ACE_DEBUG ((LM_DEBUG, "ImR: Cannot add/update server <%s> due to locked database.\n", server));
00805 ACE_THROW (CORBA::NO_PERMISSION (
00806 CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0),
00807 CORBA::COMPLETED_NO));
00808 }
00809
00810 if (debug_ > 0)
00811 ACE_DEBUG ((LM_DEBUG, "ImR: Add/Update server <%s>.\n", server));
00812
00813 int limit = options.start_limit;
00814 if (limit < 0)
00815 {
00816 limit = -limit;
00817 }
00818 else if (limit == 0)
00819 {
00820 limit = 1;
00821 }
00822
00823 Server_Info_Ptr info = this->repository_.get_server (server);
00824 if (info.null ())
00825 {
00826 if (this->debug_ > 1)
00827 ACE_DEBUG ((LM_DEBUG, "ImR: Adding server <%s>.\n", server));
00828
00829 this->repository_.add_server (server,
00830 options.activator.in (),
00831 options.command_line.in (),
00832 options.environment,
00833 options.working_directory.in (),
00834 options.activation,
00835 limit);
00836 }
00837 else
00838 {
00839 if (this->debug_ > 1)
00840 ACE_DEBUG ((LM_DEBUG, "ImR: Updating server <%s>.\n", server));
00841
00842 info->activator = options.activator.in ();
00843 info->cmdline = options.command_line.in ();
00844 info->env_vars = options.environment;
00845 info->dir = options.working_directory.in ();
00846 info->activation_mode = options.activation;
00847 info->start_limit = limit;
00848 info->start_count = 0;
00849 int err = this->repository_.update_server (*info);
00850 ACE_ASSERT (err == 0);
00851 ACE_UNUSED_ARG (err);
00852 }
00853
00854 if (this->debug_ > 1)
00855 {
00856
00857 ACE_DEBUG ((LM_DEBUG, "ImR: Server: %s\n"
00858 "\tActivator: %s\n"
00859 "\tCommand Line: %s\n"
00860 "\tWorking Directory: %s\n"
00861 "\tActivation: %s\n"
00862 "\tStart Limit: %d\n"
00863 "\n",
00864 server,
00865 options.activator.in (),
00866 options.command_line.in (),
00867 options.working_directory.in (),
00868 ImR_Utils::activationModeToString (options.activation).c_str (),
00869 limit
00870 ));
00871
00872 for (CORBA::ULong i = 0; i < options.environment.length (); ++i)
00873 ACE_DEBUG ((LM_DEBUG, "Environment variable %s=%s\n",
00874 options.environment[i].name.in (),
00875 options.environment[i].value.in ()));
00876 }
00877 }
00878
00879 void
00880 ImR_Locator_i::remove_server (const char* name ACE_ENV_ARG_DECL)
00881 ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::NotFound))
00882 {
00883 ACE_ASSERT (name != 0);
00884 if (this->read_only_)
00885 {
00886 ACE_ERROR ((LM_ERROR,
00887 "ImR: Can't remove server <%s> due to locked database.\n", name));
00888 ACE_THROW (CORBA::NO_PERMISSION (
00889 CORBA::SystemException::_tao_minor_code (TAO_IMPLREPO_MINOR_CODE, 0),
00890 CORBA::COMPLETED_NO));
00891 }
00892
00893
00894
00895
00896
00897 Server_Info_Ptr info = this->repository_.get_server (name);
00898 if (! info.null ())
00899 {
00900 if (this->repository_.remove_server (name) == 0)
00901 {
00902 if (this->debug_ > 1)
00903 ACE_DEBUG ((LM_DEBUG, "ImR: Removing Server <%s>...\n", name));
00904
00905 PortableServer::POA_var poa = findPOA (name);
00906 ACE_CHECK;
00907 if (! CORBA::is_nil (poa.in ()))
00908 {
00909 bool etherealize = true;
00910 bool wait = false;
00911 poa->destroy (etherealize, wait ACE_ENV_ARG_PARAMETER);
00912 ACE_CHECK;
00913 }
00914 if (this->debug_ > 0)
00915 ACE_DEBUG ((LM_DEBUG, "ImR: Removed Server <%s>.\n", name));
00916 }
00917 }
00918 else
00919 {
00920 ACE_ERROR ((LM_ERROR,
00921 "ImR: Can't remove unknown server <%s>.\n", name));
00922 ACE_THROW (ImplementationRepository::NotFound ());
00923 }
00924 }
00925
00926 PortableServer::POA_ptr
00927 ImR_Locator_i::findPOA (const char* name)
00928 {
00929 ACE_TRY_NEW_ENV
00930 {
00931 bool activate_it = false;
00932 return root_poa_->find_POA (name, activate_it ACE_ENV_ARG_PARAMETER);
00933 ACE_TRY_CHECK;
00934 }
00935 ACE_CATCHANY
00936 {
00937 }
00938 ACE_ENDTRY;
00939 return PortableServer::POA::_nil ();
00940 }
00941
00942 void
00943 ImR_Locator_i::shutdown_server (const char* server ACE_ENV_ARG_DECL)
00944 ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::NotFound))
00945 {
00946 ACE_ASSERT (server != 0);
00947
00948 if (this->debug_ > 0)
00949 ACE_DEBUG ((LM_DEBUG, "ImR: Shutting down server <%s>.\n", server));
00950
00951 Server_Info_Ptr info = this->repository_.get_server (server);
00952 if (info.null ())
00953 {
00954 ACE_ERROR ((LM_ERROR,
00955 "ImR: shutdown_server () Cannot find info for server <%s>\n", server));
00956 ACE_THROW (ImplementationRepository::NotFound ());
00957 }
00958
00959 connect_server (*info);
00960
00961 if (CORBA::is_nil (info->server.in ()))
00962 {
00963 ACE_ERROR ((LM_ERROR,
00964 "ImR: shutdown_server () Cannot connect to server <%s>\n", server));
00965 ACE_THROW (ImplementationRepository::NotFound ());
00966 }
00967
00968 ACE_TRY_NEW_ENV
00969 {
00970 CORBA::Object_var obj = set_timeout_policy (info->server.in (), DEFAULT_SHUTDOWN_TIMEOUT);
00971 ImplementationRepository::ServerObject_var server =
00972 ImplementationRepository::ServerObject::_unchecked_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
00973 ACE_TRY_CHECK;
00974 server->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER);
00975 ACE_TRY_CHECK;
00976 }
00977 ACE_CATCH (CORBA::TIMEOUT, ex)
00978 {
00979 info->reset ();
00980 int err = this->repository_.update_server (*info);
00981 ACE_ASSERT (err == 0);
00982 ACE_UNUSED_ARG (err);
00983
00984
00985 if (this->debug_ > 1)
00986 {
00987 ACE_DEBUG ((LM_DEBUG, "ImR: Timeout while waiting for <%s> shutdown.\n", server));
00988 }
00989 ACE_RE_THROW;
00990 }
00991 ACE_CATCHANY
00992 {
00993 if (this->debug_ > 1)
00994 {
00995 ACE_DEBUG ((LM_DEBUG, "ImR: Exception ignored while shutting down <%s>\n", server));
00996 }
00997 }
00998 ACE_ENDTRY;
00999
01000
01001
01002 info->reset ();
01003
01004 int err = this->repository_.update_server (*info);
01005 ACE_ASSERT (err == 0);
01006 ACE_UNUSED_ARG (err);
01007 }
01008
01009 void
01010 ImR_Locator_i::server_is_running (const char* name,
01011 const char* partial_ior,
01012 ImplementationRepository::ServerObject_ptr server
01013 ACE_ENV_ARG_DECL)
01014 ACE_THROW_SPEC ((CORBA::SystemException,
01015 ImplementationRepository::NotFound))
01016 {
01017 ACE_ASSERT (name != 0);
01018 ACE_ASSERT (partial_ior != 0);
01019 ACE_ASSERT (! CORBA::is_nil (server));
01020
01021 if (this->debug_ > 0)
01022 ACE_DEBUG ((LM_DEBUG, "ImR: Server %s is running at %s.\n", name, partial_ior));
01023
01024 CORBA::String_var ior = orb_->object_to_string (server ACE_ENV_ARG_PARAMETER);
01025 ACE_CHECK;
01026
01027 if (this->debug_ > 1)
01028 ACE_DEBUG ((LM_DEBUG, "ImR: Server %s callback at %s.\n", name, ior.in ()));
01029
01030 Server_Info_Ptr info = this->repository_.get_server (name);
01031 if (info.null ())
01032 {
01033 if (this->debug_ > 0)
01034 ACE_DEBUG ((LM_DEBUG, "ImR: Auto adding NORMAL server <%s>.\n", name));
01035
01036 ImplementationRepository::EnvironmentList env (0);
01037 this->repository_.add_server (name,
01038 "",
01039 "",
01040 ImplementationRepository::EnvironmentList (),
01041 "",
01042 ImplementationRepository::NORMAL,
01043 DEFAULT_START_LIMIT,
01044 partial_ior,
01045 ior.in (),
01046 ImplementationRepository::ServerObject::_nil ()
01047 );
01048 }
01049 else
01050 {
01051 if (info->activation_mode != ImplementationRepository::PER_CLIENT) {
01052 info->ior = ior.in ();
01053 info->partial_ior = partial_ior;
01054 info->server = ImplementationRepository::ServerObject::_nil ();
01055
01056 int err = this->repository_.update_server (*info);
01057 ACE_ASSERT (err == 0);
01058 ACE_UNUSED_ARG (err);
01059
01060 waiter_svt_.unblock_one (name, partial_ior, ior.in (), false);
01061 } else {
01062
01063
01064 waiter_svt_.unblock_one (name, partial_ior, ior.in (), true);
01065 }
01066 }
01067 }
01068
01069 void
01070 ImR_Locator_i::server_is_shutting_down (const char* server ACE_ENV_ARG_DECL_NOT_USED)
01071 ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::NotFound))
01072 {
01073 ACE_ASSERT (server != 0);
01074 Server_Info_Ptr info = this->repository_.get_server (server);
01075 if (info.null ())
01076 {
01077 if (this->debug_ > 1)
01078 {
01079 ACE_DEBUG ((LM_DEBUG,
01080 "ImR_Locator_i::server_is_shutting_down: Unknown server:%s\n", server));
01081 }
01082 return;
01083 }
01084
01085 if (this->debug_ > 0)
01086 ACE_DEBUG ((LM_DEBUG, "ImR: Server <%s> is shutting down.\n", server));
01087
01088 info->reset ();
01089
01090 int err = this->repository_.update_server (*info);
01091 ACE_ASSERT (err == 0);
01092 ACE_UNUSED_ARG (err);
01093 }
01094
01095 void
01096 ImR_Locator_i::find (const char* server,
01097 ImplementationRepository::ServerInformation_out imr_info
01098 ACE_ENV_ARG_DECL)
01099 ACE_THROW_SPEC ((CORBA::SystemException))
01100 {
01101 ACE_ASSERT (server != 0);
01102 ACE_NEW_THROW_EX (imr_info, ImplementationRepository::ServerInformation, CORBA::NO_MEMORY ());
01103
01104 Server_Info_Ptr info = this->repository_.get_server (server);
01105 if (! info.null ())
01106 {
01107 imr_info = info->createImRServerInfo (ACE_ENV_SINGLE_ARG_PARAMETER);
01108
01109 if (this->debug_ > 1)
01110 ACE_DEBUG ((LM_DEBUG, "ImR: Found server %s.\n", server));
01111 }
01112 else
01113 {
01114 if (debug_ > 1)
01115 ACE_DEBUG ((LM_DEBUG, "ImR: Cannot find server <%s>\n", server));
01116 }
01117 }
01118
01119 void
01120 ImR_Locator_i::list (CORBA::ULong how_many,
01121 ImplementationRepository::ServerInformationList_out server_list,
01122 ImplementationRepository::ServerInformationIterator_out server_iterator
01123 ACE_ENV_ARG_DECL
01124 ) ACE_THROW_SPEC ((CORBA::SystemException))
01125 {
01126 if (this->debug_ > 1)
01127 ACE_DEBUG ((LM_DEBUG, "ImR: List servers.\n"));
01128
01129
01130
01131 server_iterator = ImplementationRepository::ServerInformationIterator::_nil ();
01132 ACE_NEW_THROW_EX (server_list,
01133 ImplementationRepository::ServerInformationList (0), CORBA::NO_MEMORY ());
01134
01135 Locator_Repository::SIMap::ENTRY* entry = 0;
01136 Locator_Repository::SIMap::ITERATOR it (this->repository_.servers ());
01137
01138
01139 CORBA::ULong n = this->repository_.servers ().current_size ();
01140 if (how_many > 0 && n > how_many)
01141 {
01142 n = how_many;
01143 }
01144
01145 server_list->length (n);
01146
01147 if (this->debug_ > 1)
01148 ACE_DEBUG ((LM_DEBUG, "ImR_Locator_i::list: Filling ServerList with %d servers\n", n));
01149
01150 for (CORBA::ULong i = 0; i < n; i++)
01151 {
01152 it.next (entry);
01153 it.advance ();
01154 ACE_ASSERT (entry != 0);
01155
01156 Server_Info_Ptr info = entry->int_id_;
01157
01158 ImplementationRepository::ServerInformation_var imr_info = info->createImRServerInfo (ACE_ENV_SINGLE_ARG_PARAMETER);
01159 server_list[i] = *imr_info;
01160 }
01161
01162 if (this->repository_.servers ().current_size () > n)
01163 {
01164 if (this->debug_ > 1)
01165 ACE_DEBUG ((LM_DEBUG, "ImR_Locator_i::list: Creating ServerInformation Iterator\n"));
01166
01167 ImR_Iterator* imr_iter;
01168
01169 ACE_NEW_THROW_EX (imr_iter,
01170 ImR_Iterator (n, this->repository_, this->imr_poa_.in ()),
01171 CORBA::NO_MEMORY ());
01172
01173 PortableServer::ServantBase_var tmp (imr_iter);
01174
01175 ACE_TRY
01176 {
01177 PortableServer::ObjectId_var id =
01178 this->imr_poa_->activate_object (imr_iter ACE_ENV_ARG_PARAMETER);
01179 ACE_TRY_CHECK;
01180 CORBA::Object_var obj = this->imr_poa_->id_to_reference (id.in () ACE_ENV_ARG_PARAMETER);
01181 ACE_TRY_CHECK;
01182 server_iterator = ImplementationRepository::
01183 ServerInformationIterator::_unchecked_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
01184 ACE_TRY_CHECK;
01185 }
01186 ACE_CATCHANY
01187 {
01188 ACE_RE_THROW;
01189 }
01190 ACE_ENDTRY;
01191 ACE_CHECK;
01192 }
01193 }
01194
01195 Activator_Info_Ptr
01196 ImR_Locator_i::get_activator (const ACE_CString& aname)
01197 {
01198 Activator_Info_Ptr info = this->repository_.get_activator (aname);
01199 if (! info.null ())
01200 {
01201 this->connect_activator (*info);
01202 }
01203 return info;
01204 }
01205
01206 void
01207 ImR_Locator_i::connect_activator (Activator_Info& info)
01208 {
01209 if (! CORBA::is_nil (info.activator.in ()) || info.ior.length () == 0)
01210 return;
01211
01212 ACE_TRY_NEW_ENV
01213 {
01214 CORBA::Object_var obj =
01215 this->orb_->string_to_object (info.ior.c_str ()
01216 ACE_ENV_ARG_PARAMETER);
01217 ACE_TRY_CHECK;
01218
01219 if (CORBA::is_nil (obj.in ()))
01220 {
01221 info.reset ();
01222 return;
01223 }
01224
01225 if (startup_timeout_ > ACE_Time_Value::zero)
01226 {
01227 obj = set_timeout_policy (obj.in (), startup_timeout_);
01228 }
01229
01230 info.activator =
01231 ImplementationRepository::Activator::_unchecked_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
01232 ACE_TRY_CHECK;
01233
01234 if (CORBA::is_nil (info.activator.in ()))
01235 {
01236 info.reset ();
01237 return;
01238 }
01239
01240 if (debug_ > 1)
01241 ACE_DEBUG ((LM_DEBUG, "ImR: Connected to activator <%s>\n", info.name.c_str ()));
01242 }
01243 ACE_CATCHANY
01244 {
01245 info.reset ();
01246 }
01247 ACE_ENDTRY;
01248 }
01249
01250 void
01251 ImR_Locator_i::auto_start_servers (ACE_ENV_SINGLE_ARG_DECL)
01252 {
01253 if (this->repository_.servers ().current_size () == 0)
01254 return;
01255
01256 Locator_Repository::SIMap::ENTRY* server_entry;
01257 Locator_Repository::SIMap::ITERATOR server_iter (this->repository_.servers ());
01258
01259
01260
01261
01262 for (;server_iter.next (server_entry) != 0; server_iter.advance ())
01263 {
01264 Server_Info_Ptr info = server_entry->int_id_;
01265 ACE_ASSERT (! info.null ());
01266
01267 ACE_TRY
01268 {
01269 if (info->activation_mode == ImplementationRepository::AUTO_START
01270 && info->cmdline.length () > 0)
01271 {
01272 this->activate_server_i (*info, true ACE_ENV_ARG_PARAMETER);
01273 ACE_TRY_CHECK;
01274 }
01275 }
01276 ACE_CATCHANY
01277 {
01278 if (this->debug_ > 1)
01279 {
01280 ACE_DEBUG ((LM_DEBUG,
01281 "ImR: AUTO_START Could not activate <%s>\n",
01282 server_entry->ext_id_.c_str ()));
01283 ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "AUTO_START");
01284 }
01285
01286 }
01287 ACE_ENDTRY;
01288 ACE_CHECK;
01289 }
01290 }
01291
01292 void
01293 ImR_Locator_i::connect_server (Server_Info& info)
01294 {
01295 if (! CORBA::is_nil (info.server.in ()))
01296 {
01297 return;
01298 }
01299
01300 if (info.ior.length () == 0)
01301 {
01302 info.reset ();
01303 return;
01304 }
01305
01306 ACE_TRY_NEW_ENV
01307 {
01308 CORBA::Object_var obj = orb_->string_to_object (info.ior.c_str () ACE_ENV_ARG_PARAMETER);
01309 ACE_TRY_CHECK;
01310
01311 if (CORBA::is_nil (obj.in ()))
01312 {
01313 info.reset ();
01314 return;
01315 }
01316
01317 obj = set_timeout_policy (obj.in (), DEFAULT_SERVER_TIMEOUT);
01318
01319 info.server =
01320 ImplementationRepository::ServerObject::_unchecked_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
01321 ACE_TRY_CHECK;
01322
01323 if (CORBA::is_nil (info.server.in ()))
01324 {
01325 info.reset ();
01326 return;
01327 }
01328
01329 if (debug_ > 1)
01330 ACE_DEBUG ((LM_DEBUG, "ImR: Connected to server <%s>\n", info.name.c_str ()));
01331 }
01332 ACE_CATCHANY
01333 {
01334 info.reset ();
01335 }
01336 ACE_ENDTRY;
01337 }
01338
01339 bool
01340 ImR_Locator_i::is_alive (Server_Info& info)
01341 {
01342 const size_t table_size = sizeof (PING_RETRY_SCHEDULE) /
01343 sizeof (*PING_RETRY_SCHEDULE);
01344
01345 for (size_t i = 0; i < table_size; ++i)
01346 {
01347 int status = this->is_alive_i (info);
01348 if (status == 0)
01349 return false;
01350 if (status == 1)
01351 return true;
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367 if (PING_RETRY_SCHEDULE[i] > 0)
01368 {
01369 ACE_Time_Value tv (0, PING_RETRY_SCHEDULE[i] * 1000);
01370 this->orb_->run (tv);
01371 }
01372 }
01373 if (debug_ > 0)
01374 {
01375 ACE_DEBUG ((LM_DEBUG,
01376 "ImR: <%s> Ping retry count exceeded. alive=maybe.\n", info.name.c_str ()));
01377 }
01378
01379
01380
01381 info.last_ping = ACE_OS::gettimeofday ();
01382 return true;
01383 }
01384
01385 int
01386 ImR_Locator_i::is_alive_i (Server_Info& info)
01387 {
01388
01389 ACE_DECLARE_NEW_CORBA_ENV;
01390
01391 if (info.ior.length () == 0 || info.partial_ior.length () == 0)
01392 {
01393 if (debug_ > 1)
01394 {
01395 ACE_DEBUG ((LM_DEBUG,
01396 "ImR: <%s> not running. alive=false.\n", info.name.c_str ()));
01397 }
01398 info.last_ping = ACE_Time_Value::zero;
01399 return 0;
01400 }
01401
01402 if (ping_interval_ == ACE_Time_Value::zero)
01403 {
01404 if (debug_ > 1)
01405 {
01406 ACE_DEBUG ((LM_DEBUG,
01407 "ImR: <%s> Ping verification disabled. alive=true.\n", info.name.c_str ()));
01408 }
01409 return 1;
01410 }
01411
01412 if ((ACE_OS::gettimeofday () - info.last_ping) < ping_interval_)
01413 {
01414 if (debug_ > 1)
01415 {
01416 ACE_DEBUG ((LM_DEBUG,
01417 "ImR: <%s> within ping interval. alive=true.\n", info.name.c_str ()));
01418 }
01419 return 1;
01420 }
01421
01422
01423
01424
01425 if (info.cmdline.length () == 0 || ! repository_.has_activator (info.activator))
01426 {
01427 if (debug_ > 1)
01428 {
01429 ACE_DEBUG ((LM_DEBUG,
01430 "ImR: Ping verification skipped. <%s> not startable.\n", info.name.c_str ()));
01431 }
01432 return 1;
01433 }
01434
01435 connect_server (info);
01436
01437 if (CORBA::is_nil (info.server.in ()))
01438 {
01439 if (debug_ > 1)
01440 {
01441 ACE_DEBUG ((LM_DEBUG,
01442 "ImR: <%s> Could not connect. alive=false.\n", info.name.c_str ()));
01443 }
01444 return 0;
01445 }
01446
01447 ACE_TRY
01448 {
01449
01450 ImplementationRepository::ServerObject_var server = info.server;
01451
01452
01453 server->ping (ACE_ENV_SINGLE_ARG_PARAMETER);
01454 ACE_TRY_CHECK;
01455
01456 if (debug_ > 1)
01457 {
01458 ACE_DEBUG ((LM_DEBUG,
01459 "ImR: <%s> Ping successful. alive=true\n", info.name.c_str ()));
01460 }
01461 info.last_ping = ACE_OS::gettimeofday ();
01462 }
01463 ACE_CATCH (CORBA::TRANSIENT, ex)
01464 {
01465 const CORBA::ULong BITS_5_THRU_12_MASK = 0x00000f80;
01466 switch (ex.minor () & BITS_5_THRU_12_MASK)
01467 {
01468 case TAO_INVOCATION_SEND_REQUEST_MINOR_CODE:
01469 {
01470 if (debug_ > 1)
01471 {
01472 ACE_DEBUG ((LM_DEBUG,
01473 "ImR: <%s> Local TRANSIENT. alive=false.\n", info.name.c_str ()));
01474 }
01475 }
01476 info.last_ping = ACE_Time_Value::zero;
01477 return 0;
01478 case TAO_POA_DISCARDING:
01479 case TAO_POA_HOLDING:
01480 {
01481 if (debug_ > 1)
01482 {
01483 ACE_DEBUG ((LM_DEBUG,
01484 "ImR: <%s> Remote TRANSIENT. alive=maybe.\n", info.name.c_str ()));
01485 }
01486 }
01487 return -1;
01488
01489
01490 default:
01491 {
01492 if (debug_ > 1)
01493 {
01494 ACE_DEBUG ((LM_DEBUG,
01495 "ImR: <%s> TRANSIENT exception. alive=false.\n", info.name.c_str ()));
01496 }
01497 info.last_ping = ACE_Time_Value::zero;
01498 }
01499 return 0;
01500 }
01501 }
01502 ACE_CATCH (CORBA::TIMEOUT, ex)
01503 {
01504 if (debug_ > 1)
01505 {
01506 ACE_DEBUG ((LM_DEBUG,
01507 "ImR: <%s> Ping timed out. alive=true.\n", info.name.c_str ()));
01508 }
01509 return 1;
01510
01511
01512
01513 }
01514 ACE_CATCHANY
01515 {
01516 if (debug_ > 1)
01517 {
01518 ACE_DEBUG ((LM_DEBUG, "ImR: <%s> Unexpected Ping exception. alive=false\n", info.name.c_str ()));
01519 ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "\n");
01520 }
01521 info.last_ping = ACE_Time_Value::zero;
01522 return false;
01523 }
01524 ACE_ENDTRY;
01525 return 1;
01526 }
01527
01528 int
01529 ImR_Locator_i::debug () const
01530 {
01531 return debug_;
01532 }