@classmethod
def configurable_default(cls):
- return IOLoop
+ if hasattr(select, "epoll"):
+ # Python 2.6+ on Linux
+ return EPollIOLoop
+ elif hasattr(select, "kqueue"):
+ # Python 2.6+ on BSD or Mac
+ return KQueueIOLoop
+ else:
+ try:
+ # Python 2.5 on Linux with our C module installed
+ from tornado import epoll
+ return EPoll25IOLoop
+ except Exception:
+ # Everything else
+ return SelectIOLoop
# Constants from the epoll module
_EPOLLIN = 0x001
_current = threading.local()
- def initialize(self, impl=None):
- self._impl = impl or _poll()
+ def initialize(self, impl):
+ self._impl = impl
if hasattr(self._impl, 'fileno'):
set_close_exec(self._impl.fileno())
self._handlers = {}
_EPOLL_CTL_MOD = 3
def __init__(self):
+ from tornado import epoll
+ self.epoll = epoll
self._epoll_fd = epoll.epoll_create()
def fileno(self):
os.close(self._epoll_fd)
def register(self, fd, events):
- epoll.epoll_ctl(self._epoll_fd, self._EPOLL_CTL_ADD, fd, events)
+ self.epoll.epoll_ctl(self._epoll_fd, self._EPOLL_CTL_ADD, fd, events)
def modify(self, fd, events):
- epoll.epoll_ctl(self._epoll_fd, self._EPOLL_CTL_MOD, fd, events)
+ self.epoll.epoll_ctl(self._epoll_fd, self._EPOLL_CTL_MOD, fd, events)
def unregister(self, fd):
- epoll.epoll_ctl(self._epoll_fd, self._EPOLL_CTL_DEL, fd, 0)
+ self.epoll.epoll_ctl(self._epoll_fd, self._EPOLL_CTL_DEL, fd, 0)
def poll(self, timeout):
- return epoll.epoll_wait(self._epoll_fd, int(timeout * 1000))
+ return self.epoll.epoll_wait(self._epoll_fd, int(timeout * 1000))
+
+
+class EPoll25IOLoop(IOLoop):
+ def initialize(self, **kwargs):
+ super(EPoll25IOLoop, self).initialize(impl=_EPoll(), **kwargs)
class _KQueue(object):
return events.items()
+class KQueueIOLoop(IOLoop):
+ def initialize(self, **kwargs):
+ super(KQueueIOLoop, self).initialize(impl=_KQueue(), **kwargs)
+
+
class _Select(object):
"""A simple, select()-based IOLoop implementation for non-Linux systems"""
def __init__(self):
events[fd] = events.get(fd, 0) | IOLoop.ERROR
return events.items()
+class SelectIOLoop(IOLoop):
+ def initialize(self, **kwargs):
+ super(SelectIOLoop, self).initialize(impl=_Select(), **kwargs)
-# Choose a poll implementation. Use epoll if it is available, fall back to
-# select() for non-Linux platforms
-if hasattr(select, "epoll"):
- # Python 2.6+ on Linux
- _poll = select.epoll
-elif hasattr(select, "kqueue"):
- # Python 2.6+ on BSD or Mac
- _poll = _KQueue
-else:
- try:
- # Linux systems with our C module installed
- from tornado import epoll
- _poll = _EPoll
- except Exception:
- # All other systems
- import sys
- if "linux" in sys.platform:
- gen_log.warning("epoll module not found; using select()")
- _poll = _Select
+
+class EPollIOLoop(IOLoop):
+ def initialize(self, **kwargs):
+ super(EPollIOLoop, self).initialize(impl=select.epoll(), **kwargs)
"""
from tornado.options import define, options, parse_command_line
- define('autoreload', type=bool, default=False,
- help="DEPRECATED: use tornado.autoreload.main instead")
- define('httpclient', type=str, default=None)
define('exception_on_interrupt', type=bool, default=True,
help=("If true (default), ctrl-c raises a KeyboardInterrupt "
"exception. This prints a stack trace but cannot interrupt "
argv = [sys.argv[0]] + parse_command_line(sys.argv)
- if options.httpclient:
- from tornado.httpclient import AsyncHTTPClient
- AsyncHTTPClient.configure(options.httpclient)
-
if not options.exception_on_interrupt:
signal.signal(signal.SIGINT, signal.SIG_DFL)
gen_log.info('PASS')
else:
gen_log.error('FAIL')
- if not options.autoreload:
- raise
- if options.autoreload:
- import tornado.autoreload
- tornado.autoreload.wait()
+ raise
if __name__ == '__main__':
main()
argument.
* Keyword arguments to `AsyncHTTPClient.configure` are no longer used
when instantiating an implementation subclass directly.
+* The `IOLoop` poller implementations (``select``, ``epoll``, ``kqueue``)
+ are now available as distinct subclasses of `IOLoop`. Instantiating
+ `IOLoop` will continue to automatically choose the best available
+ implementation.
+* `IOLoop` now has a static ``configure`` method like the one on
+ `AsyncHTTPClient`, which can be used to select an IOLoop implementation
+ other than the default.
+* The deprecated ``--autoreload`` option of `tornado.testing.main` has
+ been removed. Use ``python -m tornado.autoreload`` as a prefix command
+ instead.
+* The ``--httpclient`` option of `tornado.testing.main` has been moved
+ to `tornado.test.runtests` so as not to pollute the application
+ option namespace. The `tornado.options` module's new callback
+ support now makes it easy to add options from a wrapper script
+ instead of putting all possible options in `tornado.testing.main`.