From fa67885d383d477c1d8c0482d57a71bad8f868f3 Mon Sep 17 00:00:00 2001 From: Ossama Othman Date: Tue, 12 Nov 2002 04:33:50 +0000 Subject: ChangeLogTag:Mon Nov 11 20:31:18 2002 Ossama Othman --- TAO/ChangeLog | 22 ++++++++ TAO/orbsvcs/LoadBalancer/LoadManager.cpp | 87 +++++++++++++++++++++++++++++--- TAO/orbsvcs/LoadBalancer/LoadMonitor.cpp | 79 ++++++++++++++++++++++++++++- 3 files changed, 179 insertions(+), 9 deletions(-) diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 1013b85ae86..d28f0babf7b 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,25 @@ +Mon Nov 11 20:31:18 2002 Ossama Othman + + * orbsvcs/LoadBalancer/LoadManager.cpp (TAO_LB_run_load_manager): + * orbsvcs/LoadBalancer/LoadMonitor.cpp (TAO_LB_run_load_monitor): + + New global function that is run when the Load{Manager,Monitor}'s + ORB thread is run. It is only used on Linux when multi-thread + support is enabled. This is part of a work-around for the + problem where signals can only be handled in the main() thread + on Linux. + + (ACE_TMAIN): + + Spawn a new thread to run the LoadManager's ORB, and handle + signals in this (main()) thread. This is the second part of a + work-around for the problem where signals can only be handled in + the main() thread on Linux. + + Moved signal handler activation to just before the point where + the ORB is run. There is no need to activate the signal handler + earlier than there. + Mon Nov 11 19:22:05 2002 Ossama Othman * orbsvcs/orbsvcs/LoadBalancing/LB_ObjectReferenceFactory.h: diff --git a/TAO/orbsvcs/LoadBalancer/LoadManager.cpp b/TAO/orbsvcs/LoadBalancer/LoadManager.cpp index 9eba0dfcaf4..ba1a9ac0f3d 100644 --- a/TAO/orbsvcs/LoadBalancer/LoadManager.cpp +++ b/TAO/orbsvcs/LoadBalancer/LoadManager.cpp @@ -6,6 +6,10 @@ #include "ace/Get_Opt.h" +#if defined (linux) && defined (ACE_HAS_THREADS) +# include "ace/Signal.h" +#endif /* linux && ACE_HAS_THREADS */ + ACE_RCSID (LoadBalancer, LoadBalancer, @@ -72,6 +76,41 @@ 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_manager (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 Manager"); + + return ACE_reinterpret_cast (void *, -1); + } + ACE_ENDTRY; + ACE_CHECK_RETURN (ACE_reinterpret_cast (void *, -1)); + + return 0; +} +#endif /* linux && ACE_HAS_THREADS */ + int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { @@ -116,14 +155,6 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[]) ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; - // Activate/register the signal handler that (attempts) to - // ensure graceful shutdown of the LoadManager so that remote - // resources created by the LoadManager can be cleaned up. - TAO_LB_Signal_Handler signal_handler (orb.in (), root_poa.in ()); - - if (signal_handler.activate () != 0) - return -1; - TAO_LB_LoadManager * lm; ACE_NEW_THROW_EX (lm, TAO_LB_LoadManager, @@ -188,8 +219,48 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[]) ACE_OS::fprintf (lm_ior, "%s", str.in ()); ACE_OS::fclose (lm_ior); +#if defined (linux) && defined (ACE_HAS_THREADS) + if (ACE_Thread_Manager::instance ()->spawn (::TAO_LB_run_load_manager, + orb.in ()) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "ERROR: Unable to spawn TAO LoadManager'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); +#else + // Activate/register the signal handler that (attempts) to + // ensure graceful shutdown of the LoadManager so that remote + // resources created by the LoadManager can be cleaned up. + TAO_LB_Signal_Handler signal_handler (orb.in (), root_poa.in ()); + + 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 */ orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_TRY_CHECK; 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. -- cgit v1.2.1