docs: def results(self):
          """Start all the tasks and return data on an iterator"""
          tt = None
          for i, tf in enumerate(self[:-1]):
              tt = self[i+1]
              q = Queue(tf.qsize)
              tf.set_out(q, tt.workers)
              tt.set_in(q, tf.workers)
  
          if tt is None: # we have only one pool
              tt = self[0]
          q = Queue(tt.qsize)
          err_q = Queue()
          tt.set_out(q, 1)
  
          for t in self:
              t.set_err(err_q)
              t._start()
  
          for item in iterqueue(q, tt.workers):
              yield item
  
          errors = list(iterqueue(err_q, sum(t.workers for t in self)))
  
          for t in self:
              t._join()
  
          if len(errors) > 0:
              task_name, ex = errors[0]
              if len(errors) == 1:
                  msg = 'The task "%s" raised %s' % (task_name, repr(ex),)
              else:
                  msg = '%d tasks raised an exeption. First error reported on task "%s": %s' % (len(errors), task_name, repr(ex))
  
              raise TaskException(msg)