00001
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 , env_buf_len_ (Activator_Options::ENVIRONMENT_BUFFER)
00028 {
00029 }
00030
00031 static PortableServer::POA_ptr
00032 createPersistentPOA (PortableServer::POA_ptr root_poa, const char* poa_name)
00033 {
00034 PortableServer::LifespanPolicy_var life =
00035 root_poa->create_lifespan_policy (PortableServer::PERSISTENT);
00036
00037 PortableServer::IdAssignmentPolicy_var assign =
00038 root_poa->create_id_assignment_policy (PortableServer::USER_ID);
00039
00040 CORBA::PolicyList pols;
00041 pols.length (2);
00042 pols[0] = PortableServer::LifespanPolicy::_duplicate (life.in ());
00043 pols[1] = PortableServer::IdAssignmentPolicy::_duplicate (assign.in ());
00044
00045 PortableServer::POAManager_var mgr = root_poa->the_POAManager ();
00046 PortableServer::POA_var poa =
00047 root_poa->create_POA(poa_name, mgr.in (), pols);
00048
00049 life->destroy ();
00050 assign->destroy ();
00051
00052 return poa._retn ();
00053 }
00054
00055
00056
00057
00058
00059 void
00060 ImR_Activator_i::register_with_imr (ImplementationRepository::Activator_ptr activator)
00061 {
00062 try
00063 {
00064 if (this->debug_ > 1)
00065 ACE_DEBUG( (LM_DEBUG, "ImR Activator: Contacting ImplRepoService...\n"));
00066
00067
00068 CORBA::Object_var obj =
00069 orb_->resolve_initial_references ("ImplRepoService");
00070
00071 this->process_mgr_.open (ACE_Process_Manager::DEFAULT_SIZE,
00072 this->orb_->orb_core ()->reactor ());
00073
00074 locator_ = ImplementationRepository::Locator::_narrow (obj.in ());
00075
00076 if (!CORBA::is_nil (locator_.in ()))
00077 {
00078 this->registration_token_ =
00079 locator_->register_activator (name_.c_str (), activator);
00080
00081 if (debug_ > 0)
00082 ACE_DEBUG((LM_DEBUG, "ImR Activator: Registered with ImR.\n"));
00083
00084 return;
00085 }
00086 }
00087 catch (const CORBA::Exception& ex)
00088 {
00089 if (debug_ > 1)
00090 ex._tao_print_exception (
00091 "ImR Activator: Can't register with ImR.");
00092 }
00093
00094 if (debug_ > 0)
00095 ACE_DEBUG ((LM_DEBUG, "ImR Activator: Not registered with ImR.\n"));
00096 }
00097
00098 int
00099 ImR_Activator_i::init_with_orb (CORBA::ORB_ptr orb, const Activator_Options& opts)
00100 {
00101 ACE_ASSERT(! CORBA::is_nil (orb));
00102 orb_ = CORBA::ORB::_duplicate (orb);
00103 debug_ = opts.debug ();
00104 notify_imr_ = opts.notify_imr ();
00105 env_buf_len_ = opts.env_buf_len ();
00106 if (opts.name ().length () > 0)
00107 {
00108 name_ = opts.name();
00109 }
00110
00111 try
00112 {
00113 CORBA::Object_var obj = orb->resolve_initial_references ("RootPOA");
00114 ACE_ASSERT (! CORBA::is_nil (obj.in ()));
00115 this->root_poa_ = PortableServer::POA::_narrow (obj.in ());
00116 ACE_ASSERT (! CORBA::is_nil(this->root_poa_.in ()));
00117
00118
00119
00120
00121 this->imr_poa_ = createPersistentPOA (this->root_poa_.in (),
00122 "ImR_Activator");
00123 ACE_ASSERT (! CORBA::is_nil(this->imr_poa_.in ()));
00124
00125
00126 PortableServer::ObjectId_var id = PortableServer::string_to_ObjectId ("ImR_Activator");
00127 this->imr_poa_->activate_object_with_id (id.in (), this);
00128 obj = this->imr_poa_->id_to_reference (id.in ());
00129 ImplementationRepository::Activator_var activator =
00130 ImplementationRepository::Activator::_narrow (obj.in ());
00131 ACE_ASSERT(! CORBA::is_nil (activator.in ()));
00132
00133 CORBA::String_var ior = this->orb_->object_to_string (activator.in ());
00134
00135 if (this->debug_ > 0)
00136 ACE_DEBUG((LM_DEBUG, "ImR Activator: Starting %s\n", name_.c_str ()));
00137
00138
00139
00140 ACE_Reactor *reactor = ACE_Reactor::instance ();
00141 if (reactor != 0)
00142 {
00143 if (this->process_mgr_.open (ACE_Process_Manager::DEFAULT_SIZE, reactor) == -1)
00144 {
00145 ACE_ERROR_RETURN ((LM_ERROR,
00146 "The ACE_Process_Manager didnt get initialized\n"), -1);
00147 }
00148 }
00149
00150 this->register_with_imr (activator.in ());
00151
00152 PortableServer::POAManager_var poaman =
00153 this->root_poa_->the_POAManager ();
00154 poaman->activate ();
00155
00156 if (this->debug_ > 1)
00157 {
00158 ACE_DEBUG ((LM_DEBUG,
00159 "ImR Activator: The Activator IOR is: <%s>\n", ior.in ()));
00160 }
00161
00162
00163
00164 if (opts.ior_filename ().length () > 0)
00165 {
00166 FILE* fp = ACE_OS::fopen (opts.ior_filename ().c_str (), "w");
00167 if (fp == 0)
00168 {
00169 ACE_ERROR_RETURN ((LM_ERROR,
00170 "ImR Activator: Could not open file: %s\n", opts.ior_filename ().c_str ()), -1);
00171 }
00172 ACE_OS::fprintf (fp, "%s", ior.in ());
00173 ACE_OS::fclose (fp);
00174 }
00175 }
00176 catch (const CORBA::Exception& ex)
00177 {
00178 ex._tao_print_exception (
00179 "ImR_Activator_i::init_with_orb");
00180 throw;
00181 }
00182 return 0;
00183 }
00184
00185 int
00186 ImR_Activator_i::init (Activator_Options& opts)
00187 {
00188 ACE_CString cmdline = opts.cmdline();
00189
00190
00191 cmdline += "-ORBUseImR 0 -ORBObjRefStyle IOR ";
00192 ACE_ARGV av (cmdline.c_str ());
00193 int argc = av.argc ();
00194
00195 CORBA::ORB_var orb =
00196 CORBA::ORB_init (argc, av.argv (), "TAO_ImR_Activator");
00197
00198 int ret = this->init_with_orb(orb.in (), opts);
00199
00200 return ret;
00201 }
00202
00203 int
00204 ImR_Activator_i::fini (void)
00205 {
00206 try
00207 {
00208 if (debug_ > 1)
00209 ACE_DEBUG ((LM_DEBUG, "ImR Activator: Shutting down...\n"));
00210
00211 this->process_mgr_.close ();
00212
00213 this->root_poa_->destroy (1, 1);
00214
00215 if (! CORBA::is_nil (this->locator_.in ()) && this->registration_token_ != 0)
00216 {
00217 this->locator_->unregister_activator (name_.c_str(),
00218 this->registration_token_);
00219 }
00220 }
00221 catch (const CORBA::COMM_FAILURE&)
00222 {
00223 if (debug_ > 1)
00224 ACE_DEBUG ((LM_DEBUG, "ImR Activator: Unable to unregister from ImR.\n"));
00225 }
00226 catch (const CORBA::TRANSIENT&)
00227 {
00228 if (debug_ > 1)
00229 ACE_DEBUG ((LM_DEBUG, "ImR Activator: Unable to unregister from ImR.\n"));
00230 }
00231 catch (const CORBA::Exception& ex)
00232 {
00233 ex._tao_print_exception ("ImR Activator: fini");
00234 throw;
00235 }
00236
00237 try
00238 {
00239 this->orb_->destroy ();
00240
00241 if (debug_ > 0)
00242 ACE_DEBUG ((LM_DEBUG, "ImR Activator: Shut down successfully.\n"));
00243 }
00244 catch (const CORBA::Exception& ex)
00245 {
00246 ex._tao_print_exception ("ImR Activator: fini 2");
00247 throw;
00248 }
00249 return 0;
00250 }
00251
00252 int
00253 ImR_Activator_i::run (void)
00254 {
00255 this->orb_->run ();
00256 return 0;
00257 }
00258
00259 void
00260 ImR_Activator_i::shutdown (void)
00261 {
00262 this->shutdown (false);
00263 }
00264
00265 void
00266 ImR_Activator_i::shutdown (bool wait_for_completion)
00267 {
00268 this->orb_->shutdown (wait_for_completion);
00269 }
00270
00271 void
00272 ImR_Activator_i::start_server(const char* name,
00273 const char* cmdline,
00274 const char* dir,
00275 const ImplementationRepository::EnvironmentList & env)
00276 {
00277 if (debug_ > 1)
00278 ACE_DEBUG((LM_DEBUG, "ImR Activator: Starting server <%s>...\n", name));
00279 if (debug_ > 1)
00280 ACE_DEBUG((LM_DEBUG, "\tcommand line : <%s>\n\tdirectory : <%s>\n", cmdline, dir));
00281
00282 ACE_Process_Options proc_opts (
00283 1,
00284 ACE_Process_Options::DEFAULT_COMMAND_LINE_BUF_LEN,
00285 this->env_buf_len_);
00286 proc_opts.command_line (cmdline);
00287 proc_opts.working_directory (dir);
00288
00289
00290
00291
00292 proc_opts.handle_inheritence (0);
00293
00294 proc_opts.setenv ("TAO_USE_IMR", "1");
00295 if (!CORBA::is_nil (this->locator_.in ()))
00296 {
00297 CORBA::String_var ior = orb_->object_to_string (locator_.in ());
00298 proc_opts.setenv ("ImplRepoServiceIOR", ior.in());
00299 }
00300
00301 for (CORBA::ULong i = 0; i < env.length (); ++i)
00302 {
00303 proc_opts.setenv (env[i].name.in (), env[i].value.in ());
00304 }
00305
00306 int pid = this->process_mgr_.spawn (proc_opts);
00307 if (pid == ACE_INVALID_PID)
00308 {
00309 ACE_ERROR ((LM_ERROR,
00310 "ImR Activator: Cannot start server <%s> using <%s>\n", name, cmdline));
00311
00312 throw ImplementationRepository::CannotActivate(
00313 CORBA::string_dup (
00314 "Process Creation Failed"));
00315 return;
00316 }
00317 else
00318 {
00319 if (debug_ > 1)
00320 {
00321 ACE_DEBUG((LM_DEBUG,
00322 "ImR Activator: register death handler for process %d\n", pid));
00323 }
00324 this->process_mgr_.register_handler (this, pid);
00325
00326
00327
00328 if (notify_imr_)
00329 {
00330 this->process_map_.rebind (pid, name);
00331 }
00332 }
00333
00334 if (debug_ > 0)
00335 {
00336 ACE_DEBUG ((LM_DEBUG, "ImR Activator: Successfully started <%s>. \n", name));
00337 }
00338 }
00339
00340 int
00341 ImR_Activator_i::handle_exit (ACE_Process * process)
00342 {
00343
00344
00345
00346
00347 if (debug_ > 0)
00348 {
00349 ACE_DEBUG
00350 ((LM_DEBUG,
00351 ACE_TEXT ("Process %d exited with exit code %d\n"),
00352 process->getpid (), process->return_value ()));
00353 }
00354
00355 ACE_CString name;
00356 if (this->process_map_.find (process->getpid (), name) == 0)
00357 {
00358 this->process_map_.unbind (process->getpid ());
00359
00360 if (!CORBA::is_nil (this->locator_.in ()))
00361 {
00362 if (debug_ > 1)
00363 {
00364 ACE_DEBUG ((LM_DEBUG,
00365 ACE_TEXT ("ImR Activator: Notifying ImR that %s has exited.\n"),
00366 name.c_str()));
00367 }
00368 this->locator_->notify_child_death (name.c_str());
00369 }
00370 }
00371
00372 return 0;
00373 }