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

Service_Manager.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // $Id: Service_Manager.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:22 chad Exp $
00003 
00004 #include "ace/Get_Opt.h"
00005 #include "ace/Log_Msg.h"
00006 #include "ace/Service_Repository.h"
00007 #include "ace/Service_Config.h"
00008 #include "ace/Service_Manager.h"
00009 #include "ace/Reactor.h"
00010 #include "ace/WFMO_Reactor.h"
00011 
00012 #if !defined (__ACE_INLINE__)
00013 #include "ace/Service_Manager.i"
00014 #endif /* __ACE_INLINE__ */
00015 
00016 ACE_RCSID(ace, Service_Manager, "$Id: Service_Manager.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:22 chad Exp $")
00017 
00018 ACE_ALLOC_HOOK_DEFINE(ACE_Service_Manager)
00019 
00020 void
00021 ACE_Service_Manager::dump (void) const
00022 {
00023   ACE_TRACE ("ACE_Service_Manager::dump");
00024 }
00025 
00026 // Static variables.
00027 
00028 u_short ACE_Service_Manager::DEFAULT_PORT_ = 10000;
00029 
00030 ACE_Service_Manager::ACE_Service_Manager (void)
00031   : debug_ (0),
00032     signum_ (SIGHUP)
00033 {
00034   ACE_TRACE ("ACE_Service_Manager::ACE_Service_Manager");
00035 }
00036 
00037 int
00038 ACE_Service_Manager::suspend (void)
00039 {
00040   ACE_TRACE ("ACE_Service_Manager::suspend");
00041   return ACE_Reactor::instance ()->suspend_handler (this);
00042 }
00043 
00044 int
00045 ACE_Service_Manager::resume (void)
00046 {
00047   ACE_TRACE ("ACE_Service_Manager::resume");
00048   return ACE_Reactor::instance ()->resume_handler (this);
00049 }
00050 
00051 int
00052 ACE_Service_Manager::open (const ACE_INET_Addr &sia)
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 }
00061 
00062 int
00063 ACE_Service_Manager::info (ACE_TCHAR **strp, size_t length) const
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 }
00083 
00084 int
00085 ACE_Service_Manager::init (int argc, ACE_TCHAR *argv[])
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 }
00120 
00121 int
00122 ACE_Service_Manager::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
00123 {
00124   ACE_TRACE ("ACE_Service_Manager::handle_close");
00125   return this->acceptor_.close ();
00126 }
00127 
00128 int
00129 ACE_Service_Manager::fini (void)
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 }
00145 
00146 ACE_HANDLE
00147 ACE_Service_Manager::get_handle (void) const
00148 {
00149   ACE_TRACE ("ACE_Service_Manager::get_handle");
00150   return this->acceptor_.get_handle ();
00151 }
00152 
00153 int
00154 ACE_Service_Manager::handle_signal (int, siginfo_t *, ucontext_t *)
00155 {
00156   return 0;
00157 }
00158 
00159 // Determine all the services offered by this daemon and return the
00160 // information back to the client.
00161 
00162 int
00163 ACE_Service_Manager::list_services (void)
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 }
00205 
00206 // Trigger a reconfiguration of the Service Configurator via its
00207 // svc.conf file.
00208 
00209 int
00210 ACE_Service_Manager::reconfigure_services (void)
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 }
00229 
00230 // isolate the request-processing code
00231 void
00232 ACE_Service_Manager::process_request (ACE_TCHAR *request)
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 }
00258 
00259 // Accept new connection from client and carry out the service they
00260 // request.
00261 
00262 int
00263 ACE_Service_Manager::handle_input (ACE_HANDLE)
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 }

Generated on Mon Jun 16 11:21:11 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002