Skip to content

Commit b788c5e

Browse files
committed
uv: Upgrade to 778144f0
joyent/libuv@778144f
1 parent 7144be7 commit b788c5e

23 files changed

+982
-99
lines changed

deps/uv/include/uv-private/uv-darwin.h

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
ev_io event_watcher; \
4242
int fflags; \
4343
int fd; \
44+
char* realpath; \
45+
int realpath_len; \
46+
int cf_flags; \
4447
void* cf_eventstream; \
4548
uv_async_t* cf_cb; \
4649
ngx_queue_t cf_events; \

deps/uv/include/uv-private/uv-unix.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,7 @@ typedef struct {
185185
int fd; \
186186
UV_STREAM_PRIVATE_PLATFORM_FIELDS \
187187

188-
#define UV_TCP_PRIVATE_FIELDS \
189-
uv_idle_t* idle_handle; /* for UV_TCP_SINGLE_ACCEPT handles */ \
188+
#define UV_TCP_PRIVATE_FIELDS /* empty */
190189

191190
#define UV_UDP_PRIVATE_FIELDS \
192191
int fd; \

deps/uv/include/uv.h

+19-2
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,11 @@ struct uv_tcp_s {
599599

600600
UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
601601

602+
/*
603+
* Opens an existing file descriptor or SOCKET as a tcp handle.
604+
*/
605+
UV_EXTERN int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock);
606+
602607
/* Enable/disable Nagle's algorithm. */
603608
UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
604609

@@ -703,6 +708,11 @@ struct uv_udp_send_s {
703708
*/
704709
UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
705710

711+
/*
712+
* Opens an existing file descriptor or SOCKET as a udp handle.
713+
*/
714+
UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
715+
706716
/*
707717
* Bind to a IPv4 address and port.
708718
*
@@ -940,7 +950,7 @@ UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc);
940950
/*
941951
* Opens an existing file descriptor or HANDLE as a pipe.
942952
*/
943-
UV_EXTERN void uv_pipe_open(uv_pipe_t*, uv_file file);
953+
UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file);
944954

945955
UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
946956

@@ -1665,7 +1675,14 @@ enum uv_fs_event_flags {
16651675
* regular interval.
16661676
* This flag is currently not implemented yet on any backend.
16671677
*/
1668-
UV_FS_EVENT_STAT = 2
1678+
UV_FS_EVENT_STAT = 2,
1679+
1680+
/*
1681+
* By default, event watcher, when watching directory, is not registering
1682+
* (is ignoring) changes in it's subdirectories.
1683+
* This flag will override this behaviour on platforms that support it.
1684+
*/
1685+
UV_FS_EVENT_RECURSIVE = 3
16691686
};
16701687

16711688

deps/uv/src/unix/fsevents.c

+52-4
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,13 @@ void uv__fsevents_cb(uv_async_t* cb, int status) {
6666
handle = cb->data;
6767

6868
UV__FSEVENTS_WALK(handle, {
69-
if (handle->fd != -1)
69+
if (handle->fd != -1) {
70+
#ifdef MAC_OS_X_VERSION_10_7
7071
handle->cb(handle, event->path, event->events, 0);
72+
#else
73+
handle->cb(handle, NULL, event->events, 0);
74+
#endif /* MAC_OS_X_VERSION_10_7 */
75+
}
7176
})
7277

7378
if ((handle->flags & (UV_CLOSING | UV_CLOSED)) == 0 && handle->fd == -1)
@@ -84,6 +89,8 @@ void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
8489
size_t i;
8590
int len;
8691
char** paths;
92+
char* path;
93+
char* pos;
8794
uv_fs_event_t* handle;
8895
uv__fsevents_event_t* event;
8996
ngx_queue_t add_list;
@@ -99,17 +106,50 @@ void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
99106
kFSEventStreamEventFlagEventIdsWrapped |
100107
kFSEventStreamEventFlagHistoryDone |
101108
kFSEventStreamEventFlagMount |
102-
kFSEventStreamEventFlagUnmount)) {
109+
kFSEventStreamEventFlagUnmount |
110+
kFSEventStreamEventFlagRootChanged)) {
103111
continue;
104112
}
105113

106114
/* TODO: Report errors */
107-
len = strlen(paths[i]);
115+
path = paths[i];
116+
len = strlen(path);
117+
118+
/* Remove absolute path prefix */
119+
if (strstr(path, handle->realpath) == path) {
120+
path += handle->realpath_len;
121+
len -= handle->realpath_len;
122+
123+
/* Skip back slash */
124+
if (*path != 0) {
125+
path++;
126+
len--;
127+
}
128+
}
129+
130+
#ifdef MAC_OS_X_VERSION_10_7
131+
/* Ignore events with path equal to directory itself */
132+
if (len == 0)
133+
continue;
134+
#endif /* MAC_OS_X_VERSION_10_7 */
135+
136+
/* Do not emit events from subdirectories (without option set) */
137+
pos = strchr(path, '/');
138+
if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 &&
139+
pos != NULL &&
140+
pos != path + 1)
141+
continue;
142+
143+
#ifndef MAC_OS_X_VERSION_10_7
144+
path = "";
145+
len = 0;
146+
#endif /* MAC_OS_X_VERSION_10_7 */
147+
108148
event = malloc(sizeof(*event) + len);
109149
if (event == NULL)
110150
break;
111151

112-
memcpy(event->path, paths[i], len + 1);
152+
memcpy(event->path, path, len + 1);
113153

114154
if (eventFlags[i] & kFSEventStreamEventFlagItemModified)
115155
event->events = UV_CHANGE;
@@ -153,6 +193,11 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
153193
ctx.release = NULL;
154194
ctx.copyDescription = NULL;
155195

196+
/* Get absolute path to file */
197+
handle->realpath = realpath(handle->filename, NULL);
198+
if (handle->realpath != NULL)
199+
handle->realpath_len = strlen(handle->realpath);
200+
156201
/* Initialize paths array */
157202
path = CFStringCreateWithCString(NULL,
158203
handle->filename,
@@ -220,6 +265,9 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
220265

221266
uv_mutex_destroy(&handle->cf_mutex);
222267
uv_sem_destroy(&handle->cf_sem);
268+
free(handle->realpath);
269+
handle->realpath = NULL;
270+
handle->realpath_len = 0;
223271

224272
return 0;
225273
}

deps/uv/src/unix/kqueue.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,6 @@ int uv_fs_event_init(uv_loop_t* loop,
9393
struct stat statbuf;
9494
#endif /* defined(__APPLE__) */
9595

96-
/* We don't support any flags yet. */
97-
assert(!flags);
98-
9996
/* TODO open asynchronously - but how do we report back errors? */
10097
if ((fd = open(filename, O_RDONLY)) == -1) {
10198
uv__set_sys_error(loop, errno);
@@ -112,6 +109,9 @@ int uv_fs_event_init(uv_loop_t* loop,
112109
#if defined(__APPLE__)
113110
/* Nullify field to perform checks later */
114111
handle->cf_eventstream = NULL;
112+
handle->realpath = NULL;
113+
handle->realpath_len = 0;
114+
handle->cf_flags = flags;
115115

116116
if (fstat(fd, &statbuf))
117117
goto fallback;

deps/uv/src/unix/linux/inotify.c

-3
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,6 @@ int uv_fs_event_init(uv_loop_t* loop,
176176
int events;
177177
int wd;
178178

179-
/* We don't support any flags yet. */
180-
assert(!flags);
181-
182179
if (init_inotify(loop)) return -1;
183180

184181
events = UV__IN_ATTRIB

deps/uv/src/unix/pipe.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,10 @@ void uv__pipe_close(uv_pipe_t* handle) {
156156
}
157157

158158

159-
void uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
160-
uv__stream_open((uv_stream_t*)handle,
161-
fd,
162-
UV_STREAM_READABLE | UV_STREAM_WRITABLE);
159+
int uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
160+
return uv__stream_open((uv_stream_t*)handle,
161+
fd,
162+
UV_STREAM_READABLE | UV_STREAM_WRITABLE);
163163
}
164164

165165

deps/uv/src/unix/stream.c

+7-40
Original file line numberDiff line numberDiff line change
@@ -386,16 +386,6 @@ void uv__stream_destroy(uv_stream_t* stream) {
386386
}
387387

388388

389-
static void uv__next_accept(uv_idle_t* idle, int status) {
390-
uv_stream_t* stream = idle->data;
391-
392-
uv_idle_stop(idle);
393-
394-
if (stream->accepted_fd == -1)
395-
uv__io_start(stream->loop, &stream->read_watcher);
396-
}
397-
398-
399389
/* Implements a best effort approach to mitigating accept() EMFILE errors.
400390
* We have a spare file descriptor stashed away that we close to get below
401391
* the EMFILE limit. Next, we accept all pending connections and close them
@@ -497,40 +487,17 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, int events) {
497487
stream->accepted_fd = fd;
498488
stream->connection_cb(stream, 0);
499489

500-
if (stream->accepted_fd != -1 ||
501-
(stream->type == UV_TCP && stream->flags == UV_TCP_SINGLE_ACCEPT)) {
490+
if (stream->accepted_fd != -1) {
502491
/* The user hasn't yet accepted called uv_accept() */
503492
uv__io_stop(loop, &stream->read_watcher);
504-
break;
493+
return;
505494
}
506-
}
507495

508-
if (stream->fd != -1 &&
509-
stream->accepted_fd == -1 &&
510-
(stream->type == UV_TCP && stream->flags == UV_TCP_SINGLE_ACCEPT))
511-
{
512-
/* Defer the next accept() syscall to the next event loop tick.
513-
* This lets us guarantee fair load balancing in in multi-process setups.
514-
* The problem is as follows:
515-
*
516-
* 1. Multiple processes listen on the same socket.
517-
* 2. The OS scheduler commonly gives preference to one process to
518-
* avoid task switches.
519-
* 3. That process therefore accepts most of the new connections,
520-
* leading to a (sometimes very) unevenly distributed load.
521-
*
522-
* Here is how we mitigate this issue:
523-
*
524-
* 1. Accept a connection.
525-
* 2. Start an idle watcher.
526-
* 3. Don't accept new connections until the idle callback fires.
527-
*
528-
* This works because the callback only fires when there have been
529-
* no recent events, i.e. none of the watched file descriptors have
530-
* recently been readable or writable.
531-
*/
532-
uv_tcp_t* tcp = (uv_tcp_t*) stream;
533-
uv_idle_start(tcp->idle_handle, uv__next_accept);
496+
if (stream->type == UV_TCP && (stream->flags & UV_TCP_SINGLE_ACCEPT)) {
497+
/* Give other processes a chance to accept connections. */
498+
struct timespec timeout = { 0, 1 };
499+
nanosleep(&timeout, NULL);
500+
}
534501
}
535502
}
536503

deps/uv/src/unix/sunos.c

-2
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,6 @@ int uv_fs_event_init(uv_loop_t* loop,
196196
int portfd;
197197
int first_run = 0;
198198

199-
/* We don't support any flags yet. */
200-
assert(!flags);
201199
if (loop->fs_fd == -1) {
202200
if ((portfd = port_create()) == -1) {
203201
uv__set_sys_error(loop, errno);

deps/uv/src/unix/tcp.c

+9-17
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030

3131
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) {
3232
uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP);
33-
tcp->idle_handle = NULL;
3433
return 0;
3534
}
3635

@@ -153,6 +152,13 @@ int uv__tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
153152
}
154153

155154

155+
int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
156+
return uv__stream_open((uv_stream_t*)handle,
157+
sock,
158+
UV_STREAM_READABLE | UV_STREAM_WRITABLE);
159+
}
160+
161+
156162
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
157163
int* namelen) {
158164
socklen_t socklen;
@@ -238,20 +244,9 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
238244
single_accept = (val == NULL) || (atoi(val) != 0); /* on by default */
239245
}
240246

241-
if (!single_accept)
242-
goto no_single_accept;
243-
244-
tcp->idle_handle = malloc(sizeof(*tcp->idle_handle));
245-
if (tcp->idle_handle == NULL)
246-
return uv__set_sys_error(tcp->loop, ENOMEM);
247+
if (single_accept)
248+
tcp->flags |= UV_TCP_SINGLE_ACCEPT;
247249

248-
if (uv_idle_init(tcp->loop, tcp->idle_handle))
249-
abort();
250-
tcp->idle_handle->flags |= UV__HANDLE_INTERNAL;
251-
252-
tcp->flags |= UV_TCP_SINGLE_ACCEPT;
253-
254-
no_single_accept:
255250
if (maybe_new_socket(tcp, AF_INET, UV_STREAM_READABLE))
256251
return -1;
257252

@@ -390,8 +385,5 @@ int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
390385

391386

392387
void uv__tcp_close(uv_tcp_t* handle) {
393-
if (handle->idle_handle)
394-
uv_close((uv_handle_t*)handle->idle_handle, (uv_close_cb)free);
395-
396388
uv__stream_close((uv_stream_t*)handle);
397389
}

0 commit comments

Comments
 (0)