AtmiBrokerSignalHandler.cxx
上传用户:xfwatch
上传日期:2020-12-14
资源大小:872k
文件大小:6k
源码类别:

中间件编程

开发平台:

Java

  1. /*
  2.  * JBoss, Home of Professional Open Source
  3.  * Copyright 2010, Red Hat, Inc., and others contributors as indicated
  4.  * by the @authors tag. All rights reserved.
  5.  * See the copyright.txt in the distribution for a
  6.  * full listing of individual contributors.
  7.  * This copyrighted material is made available to anyone wishing to use,
  8.  * modify, copy, or redistribute it subject to the terms and conditions
  9.  * of the GNU Lesser General Public License, v. 2.1.
  10.  * This program is distributed in the hope that it will be useful, but WITHOUT A
  11.  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12.  * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
  13.  * You should have received a copy of the GNU Lesser General Public License,
  14.  * v.2.1 along with this distribution; if not, write to the Free Software
  15.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  16.  * MA  02110-1301, USA.
  17.  */
  18. #include "AtmiBrokerSignalHandler.h"
  19. #include "ThreadLocalStorage.h"
  20. #include "ace/Thread.h"
  21. #include "ace/OS_NS_Thread.h"
  22. #define SIGCHK(err, msg) {if ((err) != 0) LOG4CXX_WARN(logger_, (char*) (msg) << " error: " << err);}
  23. int default_handlesigs[] = {SIGINT, SIGTERM, 0};
  24. int default_blocksigs[] = {SIGQUIT, SIGABRT, SIGHUP, SIGALRM, SIGUSR1, SIGUSR2, 0};
  25. log4cxx::LoggerPtr AtmiBrokerSignalHandler::logger_(log4cxx::Logger::getLogger("AtmiBrokerSignalHandler"));
  26. ACE_Sig_Handler AtmiBrokerSignalHandler::handler_;
  27. AtmiBrokerSignalHandler::AtmiBrokerSignalHandler(int* hsignals, int* bsignals)
  28. {
  29. int* sigp;
  30. SIGCHK(ACE_OS::sigemptyset(&hss_), "sigemptyset");
  31. SIGCHK(ACE_OS::sigemptyset(&bss_), "sigemptyset");
  32. for (sigp = hsignals; *sigp != 0; sigp++) {
  33. SIGCHK(ACE_OS::sigaddset(&hss_, *sigp), "sigaddset");
  34. SIGCHK(ACE_OS::sigaddset(&bss_, *sigp), "sigaddset");
  35. }
  36. for (sigp = bsignals; *sigp != 0; sigp++) {
  37. SIGCHK(ACE_OS::sigaddset(&bss_, *sigp), "sigaddset");
  38. }
  39. for (int i = 1; i < ACE_NSIG; i++)
  40. if (ACE_OS::sigismember(&bss_, i))
  41. handler_.register_handler(i, this);
  42. }
  43. AtmiBrokerSignalHandler::~AtmiBrokerSignalHandler()
  44. {
  45. for (int i = 1; i < ACE_NSIG; i++)
  46. if (ACE_OS::sigismember(&bss_, i))
  47. handler_.remove_handler(i);
  48. }
  49. void AtmiBrokerSignalHandler::addSignalHandler(int (*handler)(int signum), bool front)
  50. {
  51.     std::vector<int (*)(int)>::iterator it;
  52. LOG4CXX_DEBUG(logger_, (char*) "adding signal handler " << &handler << " size " << handlers_.size());
  53.     if (front)
  54.         handlers_.insert(handlers_.begin(), handler);
  55.     else
  56.         handlers_.insert(handlers_.end(), handler);
  57. }
  58. int AtmiBrokerSignalHandler::handle_signal(int sig, siginfo_t *, ucontext_t *)
  59. {
  60. sigset_t* pending = (sigset_t*) getSpecific(TSS_SIG_KEY);
  61. std::vector<int (*)(int)>::iterator it;
  62. bool doexit = false;
  63. if (pending)
  64. SIGCHK(ACE_OS::sigaddset(pending, sig), "sigaddset");
  65. if (ACE_OS::sigismember(&hss_, sig)) {
  66. LOG4CXX_DEBUG(logger_, (char*) "handling signal " << sig);
  67. for (it = handlers_.begin(); it < handlers_.end(); it++) {
  68. LOG4CXX_DEBUG(logger_, (char*) "running handler " << (*it));
  69. if ((*it)(sig) == -1)
  70. doexit = true;
  71. }
  72. } else {
  73. LOG4CXX_DEBUG(logger_, (char*) "ignoring signal " << sig);
  74. }
  75. if (doexit) {
  76. LOG4CXX_INFO(logger_, (char*) "Unregistering signal handler after signal " << sig);
  77. }
  78. return 0; // -1 unregisters this handler
  79. }
  80. int AtmiBrokerSignalHandler::blockSignals(bool sigRestart) {
  81. return block_sigs(&bss_, NULL, true, !sigRestart);
  82. }
  83. int AtmiBrokerSignalHandler::unblockSignals() {
  84. sigset_t pending;
  85. int nsigs = block_sigs(&bss_, &pending, false, false);
  86. LOG4CXX_DEBUG(logger_, (char*) " unblockSignals returned " << nsigs);
  87. for (int i = 1; i <= NSIG; i++) {
  88. if (ACE_OS::sigismember(&pending, i) == 1) {
  89. LOG4CXX_DEBUG(logger_, (char*) " treceived sig during syscall " <<  i);
  90. }
  91. }
  92. return nsigs;
  93. }
  94. /**
  95.  * block or unblock signals.
  96.  * @param mask
  97.  *  the set of signals to block/unblock
  98.  * @param pending
  99.  *  out parameter for holding any signals that were received since the last blocking call
  100.  * @param block
  101.  *  if true then block signals otherwise unblock them
  102.  * @param informational
  103.  *  if true don't actually block or unblock signals but still return any signals that were
  104.  *  received since the previous call
  105.  *
  106.  * @return
  107.  *  the number of signals received since the last call
  108.  */
  109. int AtmiBrokerSignalHandler::block_sigs(sigset_t* mask, sigset_t* pending, bool block, bool informational)
  110. {
  111. int err = 0;
  112. int i;
  113. int sigcnt = 0;
  114. sigset_t* tsspending = (sigset_t*) getSpecific(TSS_SIG_KEY);
  115. if (block) {
  116. if (tsspending == NULL) {
  117. // create a new TSS holder for the signal set that may be received before
  118. // the next matching call
  119. if ((tsspending = (sigset_t*) malloc(sizeof (sigset_t))) == NULL)
  120. err = -1;
  121. else if (ACE_OS::sigemptyset(tsspending) != 0)
  122. err = -1;
  123. else
  124. setSpecific(TSS_SIG_KEY, tsspending);
  125. } else {
  126. LOG4CXX_WARN(logger_, (char*) "sigblock called but already blocking signals");
  127. }
  128. } else {
  129. // about to unblock signals - see if there was signal since they were blocked
  130. if (tsspending == NULL) {
  131. LOG4CXX_WARN(logger_, (char*) "sigunblock called but signals are not blocked");
  132. } else {
  133. destroySpecific(TSS_SIG_KEY);
  134. if (pending != NULL) {
  135. // see if there are any pending signals
  136. sigset_t pmask;
  137. if (ACE_OS::sigemptyset(pending) == -1 || ACE_OS::sigemptyset(&pmask) == -1) {
  138. LOG4CXX_WARN(logger_, (char*) " sigemptyset error");
  139. err = -1;
  140. } else {
  141. // no ACE_OS equivalent for sigpending so ifdef the call (WIN32 does not support signals)
  142. #ifndef WIN32
  143. if (sigpending(&pmask) != 0)
  144. err = -1;
  145. #endif
  146. for (i = 1; i <= NSIG; i++)
  147. if (ACE_OS::sigismember(tsspending, i) == 1 ||
  148. ACE_OS::sigismember(&pmask, i) == 1) {
  149. setSpecific(TPE_KEY, TSS_TPGOTSIG);
  150.      (void) ACE_OS::sigaddset(pending, i);
  151. sigcnt += 1;
  152. }
  153. }
  154. }
  155. free(tsspending);
  156. }
  157. }
  158. LOG4CXX_DEBUG(logger_, (char*) "blocksigs=" << block << " informational=" << informational << " rval=" << sigcnt);
  159. if (!informational) {
  160. #ifndef WIN32
  161. // TODO figure out how to handle signals on windows
  162.      if (ACE_OS::pthread_sigmask((block ? SIG_BLOCK : SIG_UNBLOCK), mask, NULL) != 0)
  163. err = -1;
  164. #endif
  165. }
  166. return (err != 0 ? err : sigcnt);
  167. }