Sophie

Sophie

distrib > Mandriva > 10.0-com > i586 > by-pkgid > 21280410b6ea906d791d7a12afae2579 > files > 947

libace5-doc-5.4-2mdk.i586.rpm

// Connection_Handler.cpp,v 4.21 2003/11/05 02:04:53 dhinton Exp

// ============================================================================
//
// = FILENAME
//    Connection_Handler.cpp
//
// = DESCRIPTION
//      This test illustrates how to use the Acceptor pattern to
//      create multiple threads, each running its own Reactor.  You
//      can connect to this via telnet and keep typing until you enter
//      '^D'.
//
// = AUTHOR
//    Doug Schmidt
//
// ============================================================================

#include "ace/Acceptor.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/Service_Config.h"
#include "ace/Thread.h"
#include "ace/Signal.h"

#include "Connection_Handler.h"

ACE_RCSID(misc, Connection_Handler, "Connection_Handler.cpp,v 4.21 2003/11/05 02:04:53 dhinton Exp")

int
Connection_Handler::open (void *)
{
  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) in open()\n"));

  // Make ourselves an Active Object.
  return this->activate (THR_NEW_LWP | THR_DETACHED);
}

int
Connection_Handler::close (u_long)
{
  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) in close()\n"));

  // Shut ourself down.  Note that this doesn't destroy the thread,
  // just the state of the object.
  this->destroy ();
  return 0;
}

int
Connection_Handler::svc (void)
{
  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) in svc()\n"));

  this->finished_ = 0;

  // Create our own personal Reactor just for this thread.  Note that
  // we create this on the stack of the thread since it's only used
  // for the duration of this connection!

  ACE_Reactor reactor;

  // Each <ACE_Svc_Handler> has its own <ACE_Reactor *>.  By default,
  // this points to the <Acceptor's> Reactor.  However, we can point
  // it to our local Reactor, which is what we do in this case.
  this->reactor (&reactor);

  // Register ourselves to handle input in this thread without
  // blocking.
  if (this->reactor ()->register_handler
      (this, ACE_Event_Handler::READ_MASK) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "can' (%P|%t) t register with reactor\n"),
                      -1);
  // Schedule a timer.
  else if (this->reactor ()->schedule_timer (this,
                                             (const void *) this,
                                             ACE_Time_Value (2),
                                             ACE_Time_Value (2)) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "(%P|%t) can't register with reactor\n"),
                      -1);
  else
    ACE_DEBUG ((LM_DEBUG,
                "(%P|%t) connected with client\n"));

  // Keep looping until we receive SIGQUIT or the client shutsdown.

  while (this->finished_ == 0)
    {
      ACE_DEBUG ((LM_DEBUG,
                  "(%P|%t) handling events\n"));
      this->reactor ()->handle_events ();
    }

  // Cancel all pending timeouts.
  this->reactor ()->cancel_timer (this);

  // Remove ourselves from the Reactor.
  this->reactor ()->remove_handler
    (this, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL);

  // Zero-out the Reactor field so it isn't accessed later on.
  this->reactor (0);

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) exiting svc\n"));
  return 0;
}

int
Connection_Handler::handle_close (ACE_HANDLE,
                                  ACE_Reactor_Mask)
{
  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) in handle_close \n"));

  // Signal the svc() event loop to shut down.
  this->finished_ = 1;
  return 0;
}

int
Connection_Handler::handle_input (ACE_HANDLE)
{
  char buf[BUFSIZ];

  ACE_DEBUG ((LM_DEBUG, "(%P|%t) handle_input\n"));

  switch (this->peer ().recv (buf, sizeof buf))
    {
    case -1:
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%P|%t) %p bad read\n",
                         "client logger"),
                        -1);
    case 0:
      ACE_ERROR_RETURN ((LM_ERROR,
                         "(%P|%t) closing log daemon (fd = %d)\n",
                         this->get_handle ()),
                        -1);
    default:
      if (buf[0] == (char) EOF)
        ACE_ERROR_RETURN ((LM_ERROR,
                           "(%P|%t) closing log daemon (fd = %d)\n",
                           this->get_handle ()),
                          -1);
      else
        ACE_DEBUG ((LM_DEBUG,
                    "(%P|%t) from client: %s",
                    buf));
    }

  return 0;
}

int
Connection_Handler::handle_signal (int signum,
                                   siginfo_t *,
                                   ucontext_t *)
{
  // @@ Note that this code is not portable to all OS platforms since
  // it uses print statements within signal handler context.

  ACE_DEBUG ((LM_DEBUG,
              "received signal %S\n",
              signum));

  this->finished_ = 1;
  return 0;
}

int
Connection_Handler::handle_timeout (const ACE_Time_Value &tv,
                                    const void *arg)
{
  ACE_UNUSED_ARG (tv);
#if defined (ACE_NDEBUG)
  ACE_UNUSED_ARG (arg);
#endif /* ACE_NDEBUG */

  ACE_ASSERT (arg == this);
  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) handling timeout from this = %u\n",
              this));
  return 0;
}

// Define an Acceptor for the <Connection_Handler>.

typedef ACE_Acceptor <Connection_Handler, ACE_SOCK_ACCEPTOR>
        Connection_Acceptor;

int
main (int argc, char *argv[])
{
  ACE_Service_Config daemon (argv[0]);

  u_short port = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT;

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) in main\n"));

  // Acceptor factory.
  Connection_Acceptor peer_acceptor;

  // Create an adapter to end the event loop.
  ACE_Sig_Adapter sa ((ACE_Sig_Handler_Ex) ACE_Reactor::end_event_loop);

  // Register the signal handler adapter.
  if (ACE_Reactor::instance ()->register_handler (SIGINT, &sa) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "register_handler"),
                      -1);

  // Open the Acceptor.
  else if (peer_acceptor.open (ACE_INET_Addr (port),
                               ACE_Reactor::instance ()) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "open"),
                      -1);

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) starting up connection server\n"));

  // Perform connection service until we receive SIGINT.

  while (ACE_Reactor::event_loop_done() == 0)
    ACE_Reactor::run_event_loop ();

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) shutting down connection server\n"));
  return 0;
}

#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
template class ACE_Acceptor<Connection_Handler, ACE_SOCK_ACCEPTOR>;
template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#pragma instantiate ACE_Acceptor<Connection_Handler, ACE_SOCK_ACCEPTOR>
#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */