Skip to content

Commit 731adac

Browse files
indutnybnoordhuis
authored andcommitted
unix: use select() for specific fds on OS X
kqueue(2) on osx doesn't work (emits EINVAL error) with specific fds (i.e. /dev/tty, /dev/null, etc). When given such descriptors - start select(2) watcher thread that will emit io events.
1 parent 52c8a86 commit 731adac

File tree

9 files changed

+360
-41
lines changed

9 files changed

+360
-41
lines changed

include/uv-private/uv-darwin.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,7 @@
4949
uv_sem_t cf_sem; \
5050
uv_mutex_t cf_mutex; \
5151

52+
#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \
53+
void* select; \
54+
5255
#endif /* UV_DARWIN_H */

include/uv-private/uv-unix.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ struct uv__work {
9090
# define UV_PLATFORM_FS_EVENT_FIELDS /* empty */
9191
#endif
9292

93+
#ifndef UV_STREAM_PRIVATE_PLATFORM_FIELDS
94+
# define UV_STREAM_PRIVATE_PLATFORM_FIELDS /* empty */
95+
#endif
96+
9397
/* Note: May be cast to struct iovec. See writev(2). */
9498
typedef struct {
9599
char* base;
@@ -209,6 +213,7 @@ typedef struct {
209213
uv_connection_cb connection_cb; \
210214
int delayed_error; \
211215
int accepted_fd; \
216+
UV_STREAM_PRIVATE_PLATFORM_FIELDS \
212217

213218
#define UV_TCP_PRIVATE_FIELDS /* empty */
214219

src/unix/async.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ int uv_async_send(uv_async_t* handle) {
8484
r = write(handle->loop->async_pipefd[1], "x", 1);
8585
while (r == -1 && errno == EINTR);
8686

87+
assert(r == -1 || r == 1);
88+
8789
if (r == -1 && errno != EAGAIN && errno != EWOULDBLOCK)
8890
return uv__set_sys_error(handle->loop, errno);
8991

src/unix/internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,13 @@ void uv__timer_close(uv_timer_t* handle);
197197
void uv__udp_close(uv_udp_t* handle);
198198
void uv__udp_finish_close(uv_udp_t* handle);
199199

200+
#if defined(__APPLE__)
201+
int uv___stream_fd(uv_stream_t* handle);
202+
#define uv__stream_fd(handle) (uv___stream_fd((uv_stream_t*) (handle)))
203+
#else
204+
#define uv__stream_fd(handle) ((handle)->io_watcher.fd)
205+
#endif /* defined(__APPLE__) */
206+
200207
#ifdef UV__O_NONBLOCK
201208
# define UV__F_NONBLOCK UV__O_NONBLOCK
202209
#else

src/unix/pipe.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
5757
bound = 0;
5858

5959
/* Already bound? */
60-
if (handle->io_watcher.fd >= 0) {
60+
if (uv__stream_fd(handle) >= 0) {
6161
uv__set_artificial_error(handle->loop, UV_EINVAL);
6262
goto out;
6363
}
@@ -117,13 +117,13 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
117117
saved_errno = errno;
118118
status = -1;
119119

120-
if (handle->io_watcher.fd == -1) {
120+
if (uv__stream_fd(handle) == -1) {
121121
uv__set_artificial_error(handle->loop, UV_EINVAL);
122122
goto out;
123123
}
124-
assert(handle->io_watcher.fd >= 0);
124+
assert(uv__stream_fd(handle) >= 0);
125125

126-
if ((status = listen(handle->io_watcher.fd, backlog)) == -1) {
126+
if ((status = listen(uv__stream_fd(handle), backlog)) == -1) {
127127
uv__set_sys_error(handle->loop, errno);
128128
} else {
129129
handle->connection_cb = cb;
@@ -172,7 +172,7 @@ void uv_pipe_connect(uv_connect_t* req,
172172
int r;
173173

174174
saved_errno = errno;
175-
new_sock = (handle->io_watcher.fd == -1);
175+
new_sock = (uv__stream_fd(handle) == -1);
176176
err = -1;
177177

178178
if (new_sock)
@@ -187,7 +187,8 @@ void uv_pipe_connect(uv_connect_t* req,
187187
* is either there or not.
188188
*/
189189
do {
190-
r = connect(handle->io_watcher.fd, (struct sockaddr*)&saddr, sizeof saddr);
190+
r = connect(uv__stream_fd(handle),
191+
(struct sockaddr*)&saddr, sizeof saddr);
191192
}
192193
while (r == -1 && errno == EINTR);
193194

@@ -196,7 +197,7 @@ void uv_pipe_connect(uv_connect_t* req,
196197

197198
if (new_sock)
198199
if (uv__stream_open((uv_stream_t*)handle,
199-
handle->io_watcher.fd,
200+
uv__stream_fd(handle),
200201
UV_STREAM_READABLE | UV_STREAM_WRITABLE))
201202
goto out;
202203

@@ -233,7 +234,7 @@ static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
233234

234235
assert(pipe->type == UV_NAMED_PIPE);
235236

236-
sockfd = uv__accept(pipe->io_watcher.fd);
237+
sockfd = uv__accept(uv__stream_fd(pipe));
237238
if (sockfd == -1) {
238239
if (errno != EAGAIN && errno != EWOULDBLOCK) {
239240
uv__set_sys_error(pipe->loop, errno);

src/unix/process.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
204204
if (container->flags & UV_INHERIT_FD) {
205205
fd = container->data.fd;
206206
} else {
207-
fd = container->data.stream->io_watcher.fd;
207+
fd = uv__stream_fd(container->data.stream);
208208
}
209209

210210
if (fd == -1) {

0 commit comments

Comments
 (0)