unix/poll.c
Go to the documentation of this file.
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 #include <errno.h>
28 
29 
30 static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
32  int pevents;
33 
34  handle = container_of(w, uv_poll_t, io_watcher);
35 
36  /*
37  * As documented in the kernel source fs/kernfs/file.c #780
38  * poll will return POLLERR|POLLPRI in case of sysfs
39  * polling. This does not happen in case of out-of-band
40  * TCP messages.
41  *
42  * The above is the case on (at least) FreeBSD and Linux.
43  *
44  * So to properly determine a POLLPRI or a POLLERR we need
45  * to check for both.
46  */
47  if ((events & POLLERR) && !(events & UV__POLLPRI)) {
48  uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
50  handle->poll_cb(handle, UV_EBADF, 0);
51  return;
52  }
53 
54  pevents = 0;
55  if (events & POLLIN)
56  pevents |= UV_READABLE;
57  if (events & UV__POLLPRI)
58  pevents |= UV_PRIORITIZED;
59  if (events & POLLOUT)
60  pevents |= UV_WRITABLE;
61  if (events & UV__POLLRDHUP)
62  pevents |= UV_DISCONNECT;
63 
64  handle->poll_cb(handle, 0, pevents);
65 }
66 
67 
69  int err;
70 
71  if (uv__fd_exists(loop, fd))
72  return UV_EEXIST;
73 
74  err = uv__io_check_fd(loop, fd);
75  if (err)
76  return err;
77 
78  /* If ioctl(FIONBIO) reports ENOTTY, try fcntl(F_GETFL) + fcntl(F_SETFL).
79  * Workaround for e.g. kqueue fds not supporting ioctls.
80  */
81  err = uv__nonblock(fd, 1);
82  if (err == UV_ENOTTY)
84  err = uv__nonblock_fcntl(fd, 1);
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 
98  return uv_poll_init(loop, handle, socket);
99 }
100 
101 
103  uv__io_stop(handle->loop,
104  &handle->io_watcher,
105  POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
107  uv__platform_invalidate_fd(handle->loop, handle->io_watcher.fd);
108 }
109 
110 
112  assert(!uv__is_closing(handle));
114  return 0;
115 }
116 
117 
119  int events;
120 
121  assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT |
122  UV_PRIORITIZED)) == 0);
123  assert(!uv__is_closing(handle));
124 
126 
127  if (pevents == 0)
128  return 0;
129 
130  events = 0;
131  if (pevents & UV_READABLE)
132  events |= POLLIN;
133  if (pevents & UV_PRIORITIZED)
134  events |= UV__POLLPRI;
135  if (pevents & UV_WRITABLE)
136  events |= POLLOUT;
137  if (pevents & UV_DISCONNECT)
138  events |= UV__POLLRDHUP;
139 
140  uv__io_start(handle->loop, &handle->io_watcher, events);
142  handle->poll_cb = poll_cb;
143 
144  return 0;
145 }
146 
147 
150 }
uv__is_closing
#define uv__is_closing(h)
Definition: uv-common.h:238
async_greeter_server_with_graceful_shutdown.loop
loop
Definition: async_greeter_server_with_graceful_shutdown.py:59
uv__poll_stop
static void uv__poll_stop(uv_poll_t *handle)
Definition: unix/poll.c:102
UV_PRIORITIZED
@ UV_PRIORITIZED
Definition: uv.h:793
UV_WRITABLE
@ UV_WRITABLE
Definition: uv.h:791
error_ref_leak.err
err
Definition: error_ref_leak.py:35
uv_poll_init
int uv_poll_init(uv_loop_t *loop, uv_poll_t *handle, int fd)
Definition: unix/poll.c:68
uv__io_check_fd
int uv__io_check_fd(uv_loop_t *loop, int fd)
Definition: aix.c:114
UV__POLLPRI
#define UV__POLLPRI
Definition: third_party/libuv/src/unix/internal.h:126
uv__io_init
void uv__io_init(uv__io_t *w, uv__io_cb cb, int fd)
Definition: unix/core.c:853
container_of
#define container_of(ptr, type, member)
Definition: uv-common.h:57
uv__poll_close
void uv__poll_close(uv_poll_t *handle)
Definition: unix/poll.c:148
uv_poll_cb
void(* uv_poll_cb)(uv_poll_t *handle, int status, int events)
Definition: uv.h:317
uv_os_sock_t
int uv_os_sock_t
Definition: unix.h:127
uv__fd_exists
int uv__fd_exists(uv_loop_t *loop, int fd)
Definition: unix/core.c:953
uv__io_start
void uv__io_start(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: unix/core.c:870
uv__platform_invalidate_fd
void uv__platform_invalidate_fd(uv_loop_t *loop, int fd)
Definition: aix.c:1222
uv_poll_stop
int uv_poll_stop(uv_poll_t *handle)
Definition: unix/poll.c:111
UV_READABLE
@ UV_READABLE
Definition: uv.h:790
poll_cb
static void poll_cb(uv_fs_t *req)
Definition: fs-poll.c:185
uv__handle_init
#define uv__handle_init(loop_, h, type_)
Definition: uv-common.h:284
uv__nonblock_fcntl
int uv__nonblock_fcntl(int fd, int set)
Definition: unix/core.c:596
uv.h
uv__nonblock
#define uv__nonblock
Definition: third_party/libuv/src/unix/internal.h:174
uv__poll_io
static void uv__poll_io(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: unix/poll.c:30
internal.h
UV__POLLRDHUP
#define UV__POLLRDHUP
Definition: third_party/libuv/src/unix/internal.h:120
uv_poll_s
Definition: uv.h:783
uv__nonblock_ioctl
int uv__nonblock_ioctl(int fd, int set)
Definition: unix/core.c:566
uv__io_stop
void uv__io_stop(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: unix/core.c:898
handle
static csh handle
Definition: test_arm_regression.c:16
uv_handle_s
Definition: uv.h:441
UV_DISCONNECT
@ UV_DISCONNECT
Definition: uv.h:792
test_server.socket
socket
Definition: test_server.py:65
uv_loop_s
Definition: uv.h:1767
uv_poll_init_socket
int uv_poll_init_socket(uv_loop_t *loop, uv_poll_t *handle, uv_os_sock_t socket)
Definition: unix/poll.c:96
uv__handle_start
#define uv__handle_start(h)
Definition: uv-common.h:241
uv__io_s
Definition: unix.h:94
uv_poll_start
int uv_poll_start(uv_poll_t *handle, int pevents, uv_poll_cb poll_cb)
Definition: unix/poll.c:118
uv__handle_stop
#define uv__handle_stop(h)
Definition: uv-common.h:249
errno.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:53