summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp')
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp96
1 files changed, 75 insertions, 21 deletions
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
index 819f35b7f4f..ab2e06d5c0f 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
@@ -34,6 +34,41 @@ Active_Pid_Setter::~Active_Pid_Setter()
{
owner_.active_check_pid_ = ACE_INVALID_PID;
}
+
+Watchdog::Watchdog(ACE_Process_Manager& procman) :
+ stop_(false),
+ procman_(procman)
+{
+}
+
+int
+Watchdog::svc()
+{
+ while (!this->stop_)
+ {
+ if (this->procman_.managed() > 0)
+ {
+ this->procman_.wait(0, ACE_Time_Value(0, 25000));
+ }
+ else
+ {
+ ACE_OS::sleep (ACE_Time_Value(0, 25000));
+ }
+ }
+ return 0;
+}
+
+bool
+Watchdog::start()
+{
+ return this->activate() == 0;
+}
+void
+Watchdog::stop()
+{
+ this->stop_ = true;
+ this->wait();
+}
#endif /* ACE_WIN32 */
ImR_Activator_i::ImR_Activator_i (void)
@@ -46,6 +81,9 @@ ImR_Activator_i::ImR_Activator_i (void)
, max_env_vars_ (Activator_Options::ENVIRONMENT_MAX_VARS)
, detach_child_ (false)
, active_check_pid_ (ACE_INVALID_PID)
+#if defined (ACE_WIN32)
+ , process_watcher_ (process_mgr_)
+#endif /* ACE_WIN32 */
{
}
@@ -85,12 +123,27 @@ ImR_Activator_i::register_with_imr (ImplementationRepository::Activator_ptr acti
if (this->debug_ > 1)
ORBSVCS_DEBUG( (LM_DEBUG, "(%P|%t) ImR Activator: Contacting ImplRepoService...\n"));
- // First, resolve the ImR, without this we can go no further
- CORBA::Object_var obj =
- orb_->resolve_initial_references ("ImplRepoService");
+#if defined (ACE_WIN32)
+ // On Windows the notify of a death of a child process requires the
+ // WFMO reactor which is not the default ORB reactor type so on
+ // Windows we are using a separate task to detect a child death
+ if (!this->process_watcher_.start ())
+ {
+ if (this->debug_ > 1)
+ {
+ ORBSVCS_ERROR ((LM_ERROR, "(%P|%t) ImR Activator: Failed to start process watchdog\n"));
+ }
+ }
+ this->process_mgr_.open (ACE_Process_Manager::DEFAULT_SIZE);
+#else
this->process_mgr_.open (ACE_Process_Manager::DEFAULT_SIZE,
this->orb_->orb_core ()->reactor ());
+#endif /* ACE_WIN32 */
+
+ // First, resolve the ImR, without this we can go no further
+ CORBA::Object_var obj =
+ orb_->resolve_initial_references ("ImplRepoService");
locator_ = ImplementationRepository::Locator::_narrow (obj.in ());
@@ -103,8 +156,7 @@ ImR_Activator_i::register_with_imr (ImplementationRepository::Activator_ptr acti
ior.in()));
}
- this->registration_token_ =
- locator_->register_activator (name_.c_str (), activator);
+ this->registration_token_ = locator_->register_activator (name_.c_str (), activator);
if (debug_ > 0)
ORBSVCS_DEBUG((LM_DEBUG, "(%P|%t) ImR Activator: Registered with ImR\n"));
@@ -175,18 +227,6 @@ ImR_Activator_i::init_with_orb (CORBA::ORB_ptr orb, const Activator_Options& opt
if (this->debug_ > 0)
ORBSVCS_DEBUG((LM_DEBUG, "(%P|%t) ImR Activator: Starting <%C>\n", name_.c_str ()));
- // initialize our process manager.
- // This requires a reactor that has signal handling.
- ACE_Reactor *reactor = ACE_Reactor::instance ();
- if (reactor != 0)
- {
- if (this->process_mgr_.open (ACE_Process_Manager::DEFAULT_SIZE, reactor) == -1)
- {
- ORBSVCS_ERROR_RETURN ((LM_ERROR,
- "(%P|%t) ImR Activator: The ACE_Process_Manager didn't get initialized\n"), -1);
- }
- }
-
this->register_with_imr (activator.in ()); // no throw
PortableServer::POAManager_var poaman =
@@ -246,6 +286,11 @@ ImR_Activator_i::fini (void)
if (debug_ > 1)
ORBSVCS_DEBUG ((LM_DEBUG, "(%P|%t) ImR Activator: Shutting down...\n"));
+#if defined (ACE_WIN32)
+ // Stop our process watcher task
+ this->process_watcher_.stop ();
+#endif /* ACE_WIN32 */
+
this->process_mgr_.close ();
this->root_poa_->destroy (1, 1);
@@ -405,7 +450,7 @@ ImR_Activator_i::kill_server (const char* name, CORBA::Long lastpid, CORBA::Shor
CORBA::Boolean
ImR_Activator_i::still_alive (CORBA::Long pid)
{
- pid_t pt = static_cast<pid_t>(pid);
+ pid_t const pt = static_cast<pid_t>(pid);
bool is_running = this->process_map_.find (pt) == 0;
#if defined (ACE_WIN32)
if (is_running)
@@ -641,7 +686,7 @@ ImR_Activator_i::handle_exit (ACE_Process * process)
{
ORBSVCS_DEBUG
((LM_DEBUG,
- ACE_TEXT ("Process %d exited with exit code %d, delay = %d\n"),
+ ACE_TEXT ("(%P|%t) ImR Activator: Process %d exited with exit code %d, delay = %d\n"),
process->getpid (), process->return_value (), this->induce_delay_));
}
@@ -651,16 +696,25 @@ ImR_Activator_i::handle_exit (ACE_Process * process)
ACE_Time_Value dtv (0, this->induce_delay_ * 1000);
pid_t const pid = process->getpid();
Act_token_type token = static_cast<Act_token_type>(pid);
- r->schedule_timer (this, reinterpret_cast<void *>(token), dtv );
+ r->schedule_timer (this, reinterpret_cast<void *>(token), dtv);
}
else
{
+#if defined (ACE_WIN32)
+ // On Windows this is called from the context of the watchdog thread
+ // so we are using the reactor here to trigger a thread switch so that
+ // handle_exit_i is called from the reactor thread
+ ACE_Reactor *r = this->orb_->orb_core ()->reactor ();
+ pid_t const pid = process->getpid ();
+ Act_token_type token = static_cast<Act_token_type>(pid);
+ r->schedule_timer (this, reinterpret_cast<void *>(token), ACE_Time_Value ());
+#else
this->handle_exit_i (process->getpid());
+#endif /* ACE_WIN32 */
}
return 0;
}
-
int
ImR_Activator_i::handle_timeout (const ACE_Time_Value &, const void * tok)
{