123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- # Copyright (C) 2010 Internet Systems Consortium.
- #
- # Permission to use, copy, modify, and distribute this software for any
- # purpose with or without fee is hereby granted, provided that the above
- # copyright notice and this permission notice appear in all copies.
- #
- # THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
- # DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- # INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
- # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- import threading
- import socket
- import select
- class ServeMixIn():
- '''Mix-In class to override the function serve_forever()
- and shutdown() in class socketserver.
- '''
- _serving = False
- _is_shut_down = threading.Event()
- _read_sock, _write_sock = socket.socketpair()
- def serve_forever(self, poll_interval=0.5):
- ''' Override the serve_forever() in class BaseServer.
- use one socket pair to wake up the select when shutdown()
- is called in anther thread.
- '''
- self._serving = True
- self._is_shut_down.clear()
- while self._serving:
- # block until the self.socket or self._read_sock is readable
- try:
- r, w, e = select.select([self, self._read_sock], [], [])
- except select.error as err:
- if err.args[0] != EINTR:
- raise
- else:
- continue
- if r:
- if self._read_sock in r:
- break
- else:
- self._handle_request_noblock()
- self._is_shut_down.set()
- def shutdown(self):
- '''Stops the serve_forever loop.
- Blocks until the loop has finished, the function should be called
- in another thread when serve_forever is running, or it will block.
- '''
- self._serving = False
- self._write_sock.send(b'anydata') # make self._read_sock readable.
- self._is_shut_down.wait()
|