code: def _handle_stdin_event(self, fd, events):
          
  
          assert fd == self.fd_stdin
  
          if events & self.ioloop.ERROR:
              # An error at the end is expected since tornado maps HUP to ERROR
              logger.debug('Error on stdin')
              # ensure pipe is closed
              if not self.process.stdin.closed:
                  self.process.stdin.close()
              # remove handler
              self.ioloop.remove_handler(self.fd_stdin)
              # if all fds are closed, we can finish
              return self._graceful_finish()
  
          # got data ready
          logger.debug('stdin ready for write')
          if self.process_input_buffer:
              count = os.write(fd, self.process_input_buffer)
              logger.debug('Wrote first %d bytes of %d total', count, len(self.process_input_buffer))
              self.process_input_buffer = self.process_input_buffer[count:]
  
          if not self.process_input_buffer:
              # consumed everything in the buffer
              if self.got_request:
                  # we got the request and wrote everything to the process
                  # this means we can close stdin and stop handling events
                  # for it
                  logger.debug('Got complete request, closing stdin')
                  self.process.stdin.close()
                  self.ioloop.remove_handler(fd)
              else:
                  # There is more data bound to come from the client
                  # so just disable write events for the moment until 
                  # we got more to write
                  logger.debug('Not interested in write events on stdin anymore')
                  self.ioloop.update_handler(fd, self.ioloop.ERROR)
docs: Eventhandler for stdin