summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/LoadBalancer/Signal_Handler.cpp
blob: 0d9fbc27eef598704e09409514ddc43553cb0dfe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// $Id$

#include "Signal_Handler.h"
#include "tao/ORB_Core.h"
#include "ace/Reactor.h"

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)
    {
      ORBSVCS_ERROR_RETURN ((LM_ERROR,
                         "(%P|%t) %p\n",
                         "ERROR waiting on signal"),
                        -1);
    }

  ACE_ASSERT (signum == SIGINT || signum == SIGTERM);

//   ORBSVCS_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 *)
{
//   ORBSVCS_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");

      ORBSVCS_ERROR_RETURN ((LM_ERROR,
                         "Problem during cleanup initiated by signal %d.\n",
                         signum),
                        -1);
    }

  return 0;
}