docs: def copy_loop (copy_to, finished=None, buf_len=10240):
      """copy_to is a dict(in: out). When any in is ready to read, data is read
      from it and writen in its out. When any in is closed, it's removed from
      copy_to. finished is a pipe; when data comes from the read end, or when
      no more ins are present, the loop finishes."""
      if finished is not None:
          copy_to[finished]= None
  
      # NOTE:
      # os.sendfile (self.dst, self.src, None, 0)
      # OSError: [Errno 22] Invalid argument
      # and splice() is not available
      # so, copy by hand
      selector = DefaultSelector ()
      for src in copy_to.keys ():
          if (     not isinstance (src, int)
                  and (   getattr (src, 'fileno', None) is None
                      or not isinstance (src.fileno(), int)) ):
              logger.debug ('type mismatch: %s', src)
          else:
              logger.debug ("registering %s for read", src)
              # if finished is also one of the srcs, then register() complains
              try:
                  selector.register (src, EVENT_READ)
              except KeyError:
                  pass
  
      def close_file (f):
          if f in copy_to:
              del copy_to[f]
  
          try:
              selector.unregister (i)
          except KeyError:
              pass
  
          close (f)
  
      while len (copy_to)>0:
          logger.debug (copy_to)
  
          events= selector.select ()
          for key, _ in events:
              logger.debug ("%s is ready to read", key)
              i= key.fileobj
  
              # for error in e:
              #     logger.debug ('%s error')
                  # TODO: what?
  
              o= copy_to[i]
  
              try:
                  data= read (i, buf_len)
                  logger.debug2 ('%s -> %s: %s', i, o, data)
  
              # ValueError: read of closed file
              except (OSError, ValueError) as e:
                  logger.debug ('stopping copying for %s', i)
                  logger.debug (traceback.format_exc ())
                  close_file (i)
                  break
              else:
                  if len (data)==0:
                      logger.debug ('stopping copying for %s, no more data', i)
                      close_file (i)
  
                      if finished is not None and i==finished:
                          logger.debug ('finishing')
                          # quite a hack :)
                          copy_to= {}
  
                          break
                  else:
                      write (o, data)
  
      selector.close ()
      logger.debug ('over and out')