ImR_Activator_i.cpp

Go to the documentation of this file.
00001 // ImR_Activator_i.cpp,v 1.35 2006/03/10 15:50:16 smcqueen Exp
00002 
00003 #include "ImR_Activator_i.h"
00004 
00005 #include "Activator_Options.h"
00006 
00007 #include "tao/ORB_Core.h"
00008 
00009 #include "ace/Reactor.h"
00010 #include "ace/ARGV.h"
00011 #include "ace/OS_NS_unistd.h"
00012 #include "ace/OS_NS_stdio.h"
00013 #include "ace/os_include/os_netdb.h"
00014 
00015 static ACE_CString getHostName ()
00016 {
00017   char host_name[MAXHOSTNAMELEN];
00018   ACE_OS::hostname (host_name, MAXHOSTNAMELEN);
00019   return ACE_CString (host_name);
00020 }
00021 
00022 ImR_Activator_i::ImR_Activator_i (void)
00023 : registration_token_(0)
00024 , debug_(0)
00025 , notify_imr_ (false)
00026 , name_ (getHostName ())
00027 {
00028 }
00029 
00030 static PortableServer::POA_ptr
00031 createPersistentPOA (PortableServer::POA_ptr root_poa, const char* poa_name ACE_ENV_ARG_DECL)
00032 {
00033   PortableServer::LifespanPolicy_var life =
00034     root_poa->create_lifespan_policy (PortableServer::PERSISTENT ACE_ENV_ARG_PARAMETER);
00035   ACE_CHECK_RETURN (PortableServer::POA::_nil ());
00036 
00037   PortableServer::IdAssignmentPolicy_var assign =
00038     root_poa->create_id_assignment_policy (PortableServer::USER_ID ACE_ENV_ARG_PARAMETER);
00039   ACE_CHECK_RETURN (PortableServer::POA::_nil ());
00040 
00041   CORBA::PolicyList pols;
00042   pols.length (2);
00043   pols[0] = PortableServer::LifespanPolicy::_duplicate (life.in ());
00044   pols[1] = PortableServer::IdAssignmentPolicy::_duplicate (assign.in ());
00045 
00046   PortableServer::POAManager_var mgr = root_poa->the_POAManager ();
00047   PortableServer::POA_var poa =
00048     root_poa->create_POA(poa_name, mgr.in (), pols ACE_ENV_ARG_PARAMETER);
00049   ACE_CHECK_RETURN(PortableServer::POA::_nil ());
00050 
00051   life->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00052   ACE_CHECK_RETURN (PortableServer::POA::_nil ());
00053   assign->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00054   ACE_CHECK_RETURN (PortableServer::POA::_nil ());
00055 
00056   return poa._retn ();
00057 }
00058 
00059 // It's ok if we can't register with the ImR. It just
00060 // means we won't be able to notify it of any events
00061 // (Currently, just that we're shutting down.)
00062 void
00063 ImR_Activator_i::register_with_imr (ImplementationRepository::Activator_ptr activator)
00064 {
00065   ACE_TRY_NEW_ENV
00066     {
00067       if (this->debug_ > 1)
00068         ACE_DEBUG( (LM_DEBUG, "ImR Activator: Contacting ImplRepoService...\n"));
00069 
00070       // First, resolve the ImR, without this we can go no further
00071       CORBA::Object_var obj =
00072         orb_->resolve_initial_references ("ImplRepoService" ACE_ENV_ARG_PARAMETER);
00073       ACE_TRY_CHECK;
00074 
00075       this->process_mgr_.open (ACE_Process_Manager::DEFAULT_SIZE,
00076         this->orb_->orb_core ()->reactor ());
00077 
00078       locator_ = ImplementationRepository::Locator::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
00079       ACE_TRY_CHECK;
00080 
00081       if (!CORBA::is_nil (locator_.in ()))
00082         {
00083           this->registration_token_ =
00084             locator_->register_activator (name_.c_str (), activator ACE_ENV_ARG_PARAMETER);
00085           ACE_TRY_CHECK;
00086 
00087           if (debug_ > 0)
00088             ACE_DEBUG((LM_DEBUG, "ImR Activator: Registered with ImR.\n"));
00089 
00090           return;
00091         }
00092     }
00093   ACE_CATCHANY
00094     {
00095       if (debug_ > 1)
00096         ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR Activator: Can't register with ImR.");
00097     }
00098   ACE_ENDTRY;
00099 
00100   if (debug_ > 0)
00101     ACE_DEBUG ((LM_DEBUG, "ImR Activator: Not registered with ImR.\n"));
00102 }
00103 
00104 int
00105 ImR_Activator_i::init_with_orb (CORBA::ORB_ptr orb, const Activator_Options& opts ACE_ENV_ARG_DECL)
00106 {
00107   ACE_ASSERT(! CORBA::is_nil (orb));
00108   orb_ = CORBA::ORB::_duplicate (orb);
00109   debug_ = opts.debug ();
00110   notify_imr_ = opts.notify_imr ();
00111   if (opts.name ().length () > 0)
00112     {
00113       name_ = opts.name();
00114     }
00115 
00116   ACE_TRY
00117     {
00118       CORBA::Object_var obj = orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER);
00119       ACE_TRY_CHECK;
00120       ACE_ASSERT (! CORBA::is_nil (obj.in ()));
00121       this->root_poa_ = PortableServer::POA::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
00122       ACE_TRY_CHECK;
00123       ACE_ASSERT (! CORBA::is_nil(this->root_poa_.in ()));
00124 
00125       // The activator must use a persistent POA so that it can be started before the
00126       // locator in some scenarios, such as when the locator persists its database, and
00127       // wants to reconnect to running activators to auto_start some servers.
00128       this->imr_poa_ = createPersistentPOA (this->root_poa_.in (),
00129         "ImR_Activator" ACE_ENV_ARG_PARAMETER);
00130       ACE_TRY_CHECK;
00131       ACE_ASSERT (! CORBA::is_nil(this->imr_poa_.in ()));
00132 
00133       // Activate ourself
00134       PortableServer::ObjectId_var id = PortableServer::string_to_ObjectId ("ImR_Activator");
00135       this->imr_poa_->activate_object_with_id (id.in (), this ACE_ENV_ARG_PARAMETER);
00136       ACE_TRY_CHECK;
00137       obj = this->imr_poa_->id_to_reference (id.in () ACE_ENV_ARG_PARAMETER);
00138       ACE_TRY_CHECK;
00139       ImplementationRepository::Activator_var activator =
00140         ImplementationRepository::Activator::_narrow (obj.in () ACE_ENV_ARG_PARAMETER);
00141       ACE_TRY_CHECK;
00142       ACE_ASSERT(! CORBA::is_nil (activator.in ()));
00143 
00144       CORBA::String_var ior = this->orb_->object_to_string (activator.in () ACE_ENV_ARG_PARAMETER);
00145       ACE_TRY_CHECK;
00146 
00147       if (this->debug_ > 0)
00148         ACE_DEBUG((LM_DEBUG, "ImR Activator: Starting %s\n", name_.c_str ()));
00149 
00150       // initialize our process manager.
00151       // This requires a reactor that has signal handling.
00152       ACE_Reactor *reactor = ACE_Reactor::instance ();
00153       if (reactor != 0)
00154         {
00155           if (this->process_mgr_.open (ACE_Process_Manager::DEFAULT_SIZE, reactor) == -1)
00156             {
00157               ACE_ERROR_RETURN ((LM_ERROR,
00158                 "The ACE_Process_Manager didnt get initialized\n"), -1);
00159             }
00160         }
00161 
00162       this->register_with_imr (activator.in ()); // no throw
00163 
00164       PortableServer::POAManager_var poaman =
00165         this->root_poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER);
00166       ACE_TRY_CHECK;
00167       poaman->activate (ACE_ENV_SINGLE_ARG_PARAMETER);
00168       ACE_TRY_CHECK;
00169 
00170       if (this->debug_ > 1)
00171         {
00172           ACE_DEBUG ((LM_DEBUG,
00173             "ImR Activator: The Activator IOR is: <%s>\n", ior.in ()));
00174         }
00175 
00176       // The last thing we do is write out the ior so that a test program can assume
00177       // that the activator is ready to go as soon as the ior is written.
00178       if (opts.ior_filename ().length () > 0)
00179         {
00180           FILE* fp = ACE_OS::fopen (opts.ior_filename ().c_str (), "w");
00181           if (fp == 0)
00182             {
00183               ACE_ERROR_RETURN ((LM_ERROR,
00184                 "ImR Activator: Could not open file: %s\n", opts.ior_filename ().c_str ()), -1);
00185             }
00186           ACE_OS::fprintf (fp, "%s", ior.in ());
00187           ACE_OS::fclose (fp);
00188         }
00189     }
00190   ACE_CATCHANY
00191     {
00192       ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR_Activator_i::init_with_orb");
00193       ACE_RE_THROW;
00194     }
00195   ACE_ENDTRY;
00196   ACE_CHECK_RETURN (-1);
00197   return 0;
00198 }
00199 
00200 int
00201 ImR_Activator_i::init (Activator_Options& opts ACE_ENV_ARG_DECL)
00202 {
00203   ACE_CString cmdline = opts.cmdline();
00204   // Must use IOR style objrefs, because URLs sometimes get mangled when passed
00205   // to ACE_Process::spawn().
00206   cmdline += "-ORBUseImR 0 -ORBObjRefStyle IOR ";
00207   ACE_ARGV av (cmdline.c_str ());
00208   int argc = av.argc ();
00209 
00210   CORBA::ORB_var orb =
00211     CORBA::ORB_init (argc, av.argv (), "TAO_ImR_Activator" ACE_ENV_ARG_PARAMETER);
00212   ACE_CHECK_RETURN(-1);
00213 
00214   int ret = this->init_with_orb(orb.in (), opts ACE_ENV_ARG_PARAMETER);
00215   ACE_CHECK_RETURN(-1);
00216 
00217   return ret;
00218 }
00219 
00220 int
00221 ImR_Activator_i::fini (ACE_ENV_SINGLE_ARG_DECL)
00222 {
00223   ACE_TRY_EX (try_block_1)
00224     {
00225       if (debug_ > 1)
00226         ACE_DEBUG ((LM_DEBUG, "ImR Activator: Shutting down...\n"));
00227 
00228       this->process_mgr_.close ();
00229 
00230       this->root_poa_->destroy (1, 1 ACE_ENV_ARG_PARAMETER);
00231       ACE_TRY_CHECK_EX (try_block_1);
00232 
00233       if (! CORBA::is_nil (this->locator_.in ()) && this->registration_token_ != 0)
00234         {
00235           this->locator_->unregister_activator (name_.c_str(),
00236             this->registration_token_ ACE_ENV_ARG_PARAMETER);
00237           ACE_TRY_CHECK_EX (try_block_1);
00238         }
00239     }
00240   ACE_CATCH(CORBA::COMM_FAILURE, ex)
00241     {
00242       if (debug_ > 1)
00243         ACE_DEBUG ((LM_DEBUG, "ImR Activator: Unable to unregister from ImR.\n"));
00244     }
00245   ACE_CATCH(CORBA::TRANSIENT, ex)
00246     {
00247       if (debug_ > 1)
00248         ACE_DEBUG ((LM_DEBUG, "ImR Activator: Unable to unregister from ImR.\n"));
00249     }
00250   ACE_CATCHANY
00251   {
00252     ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR Activator: fini");
00253     ACE_RE_THROW_EX (try_block_1);
00254   }
00255   ACE_ENDTRY;
00256   ACE_CHECK_RETURN (-1);
00257 
00258   ACE_TRY_EX (try_block_2)
00259     {
00260       this->orb_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00261       ACE_TRY_CHECK_EX (try_block_2);
00262 
00263       if (debug_ > 0)
00264         ACE_DEBUG ((LM_DEBUG, "ImR Activator: Shut down successfully.\n"));
00265     }
00266   ACE_CATCHANY
00267     {
00268       ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "ImR Activator: fini 2");
00269       ACE_RE_THROW_EX (try_block_2);
00270     }
00271   ACE_ENDTRY;
00272   ACE_CHECK_RETURN (-1);
00273   return 0;
00274 }
00275 
00276 int
00277 ImR_Activator_i::run (ACE_ENV_SINGLE_ARG_DECL)
00278 {
00279   this->orb_->run (ACE_ENV_SINGLE_ARG_PARAMETER);
00280   ACE_CHECK_RETURN (-1);
00281   return 0;
00282 }
00283 
00284 void
00285 ImR_Activator_i::shutdown (ACE_ENV_SINGLE_ARG_DECL)
00286 ACE_THROW_SPEC ((CORBA::SystemException))
00287 {
00288   shutdown (false ACE_ENV_ARG_PARAMETER);
00289 }
00290 
00291 void
00292 ImR_Activator_i::shutdown (bool wait_for_completion ACE_ENV_ARG_DECL)
00293 {
00294   this->orb_->shutdown (wait_for_completion ACE_ENV_ARG_PARAMETER);
00295 }
00296 
00297 void
00298 ImR_Activator_i::start_server(const char* name,
00299                               const char* cmdline,
00300                               const char* dir,
00301                               const ImplementationRepository::EnvironmentList & env ACE_ENV_ARG_DECL)
00302                               ACE_THROW_SPEC ((CORBA::SystemException, ImplementationRepository::CannotActivate))
00303 {
00304   if (debug_ > 1)
00305     ACE_DEBUG((LM_DEBUG, "ImR Activator: Starting server <%s>...\n", name));
00306   if (debug_ > 1)
00307     ACE_DEBUG((LM_DEBUG, "\tcommand line : <%s>\n\tdirectory : <%s>\n", cmdline, dir));
00308 
00309   ACE_Process_Options proc_opts;
00310   proc_opts.command_line (cmdline);
00311   proc_opts.working_directory (dir);
00312   // Win32 does not support the CLOSE_ON_EXEC semantics for sockets
00313   // the way unix does, so in order to avoid having the child process
00314   // hold the listen socket open, we force the child to inherit no
00315   // handles. This includes stdin, stdout, logs, etc.
00316   proc_opts.handle_inheritence (0);
00317 
00318   proc_opts.setenv ("TAO_USE_IMR", "1");
00319   if (!CORBA::is_nil (this->locator_.in ()))
00320     {
00321       CORBA::String_var ior = orb_->object_to_string (locator_.in ());
00322       proc_opts.setenv ("ImplRepoServiceIOR", ior.in());
00323     }
00324 
00325   for (CORBA::ULong i = 0; i < env.length (); ++i)
00326     {
00327       proc_opts.setenv (env[i].name.in (), env[i].value.in ());
00328     }
00329 
00330   int pid = this->process_mgr_.spawn (proc_opts);
00331   if (pid == ACE_INVALID_PID)
00332     {
00333       ACE_ERROR ((LM_ERROR,
00334         "ImR Activator: Cannot start server <%s> using <%s>\n", name, cmdline));
00335 
00336       ACE_THROW(ImplementationRepository::CannotActivate(CORBA::string_dup ("Process Creation Failed")));
00337       return;
00338     }
00339   else
00340     {
00341       if (debug_ > 1)
00342         {
00343           ACE_DEBUG((LM_DEBUG,
00344             "ImR Activator: register death handler for process %d\n", pid));
00345         }
00346       this->process_mgr_.register_handler (this, pid);
00347 
00348       // We only bind to the process_map_ if we want to notify
00349       // the locator of a process' death.
00350       if (notify_imr_)
00351         {
00352           this->process_map_.rebind (pid, name);
00353         }
00354     }
00355 
00356   if (debug_ > 0)
00357     {
00358       ACE_DEBUG ((LM_DEBUG, "ImR Activator: Successfully started <%s>. \n", name));
00359     }
00360 }
00361 
00362 int
00363 ImR_Activator_i::handle_exit (ACE_Process * process)
00364 {
00365   // We use the process_manager so that we're notified when
00366   // any of our launched processes die. We notify the locator
00367   // when this happens.
00368 
00369   if (debug_ > 0)
00370     {
00371       ACE_DEBUG
00372         ((LM_DEBUG,
00373         ACE_TEXT ("Process %d exited with exit code %d\n"),
00374         process->getpid (), process->return_value ()));
00375     }
00376 
00377   ACE_CString name;
00378   if (this->process_map_.find (process->getpid (), name) == 0)
00379     {
00380       this->process_map_.unbind (process->getpid ());
00381 
00382       if (!CORBA::is_nil (this->locator_.in ()))
00383         {
00384           if (debug_ > 1)
00385             {
00386               ACE_DEBUG ((LM_DEBUG,
00387                 ACE_TEXT ("ImR Activator: Notifying ImR that %s has exited.\n"),
00388                 name.c_str()));
00389             }
00390           this->locator_->notify_child_death (name.c_str());
00391         }
00392     }
00393 
00394   return 0;
00395 }

Generated on Thu Nov 9 13:36:19 2006 for TAO_Implementation_Repository by doxygen 1.3.6