Project

General

Profile

Feature #17059

Updated by dsh0416 (Delton Ding) over 3 years ago

Current Ruby's `IO.select` method calls POSIX `select` API directly. With the new non-blocking scheduler, this may be the bottleneck of the I/O scheduling. For keeping the backward compatibilty of the current `IO.select` methods, a proposal may be to create a "duck" `select` which uses the `epoll_wait` as the backend. 

 One tricky part is that the `fd_set` described in POSIX is write-only, which means it is impossible to iterate for generating the `epoll_event` argument for `epoll_wait`. But similar to the large-size select situation, we could define our own `rb_fdset_t` struct in this case, and implement the following APIs. 

 ``` 
 void rb_fd_init(rb_fdset_t *); 
 void rb_fd_term(rb_fdset_t *); 
 void rb_fd_zero(rb_fdset_t *); 
 void rb_fd_set(int, rb_fdset_t *); 
 void rb_fd_clr(int, rb_fdset_t *); 
 int rb_fd_isset(int, const rb_fdset_t *); 
 void rb_fd_copy(rb_fdset_t *, const fd_set *, int); 
 void rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src); 
 int rb_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *); 
 ``` 

 TODO: 
 1. Implement the fd_set with dynamic allocated fds. 
 2. Implement the epoll with select API. 
 3. Edit io.c to use the customized fd_set struct. 

 I'm trying to work on a branch for this. Any suggestions for this?

Back