diff -r dca12bc78326 Doc/library/socketserver.rst --- a/Doc/library/socketserver.rst Sun Jul 17 19:06:03 2011 +0800 +++ b/Doc/library/socketserver.rst Mon Jul 25 21:36:25 2011 +0200 @@ -173,6 +173,11 @@ Tells the :meth:`serve_forever` loop to stop and waits until it does. +.. attribute:: BaseServer.running + + True if the server is running. + + .. versionadded:: 3.3 .. attribute:: BaseServer.address_family diff -r dca12bc78326 Lib/socketserver.py --- a/Lib/socketserver.py Sun Jul 17 19:06:03 2011 +0800 +++ b/Lib/socketserver.py Mon Jul 25 21:36:25 2011 +0200 @@ -200,6 +200,22 @@ self.RequestHandlerClass = RequestHandlerClass self.__is_shut_down = threading.Event() self.__shutdown_request = False + self.__running = False + + def __repr__(self): + info = [] + name = self.__class__.__module__ + "." + self.__class__.__name__ + info.append("status=%s" % ("running" if self.running else "stopped")) + if self.server_address: + info.append("address=%s" % repr(self.server_address)) + return '<%s %s at %#x>' % (name, ', '.join(info), id(self)) + + __str__ = __repr__ + + @property + def running(self): + """Return True if the server is running.""" + return self.__running def server_activate(self): """Called by constructor to activate the server. @@ -216,8 +232,11 @@ self.timeout. If you need to do periodic tasks, do them in another thread. """ - self.__is_shut_down.clear() + if self.running: + raise RuntimeError("the server is already running") + self.__is_shut_down.wait() try: + self.__running = True while not self.__shutdown_request: # XXX: Consider using another file descriptor or # connecting to the socket to wake this up instead of @@ -230,6 +249,7 @@ self.service_actions() finally: self.__shutdown_request = False + self.__running = False self.__is_shut_down.set() def shutdown(self): @@ -239,6 +259,8 @@ serve_forever() is running in another thread, or it will deadlock. """ + if not self.running: + raise RuntimeError("the server is not running") self.__shutdown_request = True self.__is_shut_down.wait()