From 515f8d09671812ce08ccc20de483420ab81e417b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= Date: Fri, 19 Feb 2021 14:34:44 +0900 Subject: include/ruby/internal/intern/select/win32.h: add doxygen Must not be a bad idea to improve documents. [ci skip] --- include/ruby/internal/intern/select/win32.h | 151 ++++++++++++++++++++++++++-- 1 file changed, 143 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/ruby/internal/intern/select/win32.h b/include/ruby/internal/intern/select/win32.h index 668f896cc7..edaf7a8523 100644 --- a/include/ruby/internal/intern/select/win32.h +++ b/include/ruby/internal/intern/select/win32.h @@ -41,21 +41,83 @@ RBIMPL_SYMBOL_EXPORT_BEGIN() struct timeval; +/** + * The data structure which wraps the fd_set bitmap used by select(2). This + * allows Ruby to use FD sets larger than that allowed by historic limitations + * on modern platforms. + */ typedef struct { - int capa; - fd_set *fdset; + int capa; /**< Maximum allowed number of FDs. */ + fd_set *fdset; /**< File descriptors buffer. */ } rb_fdset_t; -void rb_fd_init(rb_fdset_t *); -void rb_fd_term(rb_fdset_t *); -void rb_fd_set(int, rb_fdset_t *); -void rb_w32_fd_copy(rb_fdset_t *, const fd_set *, int); +RBIMPL_ATTR_NONNULL(()) +/** + * (Re-)initialises a fdset. One must be initialised before other `rb_fd_*` + * operations. Analogous to calling `malloc(3)` to allocate an `fd_set`. + * + * @param[out] f An fdset to squash. + * @post `f` holds no file descriptors. + * + * @internal + * + * Can't this leak memory if the same `f` is passed twice...? + */ +void rb_fd_init(rb_fdset_t *f); + +RBIMPL_ATTR_NONNULL(()) +/** + * Destroys the ::rb_fdset_t, releasing any memory and resources it used. It + * must be reinitialised using rb_fd_init() before future use. Analogous to + * calling `free(3)` to release memory for an `fd_set`. + * + * @param[out] f An fdset to squash. + * @post `f` holds no file descriptors. + */ +void rb_fd_term(rb_fdset_t *f); + +RBIMPL_ATTR_NONNULL(()) +/** + * Sets an fd to a fdset. + * + * @param[in] fd A file descriptor. + * @param[out] f Target fdset. + * @post `f` holds `fd`. + */ +void rb_fd_set(int fd, rb_fdset_t *f); + +RBIMPL_ATTR_NONNULL(()) +/** + * Destructively overwrites an fdset with another. + * + * @param[out] dst Target fdset. + * @param[in] src Source fdset. + * @param[in] max Maximum number of file descriptors to copy. + * @post `dst` is a copy of `src`. + */ +void rb_w32_fd_copy(rb_fdset_t *dst, const fd_set *src, int max); + +RBIMPL_ATTR_NONNULL(()) +/** + * Identical to rb_w32_fd_copy(), except it copies unlimited number of file + * descriptors. + * + * @param[out] dst Target fdset. + * @param[in] src Source fdset. + * @post `dst` is a copy of `src`. + */ void rb_w32_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src); RBIMPL_SYMBOL_EXPORT_END() RBIMPL_ATTR_NONNULL(()) RBIMPL_ATTR_NOALIAS() +/** + * Wipes out the current set of FDs. + * + * @param[out] f The fdset to clear. + * @post `f` has no FDs. + */ static inline void rb_fd_zero(rb_fdset_t *f) { @@ -63,6 +125,13 @@ rb_fd_zero(rb_fdset_t *f) } RBIMPL_ATTR_NONNULL(()) +/** + * Releases a specific FD from the given fdset. + * + * @param[in] n Target FD. + * @param[out] f The fdset that holds `n`. + * @post `f` doesn't hold n. + */ static inline void rb_fd_clr(int n, rb_fdset_t *f) { @@ -70,6 +139,14 @@ rb_fd_clr(int n, rb_fdset_t *f) } RBIMPL_ATTR_NONNULL(()) +/** + * Queries if the given FD is in the given set. + * + * @param[in] n Target FD. + * @param[in] f The fdset to scan. + * @retval 1 Yes there is. + * @retval 0 No there isn't. + */ static inline int rb_fd_isset(int n, rb_fdset_t *f) { @@ -77,6 +154,14 @@ rb_fd_isset(int n, rb_fdset_t *f) } RBIMPL_ATTR_NONNULL(()) +/** + * Destructively overwrites an fdset with another. + * + * @param[out] dst Target fdset. + * @param[in] src Source fdset. + * @param[in] n Maximum number of file descriptors to copy. + * @post `dst` is a copy of `src`. + */ static inline void rb_fd_copy(rb_fdset_t *dst, const fd_set *src, int n) { @@ -84,12 +169,45 @@ rb_fd_copy(rb_fdset_t *dst, const fd_set *src, int n) } RBIMPL_ATTR_NONNULL(()) +/** + * Identical to rb_fd_copy(), except it copies unlimited number of file + * descriptors. + * + * @param[out] dst Target fdset. + * @param[in] src Source fdset. + * @post `dst` is a copy of `src`. + */ static inline void rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src) { rb_w32_fd_dup(dst, src); } +/** + * Waits for multiple file descriptors at once. + * + * @param[in] n 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. + * + * @internal + * + * This can wait for `SOCKET` and `HANDLE` at once. In order to achieve that + * property we heavily touch the internals of MSVCRT. We `CreateFile` a + * `"NUL"` alongside of a socket and directly manipulate its `struct ioinfo`. + * This is of course a very dirty hack. If we could design the API today we + * could use `CancellIoEx`. But we are older than that Win32 API. + */ static inline int rb_fd_select(int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct timeval *timeout) { @@ -103,7 +221,18 @@ rb_fd_select(int n, rb_fdset_t *rfds, rb_fdset_t *wfds, rb_fdset_t *efds, struct RBIMPL_ATTR_NONNULL(()) RBIMPL_ATTR_PURE() -/* :TODO: can this function be __attribute__((returns_nonnull)) or not? */ +/** + * Raw pointer to `fd_set`. + * + * @param[in] f Target fdset. + * @retval NULL `f` is already terminated by rb_fd_term(). + * @retval otherwise Underlying fd_set. + * + * @internal + * + * Extension library must not touch raw pointers. It was a bad idea to let + * them use it. + */ static inline fd_set * rb_fd_ptr(const rb_fdset_t *f) { @@ -111,7 +240,13 @@ rb_fd_ptr(const rb_fdset_t *f) } RBIMPL_ATTR_NONNULL(()) -RBIMPL_ATTR_PURE() +RBIMPL_ATTR_PURE_UNLESS_DEBUG() +/** + * It seems this function has no use. Maybe just remove? + * + * @param[in] f A set. + * @return Number of file descriptors stored. + */ static inline int rb_fd_max(const rb_fdset_t *f) { -- cgit v1.2.3