summaryrefslogtreecommitdiff
path: root/include/ruby/internal/intern/select.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/ruby/internal/intern/select.h')
-rw-r--r--include/ruby/internal/intern/select.h36
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()