backlog = 5
- closed = False
-
def __init__(self, root, interface, port=8080):
self.root = root
self.interface = interface
# ready indicates when we are ready to begin accept connections
# it should be set after a successful bind
self.ready = False
+ self.closed = False
def run(self):
self.bind()
def stop(self):
self.close()
-
def bind(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
flags = fcntl.fcntl(self.socket.fileno(), fcntl.F_GETFD)
def close(self):
self.closed = True
+ self.ready = False
try:
+ # shutdown socket explicitly to allow reuse
+ self.socket.shutdown(socket.SHUT_RDWR)
self.socket.close()
except:
pass
def getResource(self, req):
return self.root.getRequestResource(req)
+ def shutdown(self):
+ self.close()
+
class UnixHttpServer(HttpServer):
def __init__(self, root):
self.servers = []
self.root = root
+ self.running = False
self.cleaningUp = False
self.reloadingConfig = False
server.shutdown()
except:
pass
+ self.running = False
def reloadConfig(self, signum = 0, frame = None):
log.debug("SrvServer.reloadConfig()")
if server.ready:
continue
- thread = Thread(target=server.run, name=server.__class__.__name__)
- if isinstance(server, HttpServer):
- thread.setDaemon(True)
+ thread = Thread(target=server.run,
+ name=server.__class__.__name__)
+ thread.setDaemon(True)
thread.start()
threads.append(thread)
-
# check for when all threads have initialized themselves and then
# close the status pipe
status.close()
status = None
- # Interruptible Thread.join - Python Bug #1167930
- # Replaces: for t in threads: t.join()
- # Reason: The above will cause python signal handlers to be
- # blocked so we're not able to catch SIGTERM in any
- # way for cleanup
- runningThreads = threads
- while len(runningThreads) > 0:
- try:
- for t in threads:
- t.join(1.0)
- runningThreads = [t for t in threads
- if t.isAlive() and not t.isDaemon()]
- if self.cleaningUp and len(runningThreads) > 0:
- log.debug("Waiting for %s." %
- [x.getName() for x in runningThreads])
- except:
- pass
-
+ # loop to keep main thread alive until it receives a SIGTERM
+ self.running = True
+ while self.running:
+ time.sleep(100000000)
+
if self.reloadingConfig:
log.info("Restarting all XML-RPC and Xen-API servers...")
self.cleaningUp = False
self.reloadingConfig = False
xoptions.set_config()
- new_servers = [x for x in self.servers
- if isinstance(x, HttpServer)]
- self.servers = new_servers
+ self.servers = []
_loadConfig(self, self.root, True)
else:
break
def _loadConfig(servers, root, reload):
- if not reload and xoptions.get_xend_http_server():
+ if xoptions.get_xend_http_server():
servers.add(HttpServer(root,
xoptions.get_xend_address(),
xoptions.get_xend_port()))
- if not reload and xoptions.get_xend_unix_server():
+ if xoptions.get_xend_unix_server():
path = xoptions.get_xend_unix_path()
log.info('unix path=' + path)
servers.add(UnixHttpServer(root, path))
# Custom runloop so we can cleanup when exiting.
# -----------------------------------------------------------------
try:
- self.server.socket.settimeout(1.0)
while self.running:
self.server.handle_request()
finally:
- self.cleanup()
+ self.shutdown()
def cleanup(self):
- log.debug("XMLRPCServer.cleanup()")
+ log.debug('XMLRPCServer.cleanup()')
try:
- self.server.socket.close()
+ if hasattr(self, 'server'):
+ # shutdown socket explicitly to allow reuse
+ self.server.socket.shutdown(socket.SHUT_RDWR)
+ self.server.socket.close()
except Exception, exn:
log.exception(exn)
pass
def shutdown(self):
self.running = False
- self.ready = False
-
+ if self.ready:
+ self.ready = False
+ self.cleanup()