Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

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 Methods

 ACE_Service_Manager (void)
 Constructor. More...

 ~ACE_Service_Manager (void)
 Destructor. More...


Protected Methods

virtual int reconfigure_services (void)
 Trigger a reconfiguration of the Service Configurator by. More...

virtual int list_services (void)
 Determine all the services offered by this daemon and return the information back to the client. More...

virtual int init (int argc, ACE_TCHAR *argv[])
 Initializes object when dynamic linking occurs. More...

virtual int info (ACE_TCHAR **info_string, size_t length) const
 Returns information on a service object. More...

virtual int fini (void)
 Terminates object when dynamic unlinking occurs. More...

virtual int suspend (void)
 Temporarily disable a service without removing it completely. More...

virtual int resume (void)
 Re-enable a previously suspended service. More...

void dump (void) const
 Dump the state of an object. More...


Protected Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks. More...


Private Methods

int open (const ACE_INET_Addr &sia)
virtual ACE_HANDLE get_handle (void) const
 Get the I/O handle. More...

virtual int handle_input (ACE_HANDLE fd)
 Called when input events occur (e.g., connection or data). More...

virtual int handle_close (ACE_HANDLE fd, ACE_Reactor_Mask)
 Called when a <handle_*()> method returns -1 or when the <remove_handler> method is called on an <ACE_Reactor>. The <close_mask> indicates which event has triggered the <handle_close> method callback on a particular <handle>. More...

virtual int handle_signal (int signum, siginfo_t *, ucontext_t *)
 Called when object is signaled by OS (either via UNIX signals or when a Win32 object becomes signaled). More...

virtual void process_request (ACE_TCHAR *request)
 Handle one request. More...


Private Attributes

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

ACE_SOCK_Acceptor acceptor_
 Acceptor instance. More...

int debug_
 Keep track of the debugging level. More...

int signum_
 The signal used to trigger reconfiguration. More...


Static Private Attributes

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


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: + List services: If the string "help" is sent, return a list of all the services supported by the Service Configurator. + Reconfigure: If the string "reconfigure" is sent trigger a reconfiguration, which will re-read the local <svc.conf> file. + Process directive: If neither "help" nor "reconfigure" is sent, simply treat the incoming string as a process directive and pass it along to <ACE_Service_Config::process_directive>. This allows remote configuration via command-line instructions like % echo suspend My_Remote_Service | telnet hostname 3911

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 50 of file Service_Manager.h.


Constructor & Destructor Documentation

ACE_Service_Manager::ACE_Service_Manager void   
 

Constructor.

Definition at line 30 of file Service_Manager.cpp.

References ACE_TRACE, and SIGHUP.

00031   : debug_ (0),
00032     signum_ (SIGHUP)
00033 {
00034   ACE_TRACE ("ACE_Service_Manager::ACE_Service_Manager");
00035 }

ACE_INLINE ACE_Service_Manager::~ACE_Service_Manager void   
 

Destructor.

Definition at line 7 of file Service_Manager.i.

References ACE_TRACE.

00008 {
00009   ACE_TRACE ("ACE_Service_Manager::~ACE_Service_Manager");
00010 }


Member Function Documentation

void ACE_Service_Manager::dump void    const [protected]
 

Dump the state of an object.

Definition at line 21 of file Service_Manager.cpp.

References ACE_TRACE.

00022 {
00023   ACE_TRACE ("ACE_Service_Manager::dump");
00024 }

int ACE_Service_Manager::fini void    [protected, virtual]
 

Terminates object when dynamic unlinking occurs.

Reimplemented from ACE_Shared_Object.

Definition at line 129 of file Service_Manager.cpp.

References ACE_Event_Handler::ACCEPT_MASK, ACE_TRACE, ACE_Event_Handler::DONT_CALL, get_handle, handle_close, ACE_Reactor::instance, ACE_Event_Handler::NULL_MASK, and ACE_Reactor::remove_handler.

00130 {
00131   ACE_TRACE ("ACE_Service_Manager::fini");
00132 
00133   int retv = 0;
00134   if (this->get_handle () != ACE_INVALID_HANDLE)
00135     {
00136       retv = ACE_Reactor::instance ()->remove_handler
00137         (this,
00138          ACE_Event_Handler::ACCEPT_MASK |
00139          ACE_Event_Handler::DONT_CALL);
00140       this->handle_close (ACE_INVALID_HANDLE,
00141                           ACE_Event_Handler::NULL_MASK);
00142     }
00143   return retv;
00144 }

ACE_HANDLE ACE_Service_Manager::get_handle void    const [private, virtual]
 

Get the I/O handle.

Reimplemented from ACE_Event_Handler.

Definition at line 147 of file Service_Manager.cpp.

References acceptor_, ACE_TRACE, and ACE_IPC_SAP::get_handle.

Referenced by fini, and init.

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

int ACE_Service_Manager::handle_close ACE_HANDLE    fd,
ACE_Reactor_Mask   
[private, virtual]
 

Called when a <handle_*()> method returns -1 or when the <remove_handler> method is called on an <ACE_Reactor>. The <close_mask> indicates which event has triggered the <handle_close> method callback on a particular <handle>.

Reimplemented from ACE_Event_Handler.

Definition at line 122 of file Service_Manager.cpp.

References acceptor_, ACE_Reactor_Mask, ACE_TRACE, and ACE_SOCK_Acceptor::close.

Referenced by fini.

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

int ACE_Service_Manager::handle_input ACE_HANDLE    fd [private, virtual]
 

Called when input events occur (e.g., connection or data).

Reimplemented from ACE_Event_Handler.

Definition at line 263 of file Service_Manager.cpp.

References ACE_SOCK_Acceptor::accept, acceptor_, ACE_DEBUG, ACE_LIB_TEXT, ACE_TCHAR, ACE_TRACE, client_stream_, ACE_SOCK_Stream::close, debug_, EWOULDBLOCK, ACE_INET_Addr::get_host_name, ACE_INET_Addr::get_port_number, ACE_SOCK::get_remote_addr, ACE_Reactor::instance, LM_DEBUG, LM_ERROR, process_request, ACE_SOCK_IO::recv, ACE_Reactor::register_handler, SIGPIPE, ssize_t, ACE_OS_String::strchr, and ACE_Reactor::uses_event_associations.

00264 {
00265   ACE_TRACE ("ACE_Service_Manager::handle_input");
00266 
00267   // Try to find out if the implementation of the reactor that we are
00268   // using requires us to reset the event association for the newly
00269   // created handle. This is because the newly created handle will
00270   // inherit the properties of the listen handle, including its event
00271   // associations.
00272   int reset_new_handle =
00273     ACE_Reactor::instance ()->uses_event_associations ();
00274 
00275   if (this->acceptor_.accept (this->client_stream_, // stream
00276                               0, // remote address
00277                               0, // timeout
00278                               1, // restart
00279                               reset_new_handle  // reset new handler
00280                               ) == -1)
00281     return -1;
00282 
00283   if (this->debug_)
00284     {
00285       ACE_DEBUG ((LM_DEBUG,
00286                   ACE_LIB_TEXT ("client_stream fd = %d\n"),
00287                  this->client_stream_.get_handle ()));
00288       ACE_INET_Addr sa;
00289       if (this->client_stream_.get_remote_addr (sa) == -1)
00290         return -1;
00291 
00292       ACE_DEBUG ((LM_DEBUG,
00293                   ACE_LIB_TEXT ("accepted from host %s at port %d\n"),
00294                   sa.get_host_name (),
00295                   sa.get_port_number ()));
00296     }
00297 
00298   ACE_TCHAR request[BUFSIZ];
00299   ACE_TCHAR* offset = request;
00300   ssize_t remaining = sizeof (request);
00301 
00302   // Read service request from client.
00303 
00304   ssize_t result;
00305 
00306   // Keep looping until we actually get the request.  Note that Win32
00307   // sets the socket into non-blocking mode, so we may need to loop if
00308   // the system is heavily loaded.  Read bytes into the buffer until a
00309   // '\n' or '\r' is found in the buffer, otherwise the buffer
00310   // contains an incomplete string.
00311 
00312   int error;
00313   do
00314     {
00315       result = client_stream_.recv (offset, remaining);
00316       error = errno;
00317       if (result == 0 && error != EWOULDBLOCK) 
00318         remaining = 0;
00319 
00320       if (result >= 0)
00321         {
00322           if ((remaining -= result) <= 0)
00323             {
00324               ACE_DEBUG ((LM_ERROR,
00325                           ACE_LIB_TEXT ("Request buffer overflow.\n")));
00326               result = 0;
00327               break;
00328             }
00329 
00330           offset += result;
00331           *offset = 0;
00332 
00333           if (ACE_OS::strchr (request, '\r') != 0
00334               || ACE_OS::strchr (request, '\n') != 0)
00335             remaining = 0;
00336         }
00337     }
00338   while (result == -1 && error == EWOULDBLOCK || remaining > 0);
00339 
00340   switch (result)
00341     {
00342     case -1:
00343       if (this->debug_)
00344         ACE_DEBUG ((LM_ERROR,
00345                     ACE_LIB_TEXT ("%p\n"),
00346                     ACE_LIB_TEXT ("recv")));
00347       break;
00348     case 0:
00349       return 0;
00350       /* NOTREACHED */
00351     default:
00352       {
00353         ACE_Event_Handler *old_signal_handler = 0;
00354         ACE_Reactor::instance ()->register_handler (SIGPIPE,
00355                                                     this,
00356                                                     0,
00357                                                     &old_signal_handler);
00358 
00359         this->process_request (request);
00360 
00361         // Restore existing SIGPIPE handler
00362         ACE_Reactor::instance ()->register_handler (SIGPIPE,
00363                                                     old_signal_handler);
00364       }
00365     }
00366 
00367   if (this->client_stream_.close () == -1 && this->debug_)
00368     ACE_DEBUG ((LM_ERROR,
00369                 ACE_LIB_TEXT ("%p\n"),
00370                 ACE_LIB_TEXT ("close")));
00371   return 0;
00372 }

int ACE_Service_Manager::handle_signal int    signum,
siginfo_t  ,
ucontext_t  
[private, virtual]
 

Called when object is signaled by OS (either via UNIX signals or when a Win32 object becomes signaled).

Reimplemented from ACE_Event_Handler.

Definition at line 154 of file Service_Manager.cpp.

References ucontext_t.

00155 {
00156   return 0;
00157 }

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 63 of file Service_Manager.cpp.

References acceptor_, ACE_LIB_TEXT, ACE_TCHAR, ACE_TRACE, ACE_SOCK::get_local_addr, ACE_INET_Addr::get_port_number, ACE_OS::sprintf, ACE_OS_String::strdup, ACE_OS_String::strlen, and ACE_OS_String::strsncpy.

00064 {
00065   ACE_TRACE ("ACE_Service_Manager::info");
00066   ACE_INET_Addr sa;
00067   ACE_TCHAR buf[BUFSIZ];
00068 
00069   if (this->acceptor_.get_local_addr (sa) == -1)
00070     return -1;
00071 
00072   ACE_OS::sprintf (buf,
00073                    ACE_LIB_TEXT ("%d/%s %s"),
00074                    sa.get_port_number (),
00075                    ACE_LIB_TEXT ("tcp"),
00076                    ACE_LIB_TEXT ("# lists all services in the daemon\n"));
00077   if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
00078     return -1;
00079   else
00080     ACE_OS::strsncpy (*strp, buf, length);
00081   return ACE_static_cast (int, ACE_OS_String::strlen (buf));
00082 }

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 85 of file Service_Manager.cpp.

References ACE_Event_Handler::ACCEPT_MASK, ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_TCHAR, ACE_TRACE, ACE_OS::atoi, debug_, DEFAULT_PORT_, get_handle, ACE_Reactor::instance, LM_ERROR, open, ACE_Get_Opt::opt_arg, ACE_Reactor::register_handler, ACE_INET_Addr::set, and signum_.

00086 {
00087   ACE_TRACE ("ACE_Service_Manager::init");
00088   ACE_INET_Addr local_addr (ACE_Service_Manager::DEFAULT_PORT_);
00089   ACE_Get_Opt getopt (argc, argv, ACE_LIB_TEXT ("dp:s:"), 0); // Start at argv[0]
00090 
00091   for (int c; (c = getopt ()) != -1; )
00092      switch (c)
00093        {
00094        case 'd':
00095          this->debug_ = 1;
00096          break;
00097        case 'p':
00098          local_addr.set ((u_short) ACE_OS::atoi (getopt.opt_arg ()));
00099          break;
00100        case 's':
00101          this->signum_ = ACE_OS::atoi (getopt.opt_arg ());
00102          break;
00103        default:
00104          break;
00105        }
00106 
00107   if (this->get_handle () == ACE_INVALID_HANDLE &&
00108       this->open (local_addr) == -1)
00109     ACE_ERROR_RETURN ((LM_ERROR,
00110                        ACE_LIB_TEXT ("%p\n"),
00111                        ACE_LIB_TEXT ("open")), -1);
00112   else if (ACE_Reactor::instance ()->register_handler
00113            (this,
00114             ACE_Event_Handler::ACCEPT_MASK) == -1)
00115     ACE_ERROR_RETURN ((LM_ERROR,
00116                        ACE_LIB_TEXT ("registering service with ACE_Reactor\n")),
00117                       -1);
00118   return 0;
00119 }

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 163 of file Service_Manager.cpp.

References ACE_DEBUG, ACE_ERROR, ACE_LIB_TEXT, ACE_TCHAR, ACE_TRACE, ACE_Service_Type::active, ACE_Service_Repository_Iterator::advance, client_stream_, debug_, ACE_Service_Type_Impl::info, ACE_Service_Repository::instance, LM_DEBUG, LM_ERROR, ACE_Service_Type::name, ACE_Service_Repository_Iterator::next, ACE_SOCK_Stream::send_n, ssize_t, ACE_OS_String::strcat, ACE_OS_String::strcpy, ACE_OS_String::strlen, and ACE_Service_Type::type.

Referenced by process_request.

00164 {
00165   ACE_TRACE ("ACE_Service_Manager::list_services");
00166   ACE_Service_Repository_Iterator sri (*ACE_Service_Repository::instance (), 0);
00167 
00168   for (const ACE_Service_Type *sr;
00169        sri.next (sr) != 0;
00170        sri.advance ())
00171     {
00172       size_t len = ACE_OS_String::strlen (sr->name ()) + 11;
00173       ACE_TCHAR buf[BUFSIZ];
00174       ACE_TCHAR *p = buf + len;
00175 
00176       ACE_OS::strcpy (buf, sr->name ());
00177       ACE_OS::strcat (buf, (sr->active ()) ?
00178                       ACE_LIB_TEXT (" (active) ") :
00179                       ACE_LIB_TEXT (" (paused) "));
00180 
00181       p[-1] = ' ';
00182       p[0]  = '\0';
00183 
00184       len += sr->type ()->info (&p, sizeof buf - len);
00185 
00186       if (this->debug_)
00187         ACE_DEBUG ((LM_DEBUG,
00188                     ACE_LIB_TEXT ("len = %d, info = %s%s"),
00189                     len,
00190                     buf,
00191                     buf[len - 1] == '\n' ? ACE_LIB_TEXT ("") : ACE_LIB_TEXT ("\n")));
00192 
00193       if (len > 0)
00194         {
00195           ssize_t n = this->client_stream_.send_n (buf, len);
00196           if (n <= 0 && errno != EPIPE)
00197             ACE_ERROR ((LM_ERROR,
00198                         ACE_LIB_TEXT ("%p\n"),
00199                         ACE_LIB_TEXT ("send_n")));
00200         }
00201     }
00202 
00203   return 0;
00204 }

int ACE_Service_Manager::open const ACE_INET_Addr   sia [private]
 

Definition at line 52 of file Service_Manager.cpp.

References acceptor_, ACE_TRACE, and ACE_SOCK_Acceptor::open.

Referenced by init.

00053 {
00054   ACE_TRACE ("ACE_Service_Manager::open");
00055 
00056   // Reuse the listening address, even if it's already in use!
00057   if (this->acceptor_.open (sia, 1) == -1)
00058     return -1;
00059   return 0;
00060 }

void ACE_Service_Manager::process_request ACE_TCHAR   request [private, virtual]
 

Handle one request.

Definition at line 232 of file Service_Manager.cpp.

References ACE_LIB_TEXT, ACE_TCHAR, ACE_TRACE, list_services, ACE_Service_Config::process_directive, reconfigure_services, and ACE_OS_String::strcmp.

Referenced by handle_input.

00233 {
00234   ACE_TRACE("ACE_Service_Manager::process_request");
00235   ACE_TCHAR *p;
00236 
00237   // Kill trailing newlines.
00238   for (p = request;
00239        (*p != '\0') && (*p != '\r') && (*p != '\n');
00240        p++)
00241     continue;
00242 
00243   *p = '\0';
00244 
00245   if (ACE_OS::strcmp (request, ACE_LIB_TEXT ("help")) == 0)
00246     // Return a list of the configured services.
00247     this->list_services ();
00248   else if (ACE_OS::strcmp (request, ACE_LIB_TEXT ("reconfigure") )== 0)
00249     // Trigger a reconfiguration by re-reading the local <svc.conf> file.
00250     this->reconfigure_services ();
00251   else
00252     // Just process a single request passed in via the socket
00253     // remotely.
00254     ACE_Service_Config::process_directive (request);
00255 
00256   // Additional management services may be handled here...
00257 }

int ACE_Service_Manager::reconfigure_services void    [protected, virtual]
 

Trigger a reconfiguration of the Service Configurator by.

Definition at line 210 of file Service_Manager.cpp.

References ACE_TRACE, client_stream_, ACE_Service_Config::reconfig_occurred, ACE_SOCK_Stream::send_n, and sig_atomic_t.

Referenced by process_request.

00211 {
00212   ACE_TRACE ("ACE_Service_Manager::reconfigure_services");
00213 
00214 #if 0
00215 // Send ourselves a signal!  ACE_OS::kill (ACE_OS::getpid (),
00216 // this->signum_);
00217 #endif /* 0 */
00218 
00219   // Flag the main event loop that a reconfiguration should occur.
00220   // The next trip through the <ACE_Reactor::run_event_loop> should
00221   // pick this up and cause a reconfiguration.  Note that we can't
00222   // trigger the reconfiguration automatically since that might "pull
00223   // the rug" out from underneath the existing services in a
00224   // problematic way.
00225   ACE_Service_Config::reconfig_occurred ((sig_atomic_t) 1);
00226   return this->client_stream_.send_n ("done\n",
00227                                       sizeof ("done\n"));
00228 }

int ACE_Service_Manager::resume void    [protected, virtual]
 

Re-enable a previously suspended service.

Reimplemented from ACE_Service_Object.

Definition at line 45 of file Service_Manager.cpp.

References ACE_TRACE, ACE_Reactor::instance, and ACE_Reactor::resume_handler.

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

int ACE_Service_Manager::suspend void    [protected, virtual]
 

Temporarily disable a service without removing it completely.

Reimplemented from ACE_Service_Object.

Definition at line 38 of file Service_Manager.cpp.

References ACE_TRACE, ACE_Reactor::instance, and ACE_Reactor::suspend_handler.

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


Member Data Documentation

ACE_SOCK_Acceptor ACE_Service_Manager::acceptor_ [private]
 

Acceptor instance.

Definition at line 103 of file Service_Manager.h.

Referenced by get_handle, handle_close, handle_input, info, and open.

ACE_Service_Manager::ACE_ALLOC_HOOK_DECLARE [protected]
 

Declare the dynamic allocation hooks.

Definition at line 84 of file Service_Manager.h.

ACE_SOCK_Stream ACE_Service_Manager::client_stream_ [private]
 

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

Definition at line 100 of file Service_Manager.h.

Referenced by handle_input, list_services, and reconfigure_services.

int ACE_Service_Manager::debug_ [private]
 

Keep track of the debugging level.

Definition at line 106 of file Service_Manager.h.

Referenced by handle_input, init, and list_services.

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

Default port for the Acceptor to listen on.

Definition at line 28 of file Service_Manager.cpp.

Referenced by init.

int ACE_Service_Manager::signum_ [private]
 

The signal used to trigger reconfiguration.

Definition at line 109 of file Service_Manager.h.

Referenced by init.


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 12:55:55 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002