Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes

ACE_Service_Manager Class Reference

Provide a standard ACE service for managing all the services configured in an ACE_Service_Repository. More...

#include <Service_Manager.h>

Inheritance diagram for ACE_Service_Manager:
Inheritance graph
[legend]
Collaboration diagram for ACE_Service_Manager:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ACE_Service_Manager (void)
 Constructor.
virtual ~ACE_Service_Manager (void)
 Destructor.

Protected Member Functions

virtual int reconfigure_services (void)
virtual int list_services (void)
virtual int init (int argc, ACE_TCHAR *argv[])
 Initializes object when dynamic linking occurs.
virtual int info (ACE_TCHAR **info_string, size_t length) const
 Returns information on a service object.
virtual int fini (void)
 Terminates object when dynamic unlinking occurs.
virtual int suspend (void)
 Temporarily disable a service without removing it completely.
virtual int resume (void)
 Re-enable a previously suspended service.
void dump (void) const
 Dump the state of an object.
int open (const ACE_INET_Addr &sia)
virtual ACE_HANDLE get_handle (void) const
virtual int handle_input (ACE_HANDLE fd)
virtual int handle_close (ACE_HANDLE fd, ACE_Reactor_Mask)
virtual int handle_signal (int signum, siginfo_t *, ucontext_t *)
virtual void process_request (ACE_TCHAR *request)
 Handle one request.

Protected Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.
ACE_SOCK_Stream client_stream_
ACE_SOCK_Acceptor acceptor_
 Acceptor instance.
bool debug_
 Keep track whether we debug or not.
int signum_
 The signal used to trigger reconfiguration.

Static Protected Attributes

static u_short DEFAULT_PORT_ = 10000
 Default port for the Acceptor to listen on.

Detailed Description

Provide a standard ACE service for managing all the services configured in an ACE_Service_Repository.

This implementation is simple and just handles each client request one at a time. There are currently 3 types of requests:

Each request is associated with a new connection, which is closed when the request is processed. In addition, you must be using the singleton <ACE_Reactor::instance> in order to trigger reconfigurations.

Definition at line 52 of file Service_Manager.h.


Constructor & Destructor Documentation

ACE_Service_Manager::ACE_Service_Manager ( void   ) 

Constructor.

Definition at line 35 of file Service_Manager.cpp.

  : debug_ (false),
    signum_ (SIGHUP)
{
  ACE_TRACE ("ACE_Service_Manager::ACE_Service_Manager");
}

ACE_Service_Manager::~ACE_Service_Manager ( void   )  [virtual]

Destructor.

Definition at line 42 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::~ACE_Service_Manager");
}


Member Function Documentation

void ACE_Service_Manager::dump ( void   )  const [protected]

Dump the state of an object.

int ACE_Service_Manager::fini ( void   )  [protected, virtual]

Terminates object when dynamic unlinking occurs.

Reimplemented from ACE_Shared_Object.

Definition at line 158 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::fini");

  int retv = 0;

  if (this->get_handle () != ACE_INVALID_HANDLE)
    {
      retv =
        ACE_Reactor::instance ()->remove_handler (
          this,
          ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);

      this->handle_close (ACE_INVALID_HANDLE,
                          ACE_Event_Handler::NULL_MASK);
    }

  return retv;
}

ACE_HANDLE ACE_Service_Manager::get_handle ( void   )  const [protected, virtual]

Definition at line 179 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::get_handle");
  return this->acceptor_.get_handle ();
}

int ACE_Service_Manager::handle_close ( ACE_HANDLE  fd,
ACE_Reactor_Mask   
) [protected, virtual]

Definition at line 151 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::handle_close");
  return this->acceptor_.close ();
}

int ACE_Service_Manager::handle_input ( ACE_HANDLE  fd  )  [protected, virtual]

Definition at line 309 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::handle_input");

  // Try to find out if the implementation of the reactor that we are
  // using requires us to reset the event association for the newly
  // created handle. This is because the newly created handle will
  // inherit the properties of the listen handle, including its event
  // associations.
  bool reset_new_handle =
    ACE_Reactor::instance ()->uses_event_associations ();

  if (this->acceptor_.accept (this->client_stream_, // stream
                              0, // remote address
                              0, // timeout
                              1, // restart
                              reset_new_handle  // reset new handler
                              ) == -1)
    {
      return -1;
    }

  if (this->debug_)
    {
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("client_stream fd = %d\n"),
                 this->client_stream_.get_handle ()));
      ACE_INET_Addr sa;

      if (this->client_stream_.get_remote_addr (sa) == -1)
        {
          return -1;
        }

      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("accepted from host %C at port %d\n"),
                  sa.get_host_name (),
                  sa.get_port_number ()));
    }

  ACE_TCHAR request[BUFSIZ];
  ACE_TCHAR* offset = request;
  ssize_t remaining = sizeof (request);

  // Read service request from client.

  ssize_t result;

  // Keep looping until we actually get the request.  Note that Win32
  // sets the socket into non-blocking mode, so we may need to loop if
  // the system is heavily loaded.  Read bytes into the buffer until a
  // '\n' or '\r' is found in the buffer, otherwise the buffer
  // contains an incomplete string.

  int error;

  do
    {
      result = client_stream_.recv (offset, remaining);
      error = errno;

      if (result == 0 && error != EWOULDBLOCK)
        {
          remaining = 0;
        }

      if (result >= 0)
        {
          if ((remaining -= result) <= 0)
            {
              ACE_DEBUG ((LM_ERROR,
                          ACE_TEXT ("Request buffer overflow.\n")));
              result = 0;
              break;
            }

          offset += result;
          *offset = 0;

          if (ACE_OS::strchr (request, '\r') != 0
              || ACE_OS::strchr (request, '\n') != 0)
            {
              remaining = 0;
            }
        }
    }
  while ((result == -1 && error == EWOULDBLOCK) || remaining > 0);

  switch (result)
    {
    case -1:
      if (this->debug_)
        {
          ACE_DEBUG ((LM_ERROR,
                      ACE_TEXT ("%p\n"),
                      ACE_TEXT ("recv")));
        }

      break;
    case 0:
      return 0;
      /* NOTREACHED */
    default:
      {
        ACE_Event_Handler *old_signal_handler = 0;
        ACE_Reactor::instance ()->register_handler (SIGPIPE,
                                                    this,
                                                    0,
                                                    &old_signal_handler);

        this->process_request (request);

        // Restore existing SIGPIPE handler
        ACE_Reactor::instance ()->register_handler (SIGPIPE,
                                                    old_signal_handler);
      }
    }

  if (this->client_stream_.close () == -1 && this->debug_)
    {
      ACE_DEBUG ((LM_ERROR,
                  ACE_TEXT ("%p\n"),
                  ACE_TEXT ("close")));
    }

  return 0;
}

int ACE_Service_Manager::handle_signal ( int  signum,
siginfo_t ,
ucontext_t  
) [protected, virtual]

Definition at line 186 of file Service_Manager.cpp.

{
  return 0;
}

int ACE_Service_Manager::info ( ACE_TCHAR **  info_string,
size_t  length 
) const [protected, virtual]

Returns information on a service object.

Reimplemented from ACE_Shared_Object.

Definition at line 76 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::info");
  ACE_INET_Addr sa;
  ACE_TCHAR buf[BUFSIZ];

  if (this->acceptor_.get_local_addr (sa) == -1)
    {
      return -1;
    }

  ACE_OS::sprintf (buf,
                   ACE_TEXT ("%d/%s %s"),
                   sa.get_port_number (),
                   ACE_TEXT ("tcp"),
                   ACE_TEXT ("# lists all services in the daemon\n"));

  if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
    {
      return -1;
    }
  else
    {
      ACE_OS::strsncpy (*strp, buf, length);
    }

  return static_cast<int> (ACE_OS::strlen (buf));
}

int ACE_Service_Manager::init ( int  argc,
ACE_TCHAR argv[] 
) [protected, virtual]

Initializes object when dynamic linking occurs.

Reimplemented from ACE_Shared_Object.

Definition at line 106 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::init");
  ACE_INET_Addr local_addr (ACE_Service_Manager::DEFAULT_PORT_);

  //FUZZ: disable check_for_lack_ACE_OS
  ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("dp:s:"), 0); // Start at argv[0]

  for (int c; (c = getopt ()) != -1; )
  //FUZZ: enable check_for_lack_ACE_OS
     switch (c)
       {
       case 'd':
         this->debug_ = true;
         break;
       case 'p':
         local_addr.set ((u_short) ACE_OS::atoi (getopt.opt_arg ()));
         break;
       case 's':
         this->signum_ = ACE_OS::atoi (getopt.opt_arg ());
         break;
       default:
         break;
       }

  if (this->get_handle () == ACE_INVALID_HANDLE &&
      this->open (local_addr) == -1)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT ("%p\n"),
                         ACE_TEXT ("open")), -1);
    }
  else if (ACE_Reactor::instance ()->register_handler
           (this,
            ACE_Event_Handler::ACCEPT_MASK) == -1)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT ("registering service with ACE_Reactor\n")),
                        -1);
    }

  return 0;
}

int ACE_Service_Manager::list_services ( void   )  [protected, virtual]

Determine all the services offered by this daemon and return the information back to the client.

Definition at line 195 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::list_services");
  ACE_Service_Repository_Iterator sri (*ACE_Service_Repository::instance (), 0);

  for (const ACE_Service_Type *sr;
       sri.next (sr) != 0;
       sri.advance ())
    {
      ssize_t len = static_cast<ssize_t> (ACE_OS::strlen (sr->name ())) + 11;
      ACE_TCHAR buf[BUFSIZ];
      ACE_TCHAR *p = buf + len;

      ACE_OS::strcpy (buf, sr->name ());
      ACE_OS::strcat (buf, (sr->active ()) ?
                      ACE_TEXT (" (active) ") :
                      ACE_TEXT (" (paused) "));

      p[-1] = ' ';
      p[0]  = '\0';

      len += sr->type ()->info (&p, sizeof buf - len);

      if (this->debug_)
        {
          ACE_DEBUG ((LM_DEBUG,
                      ACE_TEXT ("len = %d, info = %s%s"),
                      len,
                      buf,
                      buf[len - 1] == '\n' ? ACE_TEXT ("") : ACE_TEXT ("\n")));
        }

      if (len > 0)
        {
          ssize_t n = this->client_stream_.send_n (buf, len);

          if (n <= 0 && errno != EPIPE)
            {
              ACE_ERROR ((LM_ERROR,
                          ACE_TEXT ("%p\n"),
                          ACE_TEXT ("send_n")));
            }
        }
    }

  return 0;
}

int ACE_Service_Manager::open ( const ACE_INET_Addr sia  )  [protected]

Definition at line 62 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::open");

  // Reuse the listening address, even if it's already in use!
  if (this->acceptor_.open (sia, 1) == -1)
    {
      return -1;
    }

  return 0;
}

void ACE_Service_Manager::process_request ( ACE_TCHAR request  )  [protected, virtual]

Handle one request.

Definition at line 269 of file Service_Manager.cpp.

{
  ACE_TRACE("ACE_Service_Manager::process_request");
  ACE_TCHAR *p;

  // Kill trailing newlines.
  for (p = request;
       (*p != '\0') && (*p != '\r') && (*p != '\n');
       p++)
    {
      continue;
    }

  *p = '\0';

  if (ACE_OS::strcmp (request, ACE_TEXT ("help")) == 0)
    {
      // Return a list of the configured services.
      this->list_services ();
    }
  else if (ACE_OS::strcmp (request, ACE_TEXT ("reconfigure") )== 0)
    {
      // Trigger a reconfiguration by re-reading the local <svc.conf> file.
      this->reconfigure_services ();
    }
  else
    {
      // Just process a single request passed in via the socket
      // remotely.
      ACE_Service_Config_Guard guard (ACE_Service_Config::global ());
      ACE_Service_Config::process_directive (request);
    }

  // Additional management services may be handled here...
}

int ACE_Service_Manager::reconfigure_services ( void   )  [protected, virtual]

Trigger a reconfiguration of the Service Configurator by re-reading its local <svc.conf> file.

Definition at line 247 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::reconfigure_services");

#if 0
// Send ourselves a signal!  ACE_OS::kill (ACE_OS::getpid (),
// this->signum_);
#endif /* 0 */

  // Flag the main event loop that a reconfiguration should occur.
  // The next trip through the <ACE_Reactor::run_event_loop> should
  // pick this up and cause a reconfiguration.  Note that we can't
  // trigger the reconfiguration automatically since that might "pull
  // the rug" out from underneath the existing services in a
  // problematic way.
  ACE_Service_Config::reconfig_occurred ((sig_atomic_t) 1);
  return static_cast<int> (this->client_stream_.send_n ("done\n",
                                                        sizeof ("done\n")));
}

int ACE_Service_Manager::resume ( void   )  [protected, virtual]

Re-enable a previously suspended service.

Reimplemented from ACE_Service_Object.

Definition at line 55 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::resume");
  return ACE_Reactor::instance ()->resume_handler (this);
}

int ACE_Service_Manager::suspend ( void   )  [protected, virtual]

Temporarily disable a service without removing it completely.

Reimplemented from ACE_Service_Object.

Definition at line 48 of file Service_Manager.cpp.

{
  ACE_TRACE ("ACE_Service_Manager::suspend");
  return ACE_Reactor::instance ()->suspend_handler (this);
}


Member Data Documentation

Acceptor instance.

Definition at line 105 of file Service_Manager.h.

Declare the dynamic allocation hooks.

Definition at line 86 of file Service_Manager.h.

Connection to the client (we only support one client connection at a time).

Definition at line 102 of file Service_Manager.h.

bool ACE_Service_Manager::debug_ [protected]

Keep track whether we debug or not.

Definition at line 108 of file Service_Manager.h.

u_short ACE_Service_Manager::DEFAULT_PORT_ = 10000 [static, protected]

Default port for the Acceptor to listen on.

Definition at line 114 of file Service_Manager.h.

The signal used to trigger reconfiguration.

Definition at line 111 of file Service_Manager.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines