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.

 ~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.

int debug_
 Keep track of the debugging level.

int signum_
 The signal used to trigger reconfiguration.


Static Protected Attributes

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: + 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 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.

References ACE_TRACE, and SIGHUP.

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

ACE_Service_Manager::~ACE_Service_Manager void   ) 
 

Destructor.

Definition at line 42 of file Service_Manager.cpp.

References ACE_TRACE.

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


Member Function Documentation

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

Dump the state of an object.

Definition at line 24 of file Service_Manager.cpp.

References ACE_TRACE.

00025 {
00026 #if defined (ACE_HAS_DUMP)
00027   ACE_TRACE ("ACE_Service_Manager::dump");
00028 #endif /* ACE_HAS_DUMP */
00029 }

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

Terminates object when dynamic unlinking occurs.

Reimplemented from ACE_Shared_Object.

Definition at line 139 of file Service_Manager.cpp.

References ACE_TRACE, get_handle(), handle_close(), ACE_Reactor::instance(), and ACE_Reactor::remove_handler().

00140 {
00141   ACE_TRACE ("ACE_Service_Manager::fini");
00142 
00143   int retv = 0;
00144   if (this->get_handle () != ACE_INVALID_HANDLE)
00145     {
00146       retv = ACE_Reactor::instance ()->remove_handler
00147         (this,
00148          ACE_Event_Handler::ACCEPT_MASK |
00149          ACE_Event_Handler::DONT_CALL);
00150       this->handle_close (ACE_INVALID_HANDLE,
00151                           ACE_Event_Handler::NULL_MASK);
00152     }
00153   return retv;
00154 }

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

Get the I/O handle.

Reimplemented from ACE_Event_Handler.

Definition at line 157 of file Service_Manager.cpp.

References ACE_TRACE, and ACE_IPC_SAP::get_handle().

Referenced by fini(), and init().

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

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

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

Reimplemented from ACE_Event_Handler.

Definition at line 132 of file Service_Manager.cpp.

References ACE_Reactor_Mask, ACE_TRACE, and ACE_SOCK_Acceptor::close().

Referenced by fini().

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

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

References ACE_SOCK_Acceptor::accept(), ACE_DEBUG, ACE_LIB_TEXT, ACE_TCHAR, ACE_TEXT_CHAR_TO_TCHAR, ACE_TRACE, client_stream_, ACE_SOCK_Stream::close(), 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::strchr(), and ACE_Reactor::uses_event_associations().

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

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

References ucontext_t.

00165 {
00166   return 0;
00167 }

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

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

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

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

References ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_TCHAR, ACE_TRACE, ACE_OS::atoi(), DEFAULT_PORT_, get_handle(), ACE_Reactor::instance(), LM_ERROR, open(), ACE_Reactor::register_handler(), and ACE_INET_Addr::set().

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

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 173 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_, ACE_Service_Type_Impl::info(), LM_DEBUG, LM_ERROR, ACE_Service_Type::name(), ACE_Service_Repository_Iterator::next(), ACE_SOCK_Stream::send_n(), ssize_t, ACE_OS::strcat(), ACE_OS::strcpy(), ACE_OS::strlen(), and ACE_Service_Type::type().

Referenced by process_request().

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

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

Definition at line 62 of file Service_Manager.cpp.

References ACE_TRACE, and ACE_SOCK_Acceptor::open().

Referenced by init().

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     return -1;
00069   return 0;
00070 }

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

Handle one request.

Definition at line 242 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::strcmp().

Referenced by handle_input().

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

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 220 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().

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

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.

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

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.

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

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


Member Data Documentation

ACE_SOCK_Acceptor ACE_Service_Manager::acceptor_ [protected]
 

Acceptor instance.

Definition at line 105 of file Service_Manager.h.

ACE_Service_Manager::ACE_ALLOC_HOOK_DECLARE [protected]
 

Declare the dynamic allocation hooks.

Definition at line 86 of file Service_Manager.h.

ACE_SOCK_Stream ACE_Service_Manager::client_stream_ [protected]
 

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

Definition at line 102 of file Service_Manager.h.

Referenced by handle_input(), list_services(), and reconfigure_services().

int ACE_Service_Manager::debug_ [protected]
 

Keep track of the debugging level.

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

Referenced by init().

int ACE_Service_Manager::signum_ [protected]
 

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:
Generated on Thu Nov 9 11:29:14 2006 for ACE by doxygen 1.3.6