class_docstr: Poller that returns a Future on poll, instead of blocking.
class_docstr_tok: ["Poller","that","returns","a","Future","on","poll",",","instead","of","blocking","."]
docstr: Return a Future for a poll event
docstr_tok: ["Return","a","Future","for","a","poll","event"]
code: def poll(self, timeout=-1):
      """Return a Future for a poll event"""
      future = self._Future()
      if timeout == 0:
          try:
              result = super(_AsyncPoller, self).poll(0)
          except Exception as e:
              future.set_exception(e)
          else:
              future.set_result(result)
          return future
  
      loop = self._default_loop()
  
      # register Future to be called as soon as any event is available on any socket
      watcher = self._Future()
  
      # watch raw sockets:
      raw_sockets = []
  
      def wake_raw(*args):
          if not watcher.done():
              watcher.set_result(None)
  
      watcher.add_done_callback(
          lambda f: self._unwatch_raw_sockets(loop, *raw_sockets)
      )
  
      for socket, mask in self.sockets:
          if isinstance(socket, _zmq.Socket):
              if not isinstance(socket, self._socket_class):
                  # it's a blocking zmq.Socket, wrap it in async
                  socket = self._socket_class.from_socket(socket)
              if mask & _zmq.POLLIN:
                  socket._add_recv_event("poll", future=watcher)
              if mask & _zmq.POLLOUT:
                  socket._add_send_event("poll", future=watcher)
          else:
              raw_sockets.append(socket)
              evt = 0
              if mask & _zmq.POLLIN:
                  evt |= self._READ
              if mask & _zmq.POLLOUT:
                  evt |= self._WRITE
              self._watch_raw_socket(loop, socket, evt, wake_raw)
  
      def on_poll_ready(f):
          if future.done():
              return
          if watcher.cancelled():
              try:
                  future.cancel()
              except RuntimeError:
                  # RuntimeError may be called during teardown
                  pass
              return
          if watcher.exception():
              future.set_exception(watcher.exception())
          else:
              try:
                  result = super(_AsyncPoller, self).poll(0)
              except Exception as e:
                  future.set_exception(e)
              else:
                  future.set_result(result)
  
      watcher.add_done_callback(on_poll_ready)
  
      if timeout is not None and timeout > 0:
          # schedule cancel to fire on poll timeout, if any
          def trigger_timeout():
              if not watcher.done():
                  watcher.set_result(None)
  
          timeout_handle = loop.call_later(
              1e-3 * timeout, trigger_timeout
          )
  
          def cancel_timeout(f):
              if hasattr(timeout_handle, "cancel"):
                  timeout_handle.cancel()
              else:
                  loop.remove_timeout(timeout_handle)
  
          future.add_done_callback(cancel_timeout)
  
      def cancel_watcher(f):
          if not watcher.done():
              watcher.cancel()
  
      future.add_done_callback(cancel_watcher)
  
      return future
  
imports: from collections import namedtuple, deque
  from itertools import chain
  from zmq import EVENTS, POLLOUT, POLLIN
  import zmq
label_desc: Use image node_id 1 for calling the _AsyncPoller obj's underlying member method code with example usage: obj.poll(timeout) and returns: future, future