diff options
Diffstat (limited to 'include/ruby/internal/intern/select.h')
-rw-r--r-- | include/ruby/internal/intern/select.h | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/include/ruby/internal/intern/select.h b/include/ruby/internal/intern/select.h index 67df6cf7b7..fabc287cd1 100644 --- a/include/ruby/internal/intern/select.h +++ b/include/ruby/internal/intern/select.h @@ -35,9 +35,11 @@ # include "ruby/internal/intern/select/largesize.h" #elif defined(_WIN32) # include "ruby/internal/intern/select/win32.h" +# /** Does nothing (defined for compatibility). */ # define rb_fd_resize(n, f) ((void)(f)) #else # include "ruby/internal/intern/select/posix.h" +# /** Does nothing (defined for compatibility). */ # define rb_fd_resize(n, f) ((void)(f)) #endif @@ -45,7 +47,39 @@ RBIMPL_SYMBOL_EXPORT_BEGIN() struct timeval; -int rb_thread_fd_select(int, rb_fdset_t *, rb_fdset_t *, rb_fdset_t *, struct timeval *); +/** + * Waits for multiple file descriptors at once. This is basically a wrapper of + * system-provided select() with releasing GVL, to allow other Ruby threads run + * in parallel. + * + * @param[in] nfds Max FD in everything passed, plus one. + * @param[in,out] rfds Set of FDs to wait for reads. + * @param[in,out] wfds Set of FDs to wait for writes. + * @param[in,out] efds Set of FDs to wait for OOBs. + * @param[in,out] timeout Max blocking duration. + * @retval -1 Failed, errno set. + * @retval 0 Timeout exceeded. + * @retval otherwise Total number of file descriptors returned. + * @post `rfds` contains readable FDs. + * @post `wfds` contains writable FDs. + * @post `efds` contains exceptional FDs. + * @post `timeout` is the time left. + * @note All pointers are allowed to be null pointers. + * + * Although backend threads can run in parallel of this function, touching a + * file descriptor from multiple threads could be problematic. For instance + * what happens when a thread closes a file descriptor that is selected by + * someone else, vastly varies among operating systems. You would better avoid + * touching an fd from more than one threads. + * + * @internal + * + * Although any file descriptors are possible here, it makes completely no + * sense to pass a descriptor that is not `O_NONBLOCK`. If you want to know + * the reason for this limitatuon in detail, you might find this thread super + * interesting: https://lkml.org/lkml/2004/10/6/117 + */ +int rb_thread_fd_select(int nfds, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout); RBIMPL_SYMBOL_EXPORT_END() |