diff options
Diffstat (limited to 'TAO/orbsvcs/LoadBalancer/LoadMonitor.cpp')
-rw-r--r-- | TAO/orbsvcs/LoadBalancer/LoadMonitor.cpp | 79 |
1 files changed, 78 insertions, 1 deletions
diff --git a/TAO/orbsvcs/LoadBalancer/LoadMonitor.cpp b/TAO/orbsvcs/LoadBalancer/LoadMonitor.cpp index dcf5af5dffd..3fed1993eb7 100644 --- a/TAO/orbsvcs/LoadBalancer/LoadMonitor.cpp +++ b/TAO/orbsvcs/LoadBalancer/LoadMonitor.cpp @@ -98,6 +98,42 @@ parse_args (int argc, } } +#if defined (linux) && defined (ACE_HAS_THREADS) +// Only the main thread can handle signals in Linux. Run the +// LoadManager in thread other than main(). +extern "C" +void * +TAO_LB_run_load_monitor (void * orb_arg) +{ + CORBA::ORB_ptr orb = ACE_static_cast (CORBA::ORB_ptr, orb_arg); + + // Only the main thread should handle signals. + // + // @@ This is probably unnecessary since no signals should be + // delivered to this thread on Linux. + ACE_Sig_Guard signal_guard; + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "TAO Load Monitor"); + + return ACE_reinterpret_cast (void *, -1); + } + ACE_ENDTRY; + ACE_CHECK_RETURN (ACE_reinterpret_cast (void *, -1)); + + return 0; +} +#endif /* linux && ACE_HAS_THREADS */ + + CosLoadBalancing::LoadMonitor_ptr get_load_monitor (CORBA::ORB_ptr orb, PortableServer::POA_ptr root_poa @@ -289,6 +325,42 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[]) tmp = CosLoadBalancing::LoadManager::_nil (); // PUSH // monitoring +#if defined (linux) && defined (ACE_HAS_THREADS) + if (ACE_Thread_Manager::instance ()->spawn (::TAO_LB_run_load_monitor, + orb.in ()) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "ERROR: Unable to spawn TAO LoadMonitor's " + "ORB thread.\n"), + -1); + } + + ACE_Sig_Set sigset; + sigset.sig_add (SIGINT); + sigset.sig_add (SIGTERM); + + int signum = -1; + + // Block waiting for the registered signals. + if (ACE_OS::sigwait (sigset, &signum) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p\n", + "ERROR waiting on signal"), + -1); + } + + ACE_ASSERT (signum == SIGINT || signum == SIGTERM); + + // Deregister the LoadMonitor from the LoadManager in the PULL + // load monitoring case. + if (timer_id == -1) + { + load_manager->remove_load_monitor (location.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } +#else // Activate/register the signal handler that (attempts) to // ensure graceful shutdown of the LoadMonitor so that // LoadMonitors registered with the LoadManager can be @@ -302,13 +374,18 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[]) if (signal_handler.activate () != 0) return -1; + // @@ There is a subtle race condition here. If the signal + // handler thread shuts down the ORB before it is run, the + // below call to ORB::run() will throw a CORBA::BAD_INV_ORDER + // exception. orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; +#endif /* linux && ACE_HAS_THREADS */ if (timer_id != -1 && reactor->cancel_timer (timer_id) == 0) { ACE_ERROR ((LM_ERROR, - ACE_TEXT ("ERROR:Unable to cancel \"push\" load ") + ACE_TEXT ("ERROR: Unable to cancel \"push\" load ") ACE_TEXT ("monitoring timer.\n"))); // Just keep going. We're shutting down anyway. |