Mercurial
comparison third_party/libuv/src/unix/poll.c @ 160:948de3f54cea
[ThirdParty] Added libuv
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 14 Jan 2026 19:39:52 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 159:05cf9467a1c3 | 160:948de3f54cea |
|---|---|
| 1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. | |
| 2 * | |
| 3 * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 4 * of this software and associated documentation files (the "Software"), to | |
| 5 * deal in the Software without restriction, including without limitation the | |
| 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |
| 7 * sell copies of the Software, and to permit persons to whom the Software is | |
| 8 * furnished to do so, subject to the following conditions: | |
| 9 * | |
| 10 * The above copyright notice and this permission notice shall be included in | |
| 11 * all copies or substantial portions of the Software. | |
| 12 * | |
| 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
| 19 * IN THE SOFTWARE. | |
| 20 */ | |
| 21 | |
| 22 #include "uv.h" | |
| 23 #include "internal.h" | |
| 24 | |
| 25 #include <unistd.h> | |
| 26 #include <assert.h> | |
| 27 | |
| 28 | |
| 29 static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { | |
| 30 uv_poll_t* handle; | |
| 31 int pevents; | |
| 32 | |
| 33 handle = container_of(w, uv_poll_t, io_watcher); | |
| 34 | |
| 35 /* | |
| 36 * As documented in the kernel source fs/kernfs/file.c #780 | |
| 37 * poll will return POLLERR|POLLPRI in case of sysfs | |
| 38 * polling. This does not happen in case of out-of-band | |
| 39 * TCP messages. | |
| 40 * | |
| 41 * The above is the case on (at least) FreeBSD and Linux. | |
| 42 * | |
| 43 * So to properly determine a POLLPRI or a POLLERR we need | |
| 44 * to check for both. | |
| 45 */ | |
| 46 if ((events & POLLERR) && !(events & UV__POLLPRI)) { | |
| 47 uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); | |
| 48 uv__handle_stop(handle); | |
| 49 handle->poll_cb(handle, UV_EBADF, 0); | |
| 50 return; | |
| 51 } | |
| 52 | |
| 53 pevents = 0; | |
| 54 if (events & POLLIN) | |
| 55 pevents |= UV_READABLE; | |
| 56 if (events & UV__POLLPRI) | |
| 57 pevents |= UV_PRIORITIZED; | |
| 58 if (events & POLLOUT) | |
| 59 pevents |= UV_WRITABLE; | |
| 60 if (events & UV__POLLRDHUP) | |
| 61 pevents |= UV_DISCONNECT; | |
| 62 | |
| 63 handle->poll_cb(handle, 0, pevents); | |
| 64 } | |
| 65 | |
| 66 | |
| 67 int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { | |
| 68 int err; | |
| 69 | |
| 70 if (uv__fd_exists(loop, fd)) | |
| 71 return UV_EEXIST; | |
| 72 | |
| 73 err = uv__io_check_fd(loop, fd); | |
| 74 if (err) | |
| 75 return err; | |
| 76 | |
| 77 /* If ioctl(FIONBIO) reports ENOTTY, try fcntl(F_GETFL) + fcntl(F_SETFL). | |
| 78 * Workaround for e.g. kqueue fds not supporting ioctls. | |
| 79 */ | |
| 80 err = uv__nonblock(fd, 1); | |
| 81 #if UV__NONBLOCK_IS_IOCTL | |
| 82 if (err == UV_ENOTTY) | |
| 83 err = uv__nonblock_fcntl(fd, 1); | |
| 84 #endif | |
| 85 | |
| 86 if (err) | |
| 87 return err; | |
| 88 | |
| 89 uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL); | |
| 90 uv__io_init(&handle->io_watcher, uv__poll_io, fd); | |
| 91 handle->poll_cb = NULL; | |
| 92 return 0; | |
| 93 } | |
| 94 | |
| 95 | |
| 96 int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, | |
| 97 uv_os_sock_t socket) { | |
| 98 return uv_poll_init(loop, handle, socket); | |
| 99 } | |
| 100 | |
| 101 | |
| 102 static void uv__poll_stop(uv_poll_t* handle) { | |
| 103 uv__io_stop(handle->loop, | |
| 104 &handle->io_watcher, | |
| 105 POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); | |
| 106 uv__handle_stop(handle); | |
| 107 uv__platform_invalidate_fd(handle->loop, handle->io_watcher.fd); | |
| 108 } | |
| 109 | |
| 110 | |
| 111 int uv_poll_stop(uv_poll_t* handle) { | |
| 112 assert(!uv__is_closing(handle)); | |
| 113 uv__poll_stop(handle); | |
| 114 return 0; | |
| 115 } | |
| 116 | |
| 117 | |
| 118 int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) { | |
| 119 uv__io_t** watchers; | |
| 120 uv__io_t* w; | |
| 121 int events; | |
| 122 | |
| 123 assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT | | |
| 124 UV_PRIORITIZED)) == 0); | |
| 125 assert(!uv__is_closing(handle)); | |
| 126 | |
| 127 watchers = handle->loop->watchers; | |
| 128 w = &handle->io_watcher; | |
| 129 | |
| 130 if (uv__fd_exists(handle->loop, w->fd)) | |
| 131 if (watchers[w->fd] != w) | |
| 132 return UV_EEXIST; | |
| 133 | |
| 134 uv__poll_stop(handle); | |
| 135 | |
| 136 if (pevents == 0) | |
| 137 return 0; | |
| 138 | |
| 139 events = 0; | |
| 140 if (pevents & UV_READABLE) | |
| 141 events |= POLLIN; | |
| 142 if (pevents & UV_PRIORITIZED) | |
| 143 events |= UV__POLLPRI; | |
| 144 if (pevents & UV_WRITABLE) | |
| 145 events |= POLLOUT; | |
| 146 if (pevents & UV_DISCONNECT) | |
| 147 events |= UV__POLLRDHUP; | |
| 148 | |
| 149 uv__io_start(handle->loop, &handle->io_watcher, events); | |
| 150 uv__handle_start(handle); | |
| 151 handle->poll_cb = poll_cb; | |
| 152 | |
| 153 return 0; | |
| 154 } | |
| 155 | |
| 156 | |
| 157 void uv__poll_close(uv_poll_t* handle) { | |
| 158 uv__poll_stop(handle); | |
| 159 } |