code: def event_gen(
              self, timeout_s=None, yield_nones=True, filter_predicate=None,
              terminal_events=_DEFAULT_TERMINAL_EVENTS):
          
  
          # We will either return due to the optional filter or because of a
          # timeout. The former will always set this. The latter will never set
          # this.
          self.__last_success_return = None
  
          last_hit_s = time.time()
          while True:
              block_duration_s = self.__get_block_duration()
  
              # Poll, but manage signal-related errors.
  
              try:
                  events = self.__epoll.poll(block_duration_s)
              except IOError as e:
                  if e.errno != EINTR:
                      raise
  
                  if timeout_s is not None:
                      time_since_event_s = time.time() - last_hit_s
                      if time_since_event_s > timeout_s:
                          break
  
                  continue
  
              # Process events.
  
              for fd, event_type in events:
                  # (fd) looks to always match the inotify FD.
  
                  names = self._get_event_names(event_type)
                  _LOGGER.debug("Events received from epoll: {}".format(names))
  
                  for (header, type_names, path, filename) \
                          in self._handle_inotify_event(fd):
                      last_hit_s = time.time()
  
                      e = (header, type_names, path, filename)
                      for type_name in type_names:
                          if filter_predicate is not None and \
                             filter_predicate(type_name, e) is False:
                               self.__last_success_return = (type_name, e)
                               return
                          elif type_name in terminal_events:
                              raise TerminalEventException(type_name, e)
  
                      yield e
  
              if timeout_s is not None:
                  time_since_event_s = time.time() - last_hit_s
                  if time_since_event_s > timeout_s:
                      break
  
              if yield_nones is True:
                  yield None
docs: Yield one event after another. If `timeout_s` is provided, we'll
          break when no event is received for that many seconds.