diff options
Diffstat (limited to 'ACE/TAO/orbsvcs/LoadBalancer/Signal_Handler.cpp')
-rw-r--r-- | ACE/TAO/orbsvcs/LoadBalancer/Signal_Handler.cpp | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/ACE/TAO/orbsvcs/LoadBalancer/Signal_Handler.cpp b/ACE/TAO/orbsvcs/LoadBalancer/Signal_Handler.cpp new file mode 100644 index 00000000000..24fda5bcdea --- /dev/null +++ b/ACE/TAO/orbsvcs/LoadBalancer/Signal_Handler.cpp @@ -0,0 +1,142 @@ +#include "Signal_Handler.h" + +#include "tao/ORB_Core.h" +#include "ace/Reactor.h" + +ACE_RCSID (LoadBalancer, + Signal_Handler, + "$Id$") + + +TAO_LB_Signal_Handler::TAO_LB_Signal_Handler (CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa) + : +#ifdef ACE_HAS_THREADS + signal_guard_ (), +#endif /* ACE_HAS_THREADS */ + sigset_ (), + orb_ (CORBA::ORB::_duplicate (orb)), + poa_ (PortableServer::POA::_duplicate (poa)) +{ + // Register signal handlers. + this->sigset_.sig_add (SIGINT); + this->sigset_.sig_add (SIGTERM); +} + +int +TAO_LB_Signal_Handler::svc (void) +{ + // This method is only invoked when performing synchronous signal + // handling. + + int signum = -1; + + // Block waiting for the registered signals. + if (ACE_OS::sigwait (this->sigset_, &signum) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p\n", + "ERROR waiting on signal"), + -1); + } + + ACE_ASSERT (signum == SIGINT || signum == SIGTERM); + +// ACE_DEBUG ((LM_DEBUG, +// ACE_TEXT ("(%P|%t) synchronous signal handler done\n"))); + + return this->perform_cleanup (signum); +} + +int +TAO_LB_Signal_Handler::activate (long flags, + int n_threads, + int force_active, + long priority, + int grp_id, + ACE_Task_Base *task, + ACE_hthread_t thread_handles[], + void *stack[], + size_t stack_size[], + ACE_thread_t thread_ids[], + const char* thr_name[]) +{ + // sigwait() is not implemented on MS Windows. Handle signals + // asynchronously through the ORB's reactor in that case instead. + // Otherwise, handle signals synchronously in another thread. + +#if defined (ACE_HAS_THREADS) && !defined (ACE_WIN32) + return this->ACE_Task_Base::activate (flags, + n_threads, + force_active, + priority, + grp_id, + task, + thread_handles, + stack, + stack_size, + thread_ids, + thr_name); +#else + ACE_UNUSED_ARG (flags); + ACE_UNUSED_ARG (n_threads); + ACE_UNUSED_ARG (force_active); + ACE_UNUSED_ARG (priority); + ACE_UNUSED_ARG (grp_id); + ACE_UNUSED_ARG (task); + ACE_UNUSED_ARG (thread_handles); + ACE_UNUSED_ARG (stack); + ACE_UNUSED_ARG (stack_size); + ACE_UNUSED_ARG (thread_ids); + ACE_UNUSED_ARG (thr_name); + + return + this->orb_->orb_core ()->reactor ()->register_handler (this->sigset_, + this); +#endif /* ACE_HAS_THREADS */ +} + +int +TAO_LB_Signal_Handler::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ +// ACE_DEBUG ((LM_DEBUG, +// ACE_TEXT ("(%P|%t) ASYNCHRONOUS signal handler done\n"))); + + // This method is only used in the asynchronous signal handling case + // (i.e. when single-threaded build is used). + + // @note Is it okay to perform ORB operations from this method? The + // issue here is whether or not + // ACE_Event_Handler::handle_signal() is called from within an + // OS signal handler, and if that did occur is it safe to + // perform ORB operations? + return this->perform_cleanup (signum); +} + +int +TAO_LB_Signal_Handler::perform_cleanup (int signum) +{ + try + { + // Shutdown the POA. + // + // Shutting down the POA will cause servants "owned" by the POA + // to be destroyed. Servants will then have the opportunity to + // clean up all resources they are responsible for. + this->poa_->destroy (1, 1); + + // Now shutdown the ORB. + this->orb_->shutdown (1); + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception ("Caught exception"); + + ACE_ERROR_RETURN ((LM_ERROR, + "Problem during cleanup initiated by signal %d.\n", + signum), + -1); + } + + return 0; +} |