ACE/FAQ/APG/Reactor

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

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

Содержание


ClientService.h

/**
 * $Id: ClientService.h 80826 2008-03-04 14:51:23Z wotte $
 *
 * Sample code from The ACE Programmer's Guide,
 * copyright 2003 Addison-Wesley. All Rights Reserved.
 */
 
#ifndef __CLIENTSERVICE_H_
#define __CLIENTSERVICE_H_
 
#include "ace/Synch_Traits.h"
#include "ace/Null_Condition.h"
#include "ace/Null_Mutex.h"
 
// Listing 3 code/ch07
#include "ace/Message_Block.h"
#include "ace/SOCK_Stream.h"
#include "ace/Svc_Handler.h"
 
class ClientService :
  public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
{
  typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> super;
 
public:
  int open (void * = 0);
 
  // Called when input is available from the client.
  virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);
 
  // Called when output is possible.
  virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE);
 
  // Called when this handler is removed from the ACE_Reactor.
  virtual int handle_close (ACE_HANDLE handle,
                            ACE_Reactor_Mask close_mask);
};
// Listing 3
 
#endif /* __CLIENTSERVICE_H_ */

Client.h

/**
 * $Id: Client.h 80826 2008-03-04 14:51:23Z wotte $
 *
 * Sample code from The ACE Programmer's Guide,
 * copyright 2003 Addison-Wesley. All Rights Reserved.
 */
 
#ifndef __CLIENT_H_
#define __CLIENT_H_
 
#include "ace/Synch_Traits.h"
#include "ace/Null_Condition.h"
#include "ace/Null_Mutex.h"
 
// Listing 1 code/ch07
#include "ace/Reactor.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Stream.h"
#include "ace/SOCK_Connector.h"
#include "ace/Connector.h"
#include "ace/Svc_Handler.h"
#include "ace/Reactor_Notification_Strategy.h"
 
class Client :
    public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
{
  typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> super;
 
public:
  Client () : notifier_ (0, this, ACE_Event_Handler::WRITE_MASK)
      {}
 
  virtual int open (void * = 0);
 
  // Called when input is available from the client.
  virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);
 
  // Called when output is possible.
  virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE);
 
  // Called when a timer expires.
  virtual int handle_timeout (const ACE_Time_Value &current_time,
                              const void *act = 0);
 
private:
  enum { ITERATIONS = 5 };
  int iterations_;
  ACE_Reactor_Notification_Strategy notifier_;
};
// Listing 1
 
#endif /* __CLIENT_H_ */

A simple client program using ACE_Svc_Handler and ACE_Connector

/**
 * $Id: Client.cpp 91626 2010-09-07 10:59:20Z johnnyw $
 *
 * A simple client program using ACE_Svc_Handler and ACE_Connector.
 */
 
#include "ace/OS_NS_stdio.h"
#include "ace/OS_NS_errno.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_sys_time.h"
#include "Client.h"
 
// Listing 2 code/ch07
int Client::open (void *p)
{
  ACE_Time_Value iter_delay (2);   // Two seconds
  if (super::open (p) == -1)
    return -1;
  this->notifier_.reactor (this->reactor ());
  this->msg_queue ()->notification_strategy (&this->notifier_);
  this->iterations_ = 0;
  return this->reactor ()->schedule_timer
    (this, 0, ACE_Time_Value::zero, iter_delay);
}
// Listing 2
 
// Listing 3 code/ch07
int Client::handle_input (ACE_HANDLE)
{
  char buf[64];
  ssize_t recv_cnt = this->peer ().recv (buf, sizeof (buf) - 1);
  if (recv_cnt > 0)
    {
      ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%.*C"),
                  static_cast<int> (recv_cnt),
                  buf));
      return 0;
    }
 
  if (recv_cnt == 0 || ACE_OS::last_error () != EWOULDBLOCK)
    {
      this->reactor ()->end_reactor_event_loop ();
      return -1;
    }
  return 0;
}
// Listing 3
 
// Listing 4 code/ch07
int Client::handle_timeout(const ACE_Time_Value &, const void *)
{
  if (++this->iterations_ >= ITERATIONS)
    {
      this->peer ().close_writer ();
      return 0;
    }
 
  ACE_Message_Block *mb = 0;
  ACE_NEW_RETURN (mb, ACE_Message_Block (128), -1);
  int nbytes = ACE_OS::sprintf
    (mb->wr_ptr (), "Iteration %d\n", this->iterations_);
  ACE_ASSERT (nbytes > 0);
  mb->wr_ptr (static_cast<size_t> (nbytes));
  this->putq (mb);
  return 0;
}
// Listing 4
 
// Listing 5 code/ch07
int Client::handle_output (ACE_HANDLE)
{
  ACE_Message_Block *mb = 0;
  ACE_Time_Value nowait (ACE_OS::gettimeofday ());
  while (-1 != this->getq (mb, &nowait))
    {
      ssize_t send_cnt =
        this->peer ().send (mb->rd_ptr (), mb->length ());
      if (send_cnt == -1)
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("(%P|%t) %p\n"),
                    ACE_TEXT ("send")));
      else
        mb->rd_ptr (static_cast<size_t> (send_cnt));
      if (mb->length () > 0)
        {
          this->ungetq (mb);
          break;
        }
      mb->release ();
    }
  if (this->msg_queue ()->is_empty ())
    this->reactor ()->cancel_wakeup
      (this, ACE_Event_Handler::WRITE_MASK);
  else
    this->reactor ()->schedule_wakeup
      (this, ACE_Event_Handler::WRITE_MASK);
  return 0;
}
// Listing 5
 
// Listing 6 code/ch07
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_INET_Addr port_to_connect (ACE_TEXT ("HAStatus"), ACE_LOCALHOST);
  ACE_Connector<Client, ACE_SOCK_CONNECTOR> connector;
  Client client;
  Client *pc = &client;
  if (connector.connect (pc, port_to_connect) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
                       ACE_TEXT ("connect")), 1);
 
  ACE_Reactor::instance ()->run_reactor_event_loop ();
  return (0);
}
// Listing 6
 
// Listing 7 code/ch07
// Listing 7

HAStatus

// $Id: HAStatus-AC.cpp 80826 2008-03-04 14:51:23Z wotte $
 
#include "ace/OS_NS_errno.h"
#include "ace/OS_NS_sys_time.h"
#include "ace/os_include/os_netdb.h"
#include "ClientService.h"
 
// Listing 1 code/ch07
#include "ace/Log_Msg.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/Reactor.h"
#include "ace/Acceptor.h"
 
typedef ACE_Acceptor<ClientService, ACE_SOCK_ACCEPTOR>
  ClientAcceptor;
// Listing 1
 
// Listing 4 code/ch07
int
ClientService::open (void *p)
{
  if (super::open (p) == -1)
    return -1;
 
  ACE_TCHAR peer_name[MAXHOSTNAMELEN];
  ACE_INET_Addr peer_addr;
  if (this->peer ().get_remote_addr (peer_addr) == 0 &&
      peer_addr.addr_to_string (peer_name, MAXHOSTNAMELEN) == 0)
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("(%P|%t) Connection from %s\n"),
                peer_name));
  return 0;
}
// Listing 4
 
// Listing 5 code/ch07
int
ClientService::handle_input (ACE_HANDLE)
{
  const size_t INPUT_SIZE = 4096;
  char buffer[INPUT_SIZE];
  ssize_t recv_cnt, send_cnt;
 
  recv_cnt = this->peer ().recv (buffer, sizeof(buffer));
  if (recv_cnt <= 0)
    {
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("(%P|%t) Connection closed\n")));
      return -1;
    }
 
  send_cnt =
    this->peer ().send (buffer,
                        static_cast<size_t> (recv_cnt));
  if (send_cnt == recv_cnt)
    return 0;
  if (send_cnt == -1 && ACE_OS::last_error () != EWOULDBLOCK)
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT ("(%P|%t) %p\n"),
                       ACE_TEXT ("send")),
                      0);
  if (send_cnt == -1)
    send_cnt = 0;
  ACE_Message_Block *mb = 0;
  size_t remaining =
    static_cast<size_t> ((recv_cnt - send_cnt));
  ACE_NEW_RETURN (mb, ACE_Message_Block (remaining), -1);
  mb->copy (&buffer[send_cnt], remaining);
  int output_off = this->msg_queue ()->is_empty ();
  ACE_Time_Value nowait (ACE_OS::gettimeofday ());
  if (this->putq (mb, &nowait) == -1)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("(%P|%t) %p; discarding data\n"),
                  ACE_TEXT ("enqueue failed")));
      mb->release ();
      return 0;
    }
  if (output_off)
    return this->reactor ()->register_handler
      (this, ACE_Event_Handler::WRITE_MASK);
  return 0;
}
// Listing 5
 
// Listing 6 code/ch07
int
ClientService::handle_output (ACE_HANDLE)
{
  ACE_Message_Block *mb = 0;
  ACE_Time_Value nowait (ACE_OS::gettimeofday ());
  while (-1 != this->getq (mb, &nowait))
    {
      ssize_t send_cnt =
        this->peer ().send (mb->rd_ptr (), mb->length ());
      if (send_cnt == -1)
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("(%P|%t) %p\n"),
                    ACE_TEXT ("send")));
      else
        mb->rd_ptr (static_cast<size_t> (send_cnt));
      if (mb->length () > 0)
        {
          this->ungetq (mb);
          break;
        }
      mb->release ();
    }
  return (this->msg_queue ()->is_empty ()) ? -1 : 0;
}
// Listing 6
 
// Listing 7 code/ch07
int
ClientService::handle_close (ACE_HANDLE h, ACE_Reactor_Mask mask)
{
  if (mask == ACE_Event_Handler::WRITE_MASK)
    return 0;
  return super::handle_close (h, mask);
}
// Listing 7
 
// Listing 2 code/ch07
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_INET_Addr port_to_listen ("HAStatus");
  ClientAcceptor acceptor;
  if (acceptor.open (port_to_listen,
                     ACE_Reactor::instance (),
                     ACE_NONBLOCK) == -1)
    return 1;
 
  ACE_Reactor::instance ()->run_reactor_event_loop ();
 
  return (0);
}
// Listing 2
 
// Listing 8 code/ch07
// Listing 8

HAStatus

// $Id: HAStatus.cpp 91626 2010-09-07 10:59:20Z johnnyw $
 
#include "ace/OS_NS_sys_time.h"
#include "ace/os_include/os_netdb.h"
 
// Listing 1 code/ch07
#include "ace/Auto_Ptr.h"
#include "ace/Log_Msg.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/Reactor.h"
 
class ClientAcceptor : public ACE_Event_Handler
{
public:
  virtual ~ClientAcceptor ();
 
  //FUZZ: disable check_for_lack_ACE_OS
  int open (const ACE_INET_Addr &listen_addr);
  //FUZZ: enable check_for_lack_ACE_OS
 
  // Get this handler's I/O handle.
  virtual ACE_HANDLE get_handle (void) const
    { return this->acceptor_.get_handle (); }
 
  // Called when a connection is ready to accept.
  virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);
 
  // Called when this handler is removed from the ACE_Reactor.
  virtual int handle_close (ACE_HANDLE handle,
                            ACE_Reactor_Mask close_mask);
 
protected:
  ACE_SOCK_Acceptor acceptor_;
};
// Listing 1
 
// Listing 6 code/ch07
#include "ace/Message_Block.h"
#include "ace/Message_Queue.h"
#include "ace/SOCK_Stream.h"
#include "ace/Synch.h"
 
class ClientService : public ACE_Event_Handler
{
public:
  ACE_SOCK_Stream &peer (void) { return this->sock_; }
 
  //FUZZ: disable check_for_lack_ACE_OS
  int open (void);
  //FUZZ: enable check_for_lack_ACE_OS
 
  // Get this handler's I/O handle.
  virtual ACE_HANDLE get_handle (void) const
    { return this->sock_.get_handle (); }
 
  // Called when input is available from the client.
  virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);
 
  // Called when output is possible.
  virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE);
 
  // Called when this handler is removed from the ACE_Reactor.
  virtual int handle_close (ACE_HANDLE handle,
                            ACE_Reactor_Mask close_mask);
 
protected:
  ACE_SOCK_Stream sock_;
  ACE_Message_Queue<ACE_NULL_SYNCH> output_queue_;
};
// Listing 6
 
// Listing 5 code/ch07
ClientAcceptor::~ClientAcceptor ()
{
  this->handle_close (ACE_INVALID_HANDLE, 0);
}
// Listing 5
 
// Listing 2 code/ch07
int
ClientAcceptor::open (const ACE_INET_Addr &listen_addr)
{
  if (this->acceptor_.open (listen_addr, 1) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT ("%p\n"),
                       ACE_TEXT ("acceptor.open")),
                      -1);
  return this->reactor ()->register_handler
    (this, ACE_Event_Handler::ACCEPT_MASK);
}
// Listing 2
 
// Listing 3 code/ch07
int
ClientAcceptor::handle_input (ACE_HANDLE)
{
  ClientService *client;
  ACE_NEW_RETURN (client, ClientService, -1);
  auto_ptr<ClientService> p (client);
 
  if (this->acceptor_.accept (client->peer ()) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT ("(%P|%t) %p\n"),
                       ACE_TEXT ("Failed to accept ")
                       ACE_TEXT ("client connection")),
                      -1);
  p.release ();
  client->reactor (this->reactor ());
  if (client->open () == -1)
    client->handle_close (ACE_INVALID_HANDLE, 0);
  return 0;
}
// Listing 3
 
// Listing 4 code/ch07
int
ClientAcceptor::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
{
  if (this->acceptor_.get_handle () != ACE_INVALID_HANDLE)
    {
      ACE_Reactor_Mask m = ACE_Event_Handler::ACCEPT_MASK |
                           ACE_Event_Handler::DONT_CALL;
      this->reactor ()->remove_handler (this, m);
      this->acceptor_.close ();
    }
  return 0;
}
// Listing 4
 
// Listing 7 code/ch07
int
ClientService::open (void)
{
  ACE_TCHAR peer_name[MAXHOSTNAMELEN];
  ACE_INET_Addr peer_addr;
  if (this->sock_.get_remote_addr (peer_addr) == 0 &&
      peer_addr.addr_to_string (peer_name, MAXHOSTNAMELEN) == 0)
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("(%P|%t) Connection from %s\n"),
                peer_name));
  return this->reactor ()->register_handler
    (this, ACE_Event_Handler::READ_MASK);
}
// Listing 7
 
// Listing 8 code/ch07
int
ClientService::handle_input (ACE_HANDLE)
{
  const size_t INPUT_SIZE = 4096;
  char buffer[INPUT_SIZE];
  ssize_t recv_cnt, send_cnt;
 
  if ((recv_cnt = this->sock_.recv (buffer, sizeof(buffer))) <= 0)
    {
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("(%P|%t) Connection closed\n")));
      return -1;
    }
 
  send_cnt =
    this->sock_.send (buffer, static_cast<size_t> (recv_cnt));
  if (send_cnt == recv_cnt)
    return 0;
  if (send_cnt == -1 && ACE_OS::last_error () != EWOULDBLOCK)
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT ("(%P|%t) %p\n"),
                       ACE_TEXT ("send")),
                      0);
  if (send_cnt == -1)
    send_cnt = 0;
  ACE_Message_Block *mb = 0;
  size_t remaining =
    static_cast<size_t> ((recv_cnt - send_cnt));
  ACE_NEW_RETURN (mb, ACE_Message_Block (remaining), -1);
  mb->copy (&buffer[send_cnt], remaining);
  int output_off = this->output_queue_.is_empty ();
  ACE_Time_Value nowait (ACE_OS::gettimeofday ());
  if (this->output_queue_.enqueue_tail (mb, &nowait) == -1)
    {
      ACE_ERROR ((LM_ERROR,
                  ACE_TEXT ("(%P|%t) %p; discarding data\n"),
                  ACE_TEXT ("enqueue failed")));
      mb->release ();
      return 0;
    }
  if (output_off)
    return this->reactor ()->register_handler
      (this, ACE_Event_Handler::WRITE_MASK);
  return 0;
}
// Listing 8
 
// Listing 9 code/ch07
int
ClientService::handle_output (ACE_HANDLE)
{
  ACE_Message_Block *mb = 0;
  ACE_Time_Value nowait (ACE_OS::gettimeofday ());
  while (0 <= this->output_queue_.dequeue_head
                                    (mb, &nowait))
    {
      ssize_t send_cnt =
        this->sock_.send (mb->rd_ptr (), mb->length ());
      if (send_cnt == -1)
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("(%P|%t) %p\n"),
                    ACE_TEXT ("send")));
      else
        mb->rd_ptr (static_cast<size_t> (send_cnt));
      if (mb->length () > 0)
        {
          this->output_queue_.enqueue_head (mb);
          break;
        }
      mb->release ();
    }
  return (this->output_queue_.is_empty ()) ? -1 : 0;
}
// Listing 9
 
// Listing 10 code/ch07
int
ClientService::handle_close (ACE_HANDLE, ACE_Reactor_Mask mask)
{
  if (mask == ACE_Event_Handler::WRITE_MASK)
    return 0;
  mask = ACE_Event_Handler::ALL_EVENTS_MASK |
         ACE_Event_Handler::DONT_CALL;
  this->reactor ()->remove_handler (this, mask);
  this->sock_.close ();
  this->output_queue_.flush ();
  delete this;
  return 0;
}
// Listing 10
 
// Listing 12 code/ch07
class LoopStopper : public ACE_Event_Handler
{
public:
  LoopStopper (int signum = SIGINT);
 
  // Called when object is signaled by OS.
  virtual int handle_signal (int signum,
                             siginfo_t * = 0,
                             ucontext_t * = 0);
};
 
LoopStopper::LoopStopper (int signum)
{
  ACE_Reactor::instance ()->register_handler (signum, this);
}
 
int
LoopStopper::handle_signal (int, siginfo_t *, ucontext_t *)
{
  ACE_Reactor::instance ()->end_reactor_event_loop ();
  return 0;
}
// Listing 12
 
// Listing 13 code/ch07
#include "ace/Signal.h"
 
class LogSwitcher : public ACE_Event_Handler
{
public:
  LogSwitcher (int on_sig, int off_sig);
 
  // Called when object is signaled by OS.
  virtual int handle_signal (int signum,
                             siginfo_t * = 0,
                             ucontext_t * = 0);
 
  // Called when an exceptional event occurs.
  virtual int handle_exception (ACE_HANDLE fd = ACE_INVALID_HANDLE);
 
private:
  LogSwitcher () {}
 
  int on_sig_;       // Signal to turn logging on
  int off_sig_;      // Signal to turn logging off
  int on_off_;       // 1 == turn on, 0 == turn off
};
 
LogSwitcher::LogSwitcher (int on_sig, int off_sig)
  : on_sig_ (on_sig), off_sig_ (off_sig)
{
  ACE_Sig_Set sigs;
  sigs.sig_add (on_sig);
  sigs.sig_add (off_sig);
  ACE_Reactor::instance ()->register_handler (sigs, this);
}
// Listing 13
 
// Listing 14 code/ch07
int
LogSwitcher::handle_signal (int signum, siginfo_t *, ucontext_t *)
{
  if (signum == this->on_sig_ || signum == this->off_sig_)
    {
      this->on_off_ = signum == this->on_sig_;
      ACE_Reactor::instance ()->notify (this);
    }
  return 0;
}
// Listing 14
 
// Listing 15 code/ch07
int
LogSwitcher::handle_exception (ACE_HANDLE)
{
  if (this->on_off_)
    ACE_LOG_MSG->clr_flags (ACE_Log_Msg::SILENT);
  else
    ACE_LOG_MSG->set_flags (ACE_Log_Msg::SILENT);
  return 0;
}
// Listing 15
 
// Listing 11 code/ch07
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_INET_Addr port_to_listen ("HAStatus");
  ClientAcceptor acceptor;
  acceptor.reactor (ACE_Reactor::instance ());
  if (acceptor.open (port_to_listen) == -1)
    return 1;
 
  ACE_Reactor::instance ()->run_reactor_event_loop ();
 
  return (0);
}
// Listing 11

Reschedule

/**
 * $Id: Reschedule.cpp 80826 2008-03-04 14:51:23Z wotte $
 *
 * Changing the interval
 */
 
#include "ace/OS_NS_time.h"
#include "ace/Log_Msg.h"
#include "ace/Reactor.h"
#include "ace/Event_Handler.h"
 
class MyTimerHandler : public ACE_Event_Handler
{
public:
  int handle_timeout (const ACE_Time_Value &current_time,
                      const void * = 0 )
  {
    time_t epoch = ((timespec_t)current_time).tv_sec;
    ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("handle_timeout: %s"),
                ACE_OS::ctime(&epoch)));
    return 0;
  }
 
};
 
// Listing 1 code/ch07
class SigintHandler : public ACE_Event_Handler
{
public:
  SigintHandler (long timerId, int currentInterval)
    : ACE_Event_Handler(),
      timerId_(timerId),
      currentInterval_(currentInterval)
  {
  }
 
  int handle_signal (int,
                     siginfo_t * = 0,
                     ucontext_t * = 0)
  {
    ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("Resetting interval of timer ")
                ACE_TEXT ("%d to %d\n"),
                this->timerId_,
                ++this->currentInterval_));
    ACE_Time_Value newInterval (this->currentInterval_);
    ACE_Reactor::instance()->
      reset_timer_interval (this->timerId_, newInterval);
    return 0;
  }
 
private:
  long timerId_;
  int currentInterval_;
};
// Listing 1
 
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_Time_Value initialDelay (3);
  ACE_Time_Value interval (5);
 
  // Listing 2 code/ch07
  MyTimerHandler *handler = new MyTimerHandler ();
 
  long timerId =
    ACE_Reactor::instance ()->schedule_timer (handler,
                                              0,
                                              initialDelay,
                                              interval);
  // Listing 2
 
  // Listing 3 code/ch07
  SigintHandler *handleSigint =
    new SigintHandler (timerId, 5);
  ACE_Reactor::instance ()->register_handler (SIGINT,
                                              handleSigint);
  // Listing 3
 
  ACE_Reactor::instance ()->run_reactor_event_loop ();
  return 0;
}

Schedule Timers

/**
 * $Id: Schedule_Timers.cpp 80826 2008-03-04 14:51:23Z wotte $
 *
 * Scheduling timers with the Reactor
 */
 
#include "ace/OS_NS_time.h"
#include "ace/Log_Msg.h"
#include "ace/Reactor.h"
#include "ace/Event_Handler.h"
 
// Listing 1 code/ch07
class MyTimerHandler : public ACE_Event_Handler
{
public:
  int handle_timeout (const ACE_Time_Value &current_time,
                      const void * = 0)
  {
    time_t epoch = ((timespec_t)current_time).tv_sec;
 
    ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("handle_timeout: %s\n"),
                ACE_OS::ctime (&epoch)));
 
    return 0;
  }
};
// Listing 1
 
// Create a SIGINT handler so that we can exit
// the program politely
class SigintHandler : public ACE_Event_Handler
{
public:
  int handle_signal (int signum, siginfo_t * = 0,
                     ucontext_t * = 0)
  {
    if (signum == SIGINT)
      {
        ACE_Reactor::instance ()->end_reactor_event_loop ();
      }
    return 0;
  }
};
 
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  // Listing 2 code/ch07
  MyTimerHandler * timer = new MyTimerHandler ();
  ACE_Time_Value initialDelay (3);
  ACE_Time_Value interval (5);
  ACE_Reactor::instance()->schedule_timer (timer,
                                           0,
                                           initialDelay,
                                           interval);
  // Listing 2
 
  // Exclude 1
  SigintHandler * handleExit = new SigintHandler ();
  ACE_Reactor::instance()->register_handler (SIGINT,
                                             handleExit);
  // Exclude 1
  ACE_Reactor::instance ()->run_reactor_event_loop ();
  return 0;
}

Timer Cancel

/**
 * $Id: Timer_Cancel.cpp 80826 2008-03-04 14:51:23Z wotte $
 *
 * Changing the interval and canceling
 */
 
#include "ace/OS_NS_time.h"
#include "ace/Log_Msg.h"
#include "ace/Reactor.h"
#include "ace/Event_Handler.h"
 
class MyTimerHandler : public ACE_Event_Handler
{
public:
  int handle_timeout (const ACE_Time_Value &current_time,
                      const void * = 0)
  {
    time_t epoch = ((timespec_t)current_time).tv_sec;
    ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("handle_timeout: %s"),
                ACE_OS::ctime(&epoch)));
    return 0;
  }
 
};
 
#if !defined (ACE_LACKS_UNIX_SIGNALS)
 
// Listing 1 code/ch07
class SignalHandler : public ACE_Event_Handler
{
public:
  SignalHandler (long timerId, int currentInterval)
    : ACE_Event_Handler(),
      timerId_(timerId),
      currentInterval_(currentInterval)
  {
  }
 
  int handle_signal (int sig,
                     siginfo_t * = 0,
                     ucontext_t * = 0)
  {
    if (sig == SIGINT)
      {
        ACE_DEBUG ((LM_INFO,
                    ACE_TEXT ("Resetting interval of timer ")
                    ACE_TEXT ("%d to %d\n"),
                    this->timerId_,
                    ++this->currentInterval_));
        ACE_Time_Value newInterval (this->currentInterval_);
        ACE_Reactor::instance ()->
          reset_timer_interval (this->timerId_, newInterval);
      }
    else if (sig == SIGTSTP)
      {
        ACE_DEBUG ((LM_INFO,
                    ACE_TEXT ("Canceling timer %d\n"),
                    this->timerId_));
        ACE_Reactor::instance ()->cancel_timer (this->timerId_);
      }
 
    return 0;
  }
 
private:
  long timerId_;
  int currentInterval_;
};
// Listing 1
 
#endif /* ACE_LACKS_UNIX_SIGNALS */
 
 
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_Time_Value initialDelay (3);
  ACE_Time_Value interval (5);
 
  // Listing 2 code/ch07
  MyTimerHandler *handler = new MyTimerHandler ();
  long timerId =
    ACE_Reactor::instance ()->schedule_timer (handler,
                                              0,
                                              initialDelay,
                                              interval);
  // Listing 2
 
#if !defined (ACE_LACKS_UNIX_SIGNALS)
 
  // Listing 3 code/ch07
  SignalHandler *mutateTimer =
    new SignalHandler (timerId, 5);
  ACE_Reactor::instance ()->register_handler (SIGINT,
                                              mutateTimer);
  ACE_Reactor::instance ()->register_handler (SIGTSTP,
                                              mutateTimer);
  // Listing 3
 
#else
   ACE_UNUSED_ARG (timerId);
#endif /* ACE_LACKS_UNIX_SIGNALS */
 
  ACE_Reactor::instance ()->run_reactor_event_loop ();
  return 0;
}

Timer State Data

/**
 * $Id: Timer_State_Data.cpp 91813 2010-09-17 07:52:52Z johnnyw $
 *
 * Reactor examples
 *
 * Timers & state data
 */
 
#include "ace/OS_NS_time.h"
#include "ace/Log_Msg.h"
#include "ace/Reactor.h"
#include "ace/Event_Handler.h"
 
// Listing 0 code/ch07
class TemperatureSensor
{
public:
  TemperatureSensor (const char *location)
    : location_(location),
      count_(0),
      temperature_(0.0)
    // ...
  { }
 
  const char *location () const
  {
    return this->location_;
  }
 
  int querySensor (void)
  {
    // ...
    return ++this->count_;
  }
 
  float temperature (void) const
  {
    return this->temperature_;
  }
 
private:
  const char *location_;
  int count_;
  float temperature_;
  // ...
};
// Listing 0
 
// Listing 1 code/ch07
class TemperatureQueryHandler : public ACE_Event_Handler
{
public:
  TemperatureQueryHandler ()
    : ACE_Event_Handler(),
      counter_(0),
      averageTemperature_(0.0)
    // ...
  {
  }
 
  int handle_timeout (const ACE_Time_Value &current_time,
                      const void *arg)
  {
    time_t epoch = ((timespec_t)current_time).tv_sec;
 
    const TemperatureSensor *const_sensor =
      reinterpret_cast<const TemperatureSensor *> (arg);
    TemperatureSensor *sensor =
      const_cast<TemperatureSensor *> (const_sensor);
 
    int queryCount = sensor->querySensor ();
    this->updateAverageTemperature (sensor);
 
    ACE_DEBUG ((LM_INFO,
                ACE_TEXT ("%s\t")
                ACE_TEXT ("%d/%d\t")
                ACE_TEXT ("%.2f/%.2f\t")
                ACE_TEXT ("%s\n"),
                sensor->location (),
                ++this->counter_,
                queryCount,
                this->averageTemperature_,
                sensor->temperature (),
                ACE_OS::ctime(&epoch)));
    return 0;
  }
 
private:
  void updateAverageTemperature (TemperatureSensor *)
  {
    // ...
  }
 
  int counter_;
  float averageTemperature_;
};
// Listing 1
 
// Create a SIGINT handler so that we can exit
// the program politely
class SigintHandler : public ACE_Event_Handler
{
public:
  int handle_signal (int signum, siginfo_t * = 0,
                     ucontext_t * = 0)
  {
    if (signum == SIGINT)
      {
        ACE_Reactor::instance ()->end_reactor_event_loop ();
      }
    return 0;
  }
};
 
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  // Listing 2 code/ch07
  TemperatureQueryHandler *temperatureMonitor =
    new TemperatureQueryHandler ();
  // Listing 2
 
  ACE_Time_Value initialDelay (3);
  ACE_Time_Value intervalOne (5);
  // Listing 3 code/ch07
  TemperatureSensor *sensorOne =
    new TemperatureSensor ("Kitchen");
 
  ACE_Reactor::instance ()->schedule_timer (temperatureMonitor,
                                            sensorOne,
                                            initialDelay,
                                            intervalOne);
  // Listing 3
 
  ACE_Time_Value intervalTwo (4);
  // Listing 4 code/ch07
  TemperatureSensor *sensorTwo =
    new TemperatureSensor ("Foyer");
 
  ACE_Reactor::instance ()->schedule_timer (temperatureMonitor,
                                            sensorTwo,
                                            initialDelay,
                                            intervalTwo);
  // Listing 4
 
  SigintHandler *handleExit = new SigintHandler ();
 
  ACE_Reactor::instance ()->register_handler (SIGINT,
                                              handleExit);
 
  ACE_Reactor::instance ()->run_reactor_event_loop ();
 
  return 0;
}

Timers

// $Id: Timers.cpp 80826 2008-03-04 14:51:23Z wotte $
 
#include "ace/config-all.h"
#include "ace/OS_main.h"
 
#if !defined (ACE_LACKS_FORK)
 
#include "ace/streams.h"
#include "ace/OS_NS_unistd.h"
#include "ace/OS_NS_time.h"
#include "ace/OS_NS_signal.h"
 
typedef void (*timerTask_t)(void);
 
// Listing 1 code/ch07
pid_t timerTask (int initialDelay,
                 int interval,
                 timerTask_t task)
{
  if (initialDelay < 1 && interval < 1)
    return -1;
 
  pid_t pid = ACE_OS::fork ();
 
  if (pid < 0)
    return -1;
 
  if (pid > 0)
    return pid;
 
  if (initialDelay > 0)
    ACE_OS::sleep (initialDelay);
 
  if (interval < 1)
    return 0;
 
  while (1)
    {
      (*task) ();
      ACE_OS::sleep (interval);
    }
 
  ACE_NOTREACHED (return 0);
}
// Listing 1
 
// Listing 2 code/ch07
void foo ()
{
  time_t now = ACE_OS::time (0);
  cerr << "The time is " << ACE_OS::ctime (&now) << endl;
}
// Listing 2
 
void programMainLoop (void)
{
  ACE_OS::sleep (30);
}
 
// Listing 3 code/ch07
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  pid_t timerId = timerTask (3, 5, foo);
  programMainLoop ();
  ACE_OS::kill (timerId, SIGINT);
  return 0;
}
// Listing 3
 
#else
#include "ace/OS_NS_stdio.h"
 
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  //FUZZ: disable check_for_lack_ACE_OS
  ACE_OS::puts ("This very unportable example requires fork().\n");
  //FUZZ: enable check_for_lack_ACE_OS
 
  return 0;
}
 
#endif /* ACE_LACKS_FORK */