Index: Lib/asyncore.py =================================================================== --- Lib/asyncore.py (revisione 80217) +++ Lib/asyncore.py (copia locale) @@ -115,7 +115,8 @@ except: obj.handle_error() -def poll(timeout=0.0, map=None): +def select_poller(timeout=0.0, map=None): + """A poller which uses select(), available on most platforms.""" if map is None: map = socket_map if map: @@ -159,8 +160,8 @@ continue _exception(obj) -def poll2(timeout=0.0, map=None): - # Use the poll() support added to the select module in Python 2.0 +def poll_poller(timeout=0.0, map=None): + """A poller which uses poll(), available on most UNIXen.""" if map is None: map = socket_map if timeout is not None: @@ -191,24 +192,89 @@ continue readwrite(obj, flags) -poll3 = poll2 # Alias for backward compatibility +# Aliases for backward compatibility +poll = select_poller +poll2 = poll3 = poll_poller -def loop(timeout=30.0, use_poll=False, map=None, count=None): +def epoll_poller(timeout=0.0, map=None): + """A poller which uses epoll(), supported on Linux 2.5.44 and newer.""" if map is None: map = socket_map + pollster = select.epoll() + if map: + for fd, obj in map.items(): + flags = 0 + if obj.readable(): + flags |= select.POLLIN | select.POLLPRI + if obj.writable(): + flags |= select.POLLOUT + if flags: + # Only check for exceptions if object was either readable + # or writable. + flags |= select.POLLERR | select.POLLHUP | select.POLLNVAL + pollster.register(fd, flags) + try: + r = pollster.poll(timeout) + except select.error, err: + if err.args[0] != EINTR: + raise + r = [] + for fd, flags in r: + obj = map.get(fd) + if obj is None: + continue + readwrite(obj, flags) +def kqueue_poller(timeout=0.0, map=None): + """A poller which uses kqueue(), BSD specific.""" + if map is None: + map = socket_map + if map: + kqueue = select.kqueue() + flags = select.KQ_EV_ADD | select.KQ_EV_ENABLE + selectables = 0 + for fd, obj in map.items(): + filter = 0 + if obj.readable(): + filter |= select.KQ_FILTER_READ + if obj.writable(): + filter |= select.KQ_FILTER_WRITE + if filter: + ev = select.kevent(fd, filter=filter, flags=flags) + kqueue.control([ev], 0) + selectables += 1 + + events = kqueue.control(None, selectables, timeout) + for event in events: + fd = event.ident + obj = map.get(fd) + if obj is None: + continue + if event.filter == select.KQ_FILTER_READ: + read(obj) + if event.filter == select.KQ_FILTER_WRITE: + write(obj) + kqueue.close() + + +def loop(timeout=30.0, use_poll=False, map=None, count=None, + poller=select_poller): + if map is None: + map = socket_map + # code which grants backward compatibility with "use_poll" + # argument which should no longer be used in favor of + # "poller" if use_poll and hasattr(select, 'poll'): - poll_fun = poll2 + poller = poll_poller else: - poll_fun = poll + poller = select_poller if count is None: while map: - poll_fun(timeout, map) - + poller(timeout, map) else: while map and count > 0: - poll_fun(timeout, map) + poller(timeout, map) count = count - 1 class dispatcher: