summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Willemsen <jwillemsen@remedy.nl>2019-04-17 12:23:51 +0100
committerJohnny Willemsen <jwillemsen@remedy.nl>2019-04-17 12:23:51 +0100
commitbee73e54be4fbf202600e4e418f10d6c5c149875 (patch)
tree59fb67252f5c4bf111abfe3c4874a98528c7fdec
parentd1045f0ca57cee108f4e7c18c385a3f0475ed79e (diff)
downloadATCD-bee73e54be4fbf202600e4e418f10d6c5c149875.tar.gz
Add process watchdog for Windows
On Windows we require the WFMO_Reactor to get a notify of a child death and TAO uses the TP Reactor so use a separate task to let the process manager check the status of our child processes
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp83
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h21
2 files changed, 89 insertions, 15 deletions
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
index 3b49e2bd211..4cf0590ca79 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.cpp
@@ -34,6 +34,42 @@ 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 +82,7 @@ ImR_Activator_i::ImR_Activator_i (void)
, max_env_vars_ (Activator_Options::ENVIRONMENT_MAX_VARS)
, detach_child_ (false)
, active_check_pid_ (ACE_INVALID_PID)
+ , process_watcher_ (process_mgr_)
{
}
@@ -89,8 +126,23 @@ ImR_Activator_i::register_with_imr (ImplementationRepository::Activator_ptr acti
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 */
locator_ = ImplementationRepository::Locator::_narrow (obj.in ());
@@ -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);
@@ -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,11 +696,21 @@ 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;
}
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h
index 48fdd3544f5..8e33015511c 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Activator_i.h
@@ -20,6 +20,9 @@
#include "ace/Hash_Map_Manager.h"
#include "ace/Null_Mutex.h"
#include "ace/SString.h"
+#if defined (ACE_WIN32)
+# include "ace/Task.h"
+#endif /* ACE_WIN32 */
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
@@ -45,15 +48,28 @@ struct ACE_Equal_To_pid_t
}
};
-
#if (ACE_SIZEOF_VOID_P == 8)
typedef ACE_INT64 Act_token_type;
#else
typedef ACE_INT32 Act_token_type;
#endif
+#if defined (ACE_WIN32)
class Active_Pid_Setter;
+class Watchdog : public ACE_Task_Base
+{
+public:
+ Watchdog (ACE_Process_Manager& procman);
+ virtual int svc ();
+ bool start ();
+ void stop ();
+private:
+ bool stop_;
+ ACE_Process_Manager &procman_;
+};
+#endif /* ACE_WIN32 */
+
/**
* @class ImR_Activator_i
*
@@ -154,6 +170,9 @@ private:
bool detach_child_;
pid_t active_check_pid_;
+#if defined (ACE_WIN32)
+ Watchdog process_watcher_;
+#endif /* ACE_WIN32 */
};
#if defined (ACE_WIN32)