#include <Service_Manager.h>
Inheritance diagram for ACE_Service_Manager:
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. |
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.
Definition at line 35 of file Service_Manager.cpp. References ACE_TRACE, and SIGHUP.
|
|
Destructor.
Definition at line 42 of file Service_Manager.cpp. References ACE_TRACE.
00043 { 00044 ACE_TRACE ("ACE_Service_Manager::~ACE_Service_Manager"); 00045 } |
|
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 } |
|
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 } |
|
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 } |
|
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().
|
|
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 } |
|
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 }
|
|
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 } |
|
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 } |
|
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 } |
|
Definition at line 62 of file Service_Manager.cpp. References ACE_TRACE, and ACE_SOCK_Acceptor::open(). Referenced by init().
|
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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. Referenced by handle_input(), list_services(), and reconfigure_services(). |
|
Keep track of the debugging level.
Definition at line 108 of file Service_Manager.h. |
|
Default port for the Acceptor to listen on.
Definition at line 33 of file Service_Manager.cpp. Referenced by init(). |
|
The signal used to trigger reconfiguration.
Definition at line 111 of file Service_Manager.h. |