ext/iodine/fio.c
/** returns non-zero if events were scheduled, 0 if idle */
returns non-zero if events were scheduled, 0 if idle
returns non - zero if events were scheduled 0 if idle
static size_t fio_poll(void) {
  size_t end = fio_data->capa; 
  size_t start = 0;
  struct pollfd *list = NULL;
  fio_lock(&fio_data->lock);
  while (start < end && fio_data->poll[start].fd == -1)
    ++start;
  while (start < end && fio_data->poll[end - 1].fd == -1)
    --end;
  if (start != end) {
    list = fio_malloc(sizeof(struct pollfd) * end);
    memcpy(list + start, fio_data->poll + start,
           (sizeof(struct pollfd)) * (end - start));
  }
  fio_unlock(&fio_data->lock);
  int timeout = fio_timer_calc_first_interval();
  size_t count = 0;
  if (start == end) {
    fio_throttle_thread((timeout * 1000000UL));
  } else if (poll(list + start, end - start, timeout) == -1) {
    goto finish;
  }
  for (size_t i = start; i < end; ++i) {
    if (list[i].revents) {
      touchfd(i);
      ++count;
      if (list[i].revents & FIO_POLL_WRITE_EVENTS) {
        fio_poll_remove_write(i);
        fio_defer_push_urgent(deferred_on_ready, (void *)fd2uuid(i), NULL);
      }
      if (list[i].revents & FIO_POLL_READ_EVENTS) {
        fio_poll_remove_read(i);
        fio_defer_push_task(deferred_on_data, (void *)fd2uuid(i), NULL);
      }
      if (list[i].revents & (POLLHUP | POLLERR)) {
        fio_poll_remove_fd(i);
        fio_force_close_in_poll(fd2uuid(i));
      }
      if (list[i].revents & POLLNVAL) {
        fio_poll_remove_fd(i);
        fio_lock(&fd_data(i).protocol_lock);
        fio_clear_fd(i, 0);
        fio_unlock(&fd_data(i).protocol_lock);
      }
    }
  }
finish:
  fio_free(list);
  return count;
}
static size_t fio_poll ( void ) { size_t end = fio_data -> capa ; size_t start = 0 ; struct pollfd * list = NULL ; fio_lock ( & fio_data -> lock ) ; while ( start < end && fio_data -> poll [ start ] . fd == -1 ) ++ start ; while ( start < end && fio_data -> poll [ end - 1 ] . fd == -1 ) -- end ; if ( start != end ) { list = fio_malloc ( sizeof ( struct pollfd ) * end ) ; memcpy ( list + start , fio_data -> poll + start , ( sizeof ( struct pollfd ) ) * ( end - start ) ) ; } fio_unlock ( & fio_data -> lock ) ; int timeout = fio_timer_calc_first_interval ( ) ; size_t count = 0 ; if ( start == end ) { fio_throttle_thread ( ( timeout * 1000000UL ) ) ; } else if ( poll ( list + start , end - start , timeout ) == -1 ) { goto finish ; } for ( size_t i = start ; i < end ; ++ i ) { if ( list [ i ] . revents ) { touchfd ( i ) ; ++ count ; if ( list [ i ] . revents & FIO_POLL_WRITE_EVENTS ) { fio_poll_remove_write ( i ) ; fio_defer_push_urgent ( deferred_on_ready , ( void * ) fd2uuid ( i ) , NULL ) ; } if ( list [ i ] . revents & FIO_POLL_READ_EVENTS ) { fio_poll_remove_read ( i ) ; fio_defer_push_task ( deferred_on_data , ( void * ) fd2uuid ( i ) , NULL ) ; } if ( list [ i ] . revents & ( POLLHUP | POLLERR ) ) { fio_poll_remove_fd ( i ) ; fio_force_close_in_poll ( fd2uuid ( i ) ) ; } if ( list [ i ] . revents & POLLNVAL ) { fio_poll_remove_fd ( i ) ; fio_lock ( & fd_data ( i ) . protocol_lock ) ; fio_clear_fd ( i , 0 ) ; fio_unlock ( & fd_data ( i ) . protocol_lock ) ; } } } finish : fio_free ( list ) ; return count ; }
returns non-zero if events were scheduled, 0 if idle
returns non - zero if events were scheduled 0 if idle
/* shrink fd poll range */ // max_protocol_fd might break TLS /* copy poll list for multi-threaded poll */ // FIO_LOG_DEBUG("Poll Write %zu => %p", i, (void *)fd2uuid(i)); // FIO_LOG_DEBUG("Poll Read %zu => %p", i, (void *)fd2uuid(i)); // FIO_LOG_DEBUG("Poll Hangup %zu => %p", i, (void *)fd2uuid(i)); // FIO_LOG_DEBUG("Poll Invalid %zu => %p", i, (void *)fd2uuid(i));