docs: def wait(fs, timeout=-1, return_when=ALL_COMPLETED):
      """Wait for the futures in the given sequence to complete.
      Using this function may prevent a worker from executing.
  
      :param fs: The sequence of Futures to wait upon.
      :param timeout: The maximum number of seconds to wait. If negative or not
          specified, then there is no limit on the wait time.
      :param return_when: Indicates when this function should return. The options
          are:
  
          ===============   ================================================
          FIRST_COMPLETED   Return when any future finishes or is cancelled.
          FIRST_EXCEPTION   Return when any future finishes by raising an
                            exception. If no future raises an exception then
                            it is equivalent to ALL_COMPLETED.
          ALL_COMPLETED     Return when all futures finish or are cancelled.
          ===============   ================================================
  
      :return: A named 2-tuple of sets. The first set, named 'done', contains the
          futures that completed (is finished or cancelled) before the wait
          completed. The second set, named 'not_done', contains uncompleted
          futures."""
  
      DoneAndNotDoneFutures = namedtuple('DoneAndNotDoneFutures', 'done not_done')
      if timeout < 0:
          # Negative timeout means blocking.
          if return_when == FIRST_COMPLETED:
              next(_waitAny(*fs))
          elif return_when in [ALL_COMPLETED, FIRST_EXCEPTION]:
              for _ in _waitAll(*fs):
                  pass
          done = set(f for f in fs if f.done())
          not_done = set(fs) - done
          return DoneAndNotDoneFutures(done, not_done)
  
      elif timeout == 0:
          # Zero-value entry means non-blocking
          control.execQueue.flush()
          control.execQueue.updateQueue()
          done = set(f for f in fs if f._ended())
          not_done = set(fs) - done
          return DoneAndNotDoneFutures(done, not_done)
  
      else:
          # Any other value means blocking for a given time.
          done = set()
          start_time = time.time()
          while time.time() - start_time < timeout:
              # Flush futures on local queue (to be executed remotely)
              control.execQueue.flush()
              # Block until data arrives (to free CPU time)
              control.execQueue.socket._poll(time.time() - start_time)
              # Update queue
              control.execQueue.updateQueue()
  
              for f in fs:
                  if f._ended():
                      done.add(f)
  
              not_done = set(fs) - done
  
              if return_when == FIRST_COMPLETED and len(done) > 0:
                  break
              if len(not_done) == 0:
                  break
          return DoneAndNotDoneFutures(done, not_done)