Service_Manager.cpp

Go to the documentation of this file.
00001 // $Id: Service_Manager.cpp 81517 2008-04-29 07:23:47Z johnnyw $
00002 
00003 #include "ace/Service_Manager.h"
00004 
00005 #include "ace/Get_Opt.h"
00006 #include "ace/Log_Msg.h"
00007 #include "ace/Service_Repository.h"
00008 #include "ace/Service_Config.h"
00009 #include "ace/Service_Types.h"
00010 #include "ace/Reactor.h"
00011 #include "ace/WFMO_Reactor.h"
00012 #include "ace/OS_NS_stdio.h"
00013 #include "ace/OS_NS_string.h"
00014 
00015 ACE_RCSID (ace,
00016            Service_Manager,
00017            "$Id: Service_Manager.cpp 81517 2008-04-29 07:23:47Z johnnyw $")
00018 
00019 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00020 
00021 ACE_ALLOC_HOOK_DEFINE (ACE_Service_Manager)
00022 
00023 void
00024 ACE_Service_Manager::dump (void) const
00025 {
00026 #if defined (ACE_HAS_DUMP)
00027   ACE_TRACE ("ACE_Service_Manager::dump");
00028 #endif /* ACE_HAS_DUMP */
00029 }
00030 
00031 // Static variables.
00032 
00033 u_short ACE_Service_Manager::DEFAULT_PORT_ = 10000;
00034 
00035 ACE_Service_Manager::ACE_Service_Manager (void)
00036   : debug_ (false),
00037     signum_ (SIGHUP)
00038 {
00039   ACE_TRACE ("ACE_Service_Manager::ACE_Service_Manager");
00040 }
00041 
00042 ACE_Service_Manager::~ACE_Service_Manager (void)
00043 {
00044   ACE_TRACE ("ACE_Service_Manager::~ACE_Service_Manager");
00045 }
00046 
00047 int
00048 ACE_Service_Manager::suspend (void)
00049 {
00050   ACE_TRACE ("ACE_Service_Manager::suspend");
00051   return ACE_Reactor::instance ()->suspend_handler (this);
00052 }
00053 
00054 int
00055 ACE_Service_Manager::resume (void)
00056 {
00057   ACE_TRACE ("ACE_Service_Manager::resume");
00058   return ACE_Reactor::instance ()->resume_handler (this);
00059 }
00060 
00061 int
00062 ACE_Service_Manager::open (const ACE_INET_Addr &sia)
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 }
00071 
00072 int
00073 ACE_Service_Manager::info (ACE_TCHAR **strp, size_t length) const
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_TEXT ("%d/%s %s"),
00084                    sa.get_port_number (),
00085                    ACE_TEXT ("tcp"),
00086                    ACE_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 }
00093 
00094 int
00095 ACE_Service_Manager::init (int argc, ACE_TCHAR *argv[])
00096 {
00097   ACE_TRACE ("ACE_Service_Manager::init");
00098   ACE_INET_Addr local_addr (ACE_Service_Manager::DEFAULT_PORT_);
00099 
00100   //FUZZ: disable check_for_lack_ACE_OS
00101   ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("dp:s:"), 0); // Start at argv[0]
00102 
00103   for (int c; (c = getopt ()) != -1; )
00104   //FUZZ: enable check_for_lack_ACE_OS
00105      switch (c)
00106        {
00107        case 'd':
00108          this->debug_ = true;
00109          break;
00110        case 'p':
00111          local_addr.set ((u_short) ACE_OS::atoi (getopt.opt_arg ()));
00112          break;
00113        case 's':
00114          this->signum_ = ACE_OS::atoi (getopt.opt_arg ());
00115          break;
00116        default:
00117          break;
00118        }
00119 
00120   if (this->get_handle () == ACE_INVALID_HANDLE &&
00121       this->open (local_addr) == -1)
00122     ACE_ERROR_RETURN ((LM_ERROR,
00123                        ACE_TEXT ("%p\n"),
00124                        ACE_TEXT ("open")), -1);
00125   else if (ACE_Reactor::instance ()->register_handler
00126            (this,
00127             ACE_Event_Handler::ACCEPT_MASK) == -1)
00128     ACE_ERROR_RETURN ((LM_ERROR,
00129                        ACE_TEXT ("registering service with ACE_Reactor\n")),
00130                       -1);
00131   return 0;
00132 }
00133 
00134 int
00135 ACE_Service_Manager::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
00136 {
00137   ACE_TRACE ("ACE_Service_Manager::handle_close");
00138   return this->acceptor_.close ();
00139 }
00140 
00141 int
00142 ACE_Service_Manager::fini (void)
00143 {
00144   ACE_TRACE ("ACE_Service_Manager::fini");
00145 
00146   int retv = 0;
00147   if (this->get_handle () != ACE_INVALID_HANDLE)
00148     {
00149       retv = ACE_Reactor::instance ()->remove_handler
00150         (this,
00151          ACE_Event_Handler::ACCEPT_MASK |
00152          ACE_Event_Handler::DONT_CALL);
00153       this->handle_close (ACE_INVALID_HANDLE,
00154                           ACE_Event_Handler::NULL_MASK);
00155     }
00156   return retv;
00157 }
00158 
00159 ACE_HANDLE
00160 ACE_Service_Manager::get_handle (void) const
00161 {
00162   ACE_TRACE ("ACE_Service_Manager::get_handle");
00163   return this->acceptor_.get_handle ();
00164 }
00165 
00166 int
00167 ACE_Service_Manager::handle_signal (int, siginfo_t *, ucontext_t *)
00168 {
00169   return 0;
00170 }
00171 
00172 // Determine all the services offered by this daemon and return the
00173 // information back to the client.
00174 
00175 int
00176 ACE_Service_Manager::list_services (void)
00177 {
00178   ACE_TRACE ("ACE_Service_Manager::list_services");
00179   ACE_Service_Repository_Iterator sri (*ACE_Service_Repository::instance (), 0);
00180 
00181   for (const ACE_Service_Type *sr;
00182        sri.next (sr) != 0;
00183        sri.advance ())
00184     {
00185       ssize_t len = static_cast<ssize_t> (ACE_OS::strlen (sr->name ())) + 11;
00186       ACE_TCHAR buf[BUFSIZ];
00187       ACE_TCHAR *p = buf + len;
00188 
00189       ACE_OS::strcpy (buf, sr->name ());
00190       ACE_OS::strcat (buf, (sr->active ()) ?
00191                       ACE_TEXT (" (active) ") :
00192                       ACE_TEXT (" (paused) "));
00193 
00194       p[-1] = ' ';
00195       p[0]  = '\0';
00196 
00197       len += sr->type ()->info (&p, sizeof buf - len);
00198 
00199       if (this->debug_)
00200         ACE_DEBUG ((LM_DEBUG,
00201                     ACE_TEXT ("len = %d, info = %s%s"),
00202                     len,
00203                     buf,
00204                     buf[len - 1] == '\n' ? ACE_TEXT ("") : ACE_TEXT ("\n")));
00205 
00206       if (len > 0)
00207         {
00208           ssize_t n = this->client_stream_.send_n (buf, len);
00209           if (n <= 0 && errno != EPIPE)
00210             ACE_ERROR ((LM_ERROR,
00211                         ACE_TEXT ("%p\n"),
00212                         ACE_TEXT ("send_n")));
00213         }
00214     }
00215 
00216   return 0;
00217 }
00218 
00219 // Trigger a reconfiguration of the Service Configurator via its
00220 // svc.conf file.
00221 
00222 int
00223 ACE_Service_Manager::reconfigure_services (void)
00224 {
00225   ACE_TRACE ("ACE_Service_Manager::reconfigure_services");
00226 
00227 #if 0
00228 // Send ourselves a signal!  ACE_OS::kill (ACE_OS::getpid (),
00229 // this->signum_);
00230 #endif /* 0 */
00231 
00232   // Flag the main event loop that a reconfiguration should occur.
00233   // The next trip through the <ACE_Reactor::run_event_loop> should
00234   // pick this up and cause a reconfiguration.  Note that we can't
00235   // trigger the reconfiguration automatically since that might "pull
00236   // the rug" out from underneath the existing services in a
00237   // problematic way.
00238   ACE_Service_Config::reconfig_occurred ((sig_atomic_t) 1);
00239   return static_cast<int> (this->client_stream_.send_n ("done\n",
00240                                                         sizeof ("done\n")));
00241 }
00242 
00243 // isolate the request-processing code
00244 void
00245 ACE_Service_Manager::process_request (ACE_TCHAR *request)
00246 {
00247   ACE_TRACE("ACE_Service_Manager::process_request");
00248   ACE_TCHAR *p;
00249 
00250   // Kill trailing newlines.
00251   for (p = request;
00252        (*p != '\0') && (*p != '\r') && (*p != '\n');
00253        p++)
00254     continue;
00255 
00256   *p = '\0';
00257 
00258   if (ACE_OS::strcmp (request, ACE_TEXT ("help")) == 0)
00259     // Return a list of the configured services.
00260     this->list_services ();
00261   else if (ACE_OS::strcmp (request, ACE_TEXT ("reconfigure") )== 0)
00262     // Trigger a reconfiguration by re-reading the local <svc.conf> file.
00263     this->reconfigure_services ();
00264   else
00265     // Just process a single request passed in via the socket
00266     // remotely.
00267     ACE_Service_Config::process_directive (request);
00268 
00269   // Additional management services may be handled here...
00270 }
00271 
00272 // Accept new connection from client and carry out the service they
00273 // request.
00274 
00275 int
00276 ACE_Service_Manager::handle_input (ACE_HANDLE)
00277 {
00278   ACE_TRACE ("ACE_Service_Manager::handle_input");
00279 
00280   // Try to find out if the implementation of the reactor that we are
00281   // using requires us to reset the event association for the newly
00282   // created handle. This is because the newly created handle will
00283   // inherit the properties of the listen handle, including its event
00284   // associations.
00285   int reset_new_handle =
00286     ACE_Reactor::instance ()->uses_event_associations ();
00287 
00288   if (this->acceptor_.accept (this->client_stream_, // stream
00289                               0, // remote address
00290                               0, // timeout
00291                               1, // restart
00292                               reset_new_handle  // reset new handler
00293                               ) == -1)
00294     return -1;
00295 
00296   if (this->debug_)
00297     {
00298       ACE_DEBUG ((LM_DEBUG,
00299                   ACE_TEXT ("client_stream fd = %d\n"),
00300                  this->client_stream_.get_handle ()));
00301       ACE_INET_Addr sa;
00302       if (this->client_stream_.get_remote_addr (sa) == -1)
00303         return -1;
00304 
00305       ACE_DEBUG ((LM_DEBUG,
00306                   ACE_TEXT ("accepted from host %C at port %d\n"),
00307                   sa.get_host_name (),
00308                   sa.get_port_number ()));
00309     }
00310 
00311   ACE_TCHAR request[BUFSIZ];
00312   ACE_TCHAR* offset = request;
00313   ssize_t remaining = sizeof (request);
00314 
00315   // Read service request from client.
00316 
00317   ssize_t result;
00318 
00319   // Keep looping until we actually get the request.  Note that Win32
00320   // sets the socket into non-blocking mode, so we may need to loop if
00321   // the system is heavily loaded.  Read bytes into the buffer until a
00322   // '\n' or '\r' is found in the buffer, otherwise the buffer
00323   // contains an incomplete string.
00324 
00325   int error;
00326   do
00327     {
00328       result = client_stream_.recv (offset, remaining);
00329       error = errno;
00330       if (result == 0 && error != EWOULDBLOCK)
00331         remaining = 0;
00332 
00333       if (result >= 0)
00334         {
00335           if ((remaining -= result) <= 0)
00336             {
00337               ACE_DEBUG ((LM_ERROR,
00338                           ACE_TEXT ("Request buffer overflow.\n")));
00339               result = 0;
00340               break;
00341             }
00342 
00343           offset += result;
00344           *offset = 0;
00345 
00346           if (ACE_OS::strchr (request, '\r') != 0
00347               || ACE_OS::strchr (request, '\n') != 0)
00348             remaining = 0;
00349         }
00350     }
00351   while (result == -1 && error == EWOULDBLOCK || remaining > 0);
00352 
00353   switch (result)
00354     {
00355     case -1:
00356       if (this->debug_)
00357         ACE_DEBUG ((LM_ERROR,
00358                     ACE_TEXT ("%p\n"),
00359                     ACE_TEXT ("recv")));
00360       break;
00361     case 0:
00362       return 0;
00363       /* NOTREACHED */
00364     default:
00365       {
00366         ACE_Event_Handler *old_signal_handler = 0;
00367         ACE_Reactor::instance ()->register_handler (SIGPIPE,
00368                                                     this,
00369                                                     0,
00370                                                     &old_signal_handler);
00371 
00372         this->process_request (request);
00373 
00374         // Restore existing SIGPIPE handler
00375         ACE_Reactor::instance ()->register_handler (SIGPIPE,
00376                                                     old_signal_handler);
00377       }
00378     }
00379 
00380   if (this->client_stream_.close () == -1 && this->debug_)
00381     ACE_DEBUG ((LM_ERROR,
00382                 ACE_TEXT ("%p\n"),
00383                 ACE_TEXT ("close")));
00384   return 0;
00385 }
00386 
00387 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:42 2010 for ACE by  doxygen 1.4.7