ACE/FAQ/APG/Signals

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск

Содержание


[править] SigAction

// $Id: SigAction.cpp 94310 2011-07-09 19:10:06Z schmidt $
 
#include "ace/OS_NS_unistd.h"
#include "ace/OS_NS_stdlib.h"
#include "ace/Log_Msg.h"
// Listing 1 code/ch11
#include "ace/Signal.h"
 
// Forward declaration.
static void register_actions ();
 
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_TRACE ("::main");
 
  ::register_actions ();    // Register actions to happen.
 
  // This will be raised immediately.
  ACE_OS::kill (ACE_OS::getpid(), SIGUSR2);
 
  // This will pend until the first signal is completely
  // handled and returns, because we masked it out
  // in the registerAction call.
  ACE_OS::kill (ACE_OS::getpid (), SIGUSR1);
 
  while (ACE_OS::sleep (100) == -1)
    {
      if (errno == EINTR)
        continue;
      else
        ACE_OS::exit (1);
    }
  return 0;
}
// Listing 1
#if defined (ACE_HAS_SIG_C_FUNC)
extern "C" {
#endif
// Listing 3 code/ch11
static void my_sighandler (int signo)
{
  ACE_TRACE ("::my_sighandler");
 
  ACE_OS::kill (ACE_OS::getpid (), SIGUSR1);
 
  if (signo == SIGUSR1)
    ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Signal SIGUSR1\n")));
  else
    ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Signal SIGUSR2\n")));
 
  ACE_OS::sleep (10);
}
#if defined (ACE_HAS_SIG_C_FUNC)
}
#endif
// Listing 3
// Listing 2 code/ch11
static void register_actions ()
{
  ACE_TRACE ("::register_actions");
 
  ACE_Sig_Action sa (reinterpret_cast <ACE_SignalHandler> (my_sighandler));
 
  // Make sure we specify that SIGUSR1 will be masked out
  // during the signal handler's execution.
  ACE_Sig_Set ss;
  ss.sig_add (SIGUSR1);
  sa.mask (ss);
 
  // Register the same handler function for these
  // two signals.
  sa.register_action (SIGUSR1);
  sa.register_action (SIGUSR2);
}
// Listing 2

[править] SigGuard

// $Id: SigGuard.cpp 80826 2008-03-04 14:51:23Z wotte $
 
#include "ace/OS_NS_unistd.h"
#include "ace/Log_Msg.h"
#include "ace/Signal.h"
#include "ace/Sig_Handler.h"
 
// Listing 1
class MySignalHandler : public ACE_Event_Handler
  {
  public:
    virtual int handle_signal(int signo,
                              siginfo_t * = 0, ucontext_t * = 0)
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Signal %d\n"), signo));
      return 0;
    }
  };
 
int ACE_TMAIN (int, ACE_TCHAR *[])
{
 
  MySignalHandler sighandler;
  ACE_Sig_Handler sh;
  sh.register_handler (SIGUSR1, &sighandler);
 
  ACE_Sig_Set ss;
  ss.sig_add (SIGUSR1);
 
  ACE_Sig_Guard guard (&ss);
  {
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("Entering critical region\n")));
    ACE_OS::sleep (10);
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("Leaving  critical region\n")));
  }
 
  // Do other stuff.
 
  return 0;
}
// Listing 1

[править] SigHandler

// $Id: SigHandler.cpp 94310 2011-07-09 19:10:06Z schmidt $
 
#include "ace/OS_NS_unistd.h"
#include "ace/Log_Msg.h"
#include "ace/Signal.h"
#include "ace/Sig_Handler.h"
 
// Listing 1 code/ch11
class MySignalHandler : public ACE_Event_Handler
{
public:
  MySignalHandler (int signum) : signum_(signum)
  { }
 
  virtual ~MySignalHandler()
  { }
 
  virtual int handle_signal (int signum,
                             siginfo_t * = 0,
                             ucontext_t * = 0)
  {
    ACE_TRACE ("MySignalHandler::handle_signal");
 
    // Make sure the right handler was called back.
    ACE_ASSERT (signum == this->signum_);
 
    ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%S occured\n"), signum));
    return 0;
  }
 
private:
  int signum_;
};
// Listing 1
// Listing 2 code/ch11
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  MySignalHandler h1 (SIGUSR1), h2 (SIGUSR2);
  ACE_Sig_Handler handler;
  handler.register_handler (SIGUSR1, &h1);
  handler.register_handler (SIGUSR2, &h2);
 
  ACE_OS::kill (ACE_OS::getpid (), SIGUSR1);
  ACE_OS::kill (ACE_OS::getpid (), SIGUSR2);
 
  int time = 10;
  while ((time = ACE_OS::sleep (time)) == -1)
    {
      if (errno == EINTR)
        continue;
      else
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             ACE_TEXT ("%p\n"),
                             ACE_TEXT ("sleep")), -1);
        }
    }
  return 0;
}
// Listing 2

[править] SigHandlers

// $Id: SigHandlers.cpp 94310 2011-07-09 19:10:06Z schmidt $
 
#include "ace/OS_NS_unistd.h"
#include "ace/Log_Msg.h"
#include "ace/Signal.h"
#include "ace/Sig_Handler.h"
 
class MySignalHandler : public ACE_Event_Handler
{
public:
  MySignalHandler (int signum) : signum_(signum)
  { }
 
  virtual ~MySignalHandler ()
  { }
 
  virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0)
  {
    ACE_TRACE ("MySignalHandler::handle_signal");
 
    // Make sure the right handler was called back..
    ACE_ASSERT(signum == this->signum_);
 
    ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d occured\n"), signum));
 
    return 0;
  }
 
private:
  int signum_;
};
 
// Listing 1 code/ch11
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  MySignalHandler h1 (SIGUSR1), h2 (SIGUSR1);
  ACE_Sig_Handlers handler;
  handler.register_handler (SIGUSR1, &h1);
  handler.register_handler (SIGUSR1, &h2);
 
  ACE_OS::kill (ACE_OS::getpid (), SIGUSR1);
 
  int time = 10;
  while ((time = ACE_OS::sleep (time)) == -1)
    {
      if (errno == EINTR)
        continue;
      else
        ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
                           ACE_TEXT ("sleep")), -1);
    }
  return 0;
}
// Listing 1

[править] SigInfo

// $Id: SigInfo.cpp 80826 2008-03-04 14:51:23Z wotte $
 
#include "ace/Log_Msg.h"
#include "ace/Reactor.h"
#include "ace/Event_Handler.h"
#include "ace/Signal.h"
#include "ace/OS_NS_unistd.h"
#include "ace/OS_NS_string.h"
 
#if !defined (ACE_LACKS_UNIX_SIGNALS)
 
// Listing 1 code/ch11
class MySignalHandler : public ACE_Event_Handler
{
public:
  MySignalHandler () : ACE_Event_Handler()
  { }
 
  // Listing A code/ch11
  int handle_signal (int signum,
                     siginfo_t * siginfo = 0,
                     ucontext_t * = 0)
  {
    ACE_DEBUG ((LM_INFO, ACE_TEXT ("Received signal [%S]\n"),
                signum));
    if (siginfo == 0)
      {
        ACE_DEBUG ((LM_INFO,
                    ACE_TEXT ("No siginfo_t available for ")
                    ACE_TEXT ("signal [%S]\n"),
                    signum));
        return 0;
      }
    // Listing A
#if defined (__linux__)
    // Listing B code/ch11
    ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("errno for this signal is %d [%s]\n"),
                siginfo->si_errno,
                ACE_OS::strerror (siginfo->si_errno)));
    ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("signal was sent by process %d")
                ACE_TEXT (" / user %d\n"),
                siginfo->si_pid,
                siginfo->si_uid));
 
    switch (siginfo->si_code)
      {
      case SI_TIMER:
        ACE_DEBUG ((LM_INFO, ACE_TEXT ("Timer expiration\n")));
        break;
 
      case SI_USER:
        ACE_DEBUG ((LM_INFO,
                    ACE_TEXT ("Sent by kill, sigsend or raise\n")));
        break;
 
      case SI_KERNEL:
        ACE_DEBUG ((LM_INFO,
                    ACE_TEXT ("Sent by kernel\n")));
        break;
        // ...
      };
 
    // Listing B
 
    // Listing C code/ch11
    switch (signum)
      {
      case SIGFPE:
        switch (siginfo->si_code)
          {
          case FPE_INTDIV:
          case FPE_FLTDIV:
            ACE_DEBUG ((LM_INFO,
                        ACE_TEXT ("Divide by zero at %@\n"),
                        siginfo->si_addr));
            break;
 
          case FPE_INTOVF:
          case FPE_FLTOVF:
            ACE_DEBUG ((LM_INFO,
                        ACE_TEXT ("Numeric overflow at %@\n"),
                        siginfo->si_addr));
            break;
 
          // ...
          }
        break;
 
        // Listing C
        // Listing D code/ch11
      case SIGSEGV:
        switch (siginfo->si_code)
          {
            // ...
          };
        break;
        // Listing D
 
        // Listing E code/ch11
      case SIGCHLD:
        ACE_DEBUG ((LM_INFO,
                    ACE_TEXT ("A child process has exited\n")));
        ACE_DEBUG ((LM_INFO,
                    ACE_TEXT ("The child consumed %l/%l time\n"),
                    siginfo->si_utime,
                    siginfo->si_stime));
        ACE_DEBUG ((LM_INFO,
                    ACE_TEXT ("and exited with value %d\n"),
                    siginfo->si_status));
        break;
        // ...
      }
    // Listing E
#endif /* __linux__ */
    return 0;
  }
};
// Listing 1
 
#endif /* ACE_LACKS_UNIX_SIGNALS */
 
#if !defined (ACE_LACKS_UNIX_SIGNALS)
 
int ACE_TMAIN (int, ACE_TCHAR *[])
{
#if defined (ACE_LACKS_FORK)
  //FUZZ: disable check_for_lack_ACE_OS
  ACE_DEBUG ((LM_DEBUG,
              "This example requires fork()\n"));
  //FUZZ: enable check_for_lack_ACE_OS
#else
  // Create a child process so that we can test our
  // ability to handle SIGCHLD
 
  // Listing 2 code/ch11
  ACE_Sig_Set signalSet;
  signalSet.fill_set ();
 
  MySignalHandler h1;
  ACE_Reactor::instance ()->register_handler (signalSet, &h1);
  pid_t childPid = ACE_OS::fork ();
  if (childPid == 0)      // This is the parent process.
    {
      // Exclude B
      ACE_OS::sleep (10);
      return 100;
      // Exclude B
    }
  ACE_Reactor::instance ()->run_reactor_event_loop ();
  // Listing 2
 
#endif /* ACE_LACKS_FORK */
 
  return 0;
}
 
#else
 
int
ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_DEBUG ((LM_DEBUG,
              "This example does not work on this platform.\n"));
  return 1;
}
 
#endif /* !ACE_LACKS_UNIX_SIGNALS */