docs: def __run_blast_select_loop(input_file, popens, fields):
      '''
      Run the select(2) loop to handle blast I/O to the given set of Popen
      objects.
  
      Yields records back that have been read from blast processes.
      '''
  
      def make_nonblocking(f):
          fl = fcntl.fcntl(f.fileno(), fcntl.F_GETFL)
          fl |= os.O_NONBLOCK
          fcntl.fcntl(f.fileno(), fcntl.F_SETFL, fl)
  
      rfds = set()
      wfds = set()
      fd_map = {}
  
      for p in popens:
          make_nonblocking(p.stdout)
          rfds.add(p.stdout.fileno())
          fd_map[p.stdout.fileno()] = {
              'popen': p,
              'query_buffer': '',
              'result_buffer': ''}
  
          make_nonblocking(p.stdin)
          wfds.add(p.stdin.fileno())
          fd_map[p.stdin.fileno()] = fd_map[p.stdout.fileno()]
  
      while len(rfds) + len(wfds) > 0:
          # XXX: Should we be tracking excepted file descriptors as well?
          rl, wl, _ = select.select(rfds, wfds, [])
  
          # For each of our readable blast processes, read response
          # records and emit them
          for fd in rl:
              rs = fd_map[fd]['result_buffer']
              rbuf = os.read(fd, select.PIPE_BUF)
  
              # The blast process has finished emitting records. Stop
              # attempting to read from or write to it. If we have
              # excess data in our result_buffer, c'est la vie.
              if rbuf == '':
                  p = fd_map[fd]['popen']
  
                  rfds.remove(p.stdout.fileno())
                  p.stdout.close()
  
                  if not p.stdin.closed:
                      wfds.remove(p.stdin.fileno())
                      p.stdin.close()
                  
                  continue
  
              rs += rbuf
              while True:
                  rec, rs = __read_single_query_result(rs, fields)
                  if rec is None:
                      break
                  yield rec
  
              fd_map[fd]['result_buffer'] = rs
  
          # For each of our writable blast processes, grab a new query
          # sequence and send it off to them.
          for fd in wl:
              qs = fd_map[fd]['query_buffer']
              if not qs:
                  ql = __read_single_fasta_query_lines(input_file)
  
                  # No more input records available. Close the pipe to
                  # signal this to the blast process.
                  if ql is None:
                      p = fd_map[fd]['popen']
  
                      wfds.remove(p.stdin.fileno())
                      p.stdin.close()
  
                      continue
  
                  qs = ''.join(ql)
  
              # XXX: For some reason, despite select(2) indicating that
              #      this file descriptor is writable, writes can fail
              #      with EWOULDBLOCK. Handle this gracefully.
              try:
                  written = os.write(fd, qs)
                  qs = qs[written:]
              except OSError, e:
                  assert e.errno == errno.EWOULDBLOCK
  
              fd_map[fd]['query_buffer'] = qs