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
 Get the I/O handle.
virtual int handle_input (ACE_HANDLE fd)
 Called when input events occur (e.g., connection or data).
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.

00036   : debug_ (false),
00037     signum_ (SIGHUP)
00038 {
00039   ACE_TRACE ("ACE_Service_Manager::ACE_Service_Manager");
00040 }

ACE_Service_Manager::~ACE_Service_Manager ( void   )  [virtual]

Destructor.

Definition at line 42 of file Service_Manager.cpp.

00043 {
00044   ACE_TRACE ("ACE_Service_Manager::~ACE_Service_Manager");
00045 }


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.

00159 {
00160   ACE_TRACE ("ACE_Service_Manager::fini");
00161 
00162   int retv = 0;
00163 
00164   if (this->get_handle () != ACE_INVALID_HANDLE)
00165     {
00166       retv =
00167         ACE_Reactor::instance ()->remove_handler (
00168           this,
00169           ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
00170 
00171       this->handle_close (ACE_INVALID_HANDLE,
00172                           ACE_Event_Handler::NULL_MASK);
00173     }
00174 
00175   return retv;
00176 }

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

Get the I/O handle.

Reimplemented from ACE_Event_Handler.

Definition at line 179 of file Service_Manager.cpp.

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

int ACE_Service_Manager::handle_close ( ACE_HANDLE  handle,
ACE_Reactor_Mask  close_mask 
) [protected, 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 151 of file Service_Manager.cpp.

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

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

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

Reimplemented from ACE_Event_Handler.

Definition at line 309 of file Service_Manager.cpp.

00310 {
00311   ACE_TRACE ("ACE_Service_Manager::handle_input");
00312 
00313   // Try to find out if the implementation of the reactor that we are
00314   // using requires us to reset the event association for the newly
00315   // created handle. This is because the newly created handle will
00316   // inherit the properties of the listen handle, including its event
00317   // associations.
00318   bool reset_new_handle =
00319     ACE_Reactor::instance ()->uses_event_associations ();
00320 
00321   if (this->acceptor_.accept (this->client_stream_, // stream
00322                               0, // remote address
00323                               0, // timeout
00324                               1, // restart
00325                               reset_new_handle  // reset new handler
00326                               ) == -1)
00327     {
00328       return -1;
00329     }
00330 
00331   if (this->debug_)
00332     {
00333       ACE_DEBUG ((LM_DEBUG,
00334                   ACE_TEXT ("client_stream fd = %d\n"),
00335                  this->client_stream_.get_handle ()));
00336       ACE_INET_Addr sa;
00337 
00338       if (this->client_stream_.get_remote_addr (sa) == -1)
00339         {
00340           return -1;
00341         }
00342 
00343       ACE_DEBUG ((LM_DEBUG,
00344                   ACE_TEXT ("accepted from host %C at port %d\n"),
00345                   sa.get_host_name (),
00346                   sa.get_port_number ()));
00347     }
00348 
00349   ACE_TCHAR request[BUFSIZ];
00350   ACE_TCHAR* offset = request;
00351   ssize_t remaining = sizeof (request);
00352 
00353   // Read service request from client.
00354 
00355   ssize_t result;
00356 
00357   // Keep looping until we actually get the request.  Note that Win32
00358   // sets the socket into non-blocking mode, so we may need to loop if
00359   // the system is heavily loaded.  Read bytes into the buffer until a
00360   // '\n' or '\r' is found in the buffer, otherwise the buffer
00361   // contains an incomplete string.
00362 
00363   int error;
00364 
00365   do
00366     {
00367       result = client_stream_.recv (offset, remaining);
00368       error = errno;
00369 
00370       if (result == 0 && error != EWOULDBLOCK)
00371         {
00372           remaining = 0;
00373         }
00374 
00375       if (result >= 0)
00376         {
00377           if ((remaining -= result) <= 0)
00378             {
00379               ACE_DEBUG ((LM_ERROR,
00380                           ACE_TEXT ("Request buffer overflow.\n")));
00381               result = 0;
00382               break;
00383             }
00384 
00385           offset += result;
00386           *offset = 0;
00387 
00388           if (ACE_OS::strchr (request, '\r') != 0
00389               || ACE_OS::strchr (request, '\n') != 0)
00390             {
00391               remaining = 0;
00392             }
00393         }
00394     }
00395   while ((result == -1 && error == EWOULDBLOCK) || remaining > 0);
00396 
00397   switch (result)
00398     {
00399     case -1:
00400       if (this->debug_)
00401         {
00402           ACE_DEBUG ((LM_ERROR,
00403                       ACE_TEXT ("%p\n"),
00404                       ACE_TEXT ("recv")));
00405         }
00406 
00407       break;
00408     case 0:
00409       return 0;
00410       /* NOTREACHED */
00411     default:
00412       {
00413         ACE_Event_Handler *old_signal_handler = 0;
00414         ACE_Reactor::instance ()->register_handler (SIGPIPE,
00415                                                     this,
00416                                                     0,
00417                                                     &old_signal_handler);
00418 
00419         this->process_request (request);
00420 
00421         // Restore existing SIGPIPE handler
00422         ACE_Reactor::instance ()->register_handler (SIGPIPE,
00423                                                     old_signal_handler);
00424       }
00425     }
00426 
00427   if (this->client_stream_.close () == -1 && this->debug_)
00428     {
00429       ACE_DEBUG ((LM_ERROR,
00430                   ACE_TEXT ("%p\n"),
00431                   ACE_TEXT ("close")));
00432     }
00433 
00434   return 0;
00435 }

int ACE_Service_Manager::handle_signal ( int  signum,
siginfo_t ,
ucontext_t  
) [protected, 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 186 of file Service_Manager.cpp.

00187 {
00188   return 0;
00189 }

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.

00077 {
00078   ACE_TRACE ("ACE_Service_Manager::info");
00079   ACE_INET_Addr sa;
00080   ACE_TCHAR buf[BUFSIZ];
00081 
00082   if (this->acceptor_.get_local_addr (sa) == -1)
00083     {
00084       return -1;
00085     }
00086 
00087   ACE_OS::sprintf (buf,
00088                    ACE_TEXT ("%d/%s %s"),
00089                    sa.get_port_number (),
00090                    ACE_TEXT ("tcp"),
00091                    ACE_TEXT ("# lists all services in the daemon\n"));
00092 
00093   if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
00094     {
00095       return -1;
00096     }
00097   else
00098     {
00099       ACE_OS::strsncpy (*strp, buf, length);
00100     }
00101 
00102   return static_cast<int> (ACE_OS::strlen (buf));
00103 }

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.

00107 {
00108   ACE_TRACE ("ACE_Service_Manager::init");
00109   ACE_INET_Addr local_addr (ACE_Service_Manager::DEFAULT_PORT_);
00110 
00111   //FUZZ: disable check_for_lack_ACE_OS
00112   ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("dp:s:"), 0); // Start at argv[0]
00113 
00114   for (int c; (c = getopt ()) != -1; )
00115   //FUZZ: enable check_for_lack_ACE_OS
00116      switch (c)
00117        {
00118        case 'd':
00119          this->debug_ = true;
00120          break;
00121        case 'p':
00122          local_addr.set ((u_short) ACE_OS::atoi (getopt.opt_arg ()));
00123          break;
00124        case 's':
00125          this->signum_ = ACE_OS::atoi (getopt.opt_arg ());
00126          break;
00127        default:
00128          break;
00129        }
00130 
00131   if (this->get_handle () == ACE_INVALID_HANDLE &&
00132       this->open (local_addr) == -1)
00133     {
00134       ACE_ERROR_RETURN ((LM_ERROR,
00135                          ACE_TEXT ("%p\n"),
00136                          ACE_TEXT ("open")), -1);
00137     }
00138   else if (ACE_Reactor::instance ()->register_handler
00139            (this,
00140             ACE_Event_Handler::ACCEPT_MASK) == -1)
00141     {
00142       ACE_ERROR_RETURN ((LM_ERROR,
00143                          ACE_TEXT ("registering service with ACE_Reactor\n")),
00144                         -1);
00145     }
00146 
00147   return 0;
00148 }

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.

00196 {
00197   ACE_TRACE ("ACE_Service_Manager::list_services");
00198   ACE_Service_Repository_Iterator sri (*ACE_Service_Repository::instance (), 0);
00199 
00200   for (const ACE_Service_Type *sr;
00201        sri.next (sr) != 0;
00202        sri.advance ())
00203     {
00204       ssize_t len = static_cast<ssize_t> (ACE_OS::strlen (sr->name ())) + 11;
00205       ACE_TCHAR buf[BUFSIZ];
00206       ACE_TCHAR *p = buf + len;
00207 
00208       ACE_OS::strcpy (buf, sr->name ());
00209       ACE_OS::strcat (buf, (sr->active ()) ?
00210                       ACE_TEXT (" (active) ") :
00211                       ACE_TEXT (" (paused) "));
00212 
00213       p[-1] = ' ';
00214       p[0]  = '\0';
00215 
00216       len += sr->type ()->info (&p, sizeof buf - len);
00217 
00218       if (this->debug_)
00219         {
00220           ACE_DEBUG ((LM_DEBUG,
00221                       ACE_TEXT ("len = %d, info = %s%s"),
00222                       len,
00223                       buf,
00224                       buf[len - 1] == '\n' ? ACE_TEXT ("") : ACE_TEXT ("\n")));
00225         }
00226 
00227       if (len > 0)
00228         {
00229           ssize_t n = this->client_stream_.send_n (buf, len);
00230 
00231           if (n <= 0 && errno != EPIPE)
00232             {
00233               ACE_ERROR ((LM_ERROR,
00234                           ACE_TEXT ("%p\n"),
00235                           ACE_TEXT ("send_n")));
00236             }
00237         }
00238     }
00239 
00240   return 0;
00241 }

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

Definition at line 62 of file Service_Manager.cpp.

00063 {
00064   ACE_TRACE ("ACE_Service_Manager::open");
00065 
00066   // Reuse the listening address, even if it's already in use!
00067   if (this->acceptor_.open (sia, 1) == -1)
00068     {
00069       return -1;
00070     }
00071 
00072   return 0;
00073 }

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

Handle one request.

Definition at line 269 of file Service_Manager.cpp.

00270 {
00271   ACE_TRACE("ACE_Service_Manager::process_request");
00272   ACE_TCHAR *p;
00273 
00274   // Kill trailing newlines.
00275   for (p = request;
00276        (*p != '\0') && (*p != '\r') && (*p != '\n');
00277        p++)
00278     {
00279       continue;
00280     }
00281 
00282   *p = '\0';
00283 
00284   if (ACE_OS::strcmp (request, ACE_TEXT ("help")) == 0)
00285     {
00286       // Return a list of the configured services.
00287       this->list_services ();
00288     }
00289   else if (ACE_OS::strcmp (request, ACE_TEXT ("reconfigure") )== 0)
00290     {
00291       // Trigger a reconfiguration by re-reading the local <svc.conf> file.
00292       this->reconfigure_services ();
00293     }
00294   else
00295     {
00296       // Just process a single request passed in via the socket
00297       // remotely.
00298       ACE_Service_Config_Guard guard (ACE_Service_Config::global ());
00299       ACE_Service_Config::process_directive (request);
00300     }
00301 
00302   // Additional management services may be handled here...
00303 }

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.

00248 {
00249   ACE_TRACE ("ACE_Service_Manager::reconfigure_services");
00250 
00251 #if 0
00252 // Send ourselves a signal!  ACE_OS::kill (ACE_OS::getpid (),
00253 // this->signum_);
00254 #endif /* 0 */
00255 
00256   // Flag the main event loop that a reconfiguration should occur.
00257   // The next trip through the <ACE_Reactor::run_event_loop> should
00258   // pick this up and cause a reconfiguration.  Note that we can't
00259   // trigger the reconfiguration automatically since that might "pull
00260   // the rug" out from underneath the existing services in a
00261   // problematic way.
00262   ACE_Service_Config::reconfig_occurred ((sig_atomic_t) 1);
00263   return static_cast<int> (this->client_stream_.send_n ("done\n",
00264                                                         sizeof ("done\n")));
00265 }

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.

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

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.

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


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

Generated on Tue Nov 3 23:17:31 2009 for ACE by  doxygen 1.6.1