Skip to content

Commit d9d541c

Browse files
cjihrigMylesBorins
authored andcommittedNov 11, 2018
deps: upgrade to libuv 1.23.0
Notable changes: - Restores compatibility with the old IPC protocol. - Adds uv_open_osfhandle(). - Adds uv_os_{get,set}priority(). Backport-PR-URL: #24103 PR-URL: #22365 Fixes: #21671 Fixes: #15433 Refs: #21675 Refs: nodejs/node-addon-api#304 Refs: nodejs/abi-stable-node#318 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent e3d08af commit d9d541c

24 files changed

+633
-104
lines changed
 

‎deps/uv/AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -345,3 +345,4 @@ Peter Johnson <johnson.peter@gmail.com>
345345
Paolo Greppi <paolo.greppi@libpf.com>
346346
Shelley Vohr <shelley.vohr@gmail.com>
347347
Ujjwal Sharma <usharma1998@gmail.com>
348+
Michał Kozakiewicz <michalkozakiewicz3@gmail.com>

‎deps/uv/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ set(uv_test_sources
9898
test/test-poll-closesocket.c
9999
test/test-poll-oob.c
100100
test/test-poll.c
101+
test/test-process-priority.c
101102
test/test-process-title-threadsafe.c
102103
test/test-process-title.c
103104
test/test-queue-foreach-delete.c

‎deps/uv/ChangeLog

+22
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
2018.08.18, Version 1.23.0 (Stable), 7ebb26225f2eaae6db22f4ef34ce76fa16ff89ec
2+
3+
Changes since version 1.22.0:
4+
5+
* win,pipe: restore compatibility with the old IPC framing protocol (Bert
6+
Belder)
7+
8+
* fs: add uv_open_osfhandle (Bartosz Sosnowski)
9+
10+
* doc: update Visual C++ Build Tools URL (Michał Kozakiewicz)
11+
12+
* unix: loop starvation on successful write complete (jBarz)
13+
14+
* win: add uv__getnameinfo_work() error handling (A. Hauptmann)
15+
16+
* win: return UV_ENOMEM from uv_loop_init() (cjihrig)
17+
18+
* unix,win: add uv_os_{get,set}priority() (cjihrig)
19+
20+
* test: fix warning in test-tcp-open (Santiago Gimeno)
21+
22+
123
2018.07.11, Version 1.22.0 (Stable), 8568f78a777d79d35eb7d6994617267b9fb33967
224

325
Changes since version 1.21.0:

‎deps/uv/Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
224224
test/test-poll-close-doesnt-corrupt-stack.c \
225225
test/test-poll-closesocket.c \
226226
test/test-poll-oob.c \
227+
test/test-process-priority.c \
227228
test/test-process-title.c \
228229
test/test-process-title-threadsafe.c \
229230
test/test-queue-foreach-delete.c \

‎deps/uv/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ See the [guidelines for contributing][].
349349
[libuv_banner]: https://raw.githubusercontent.com/libuv/libuv/master/img/banner.png
350350
[x32]: https://en.wikipedia.org/wiki/X32_ABI
351351
[Python 2.6 or 2.7]: https://www.python.org/downloads/
352-
[Visual C++ Build Tools]: http://landinghub.visualstudio.com/visual-cpp-build-tools
352+
[Visual C++ Build Tools]: https://visualstudio.microsoft.com/visual-cpp-build-tools/
353353
[Visual Studio 2015 Update 3]: https://www.visualstudio.com/vs/older-downloads/
354354
[Visual Studio 2017]: https://www.visualstudio.com/downloads/
355355
[Git for Windows]: http://git-scm.com/download/win

‎deps/uv/configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1414

1515
AC_PREREQ(2.57)
16-
AC_INIT([libuv], [1.22.0], [https://github.com/libuv/libuv/issues])
16+
AC_INIT([libuv], [1.23.0], [https://github.com/libuv/libuv/issues])
1717
AC_CONFIG_MACRO_DIR([m4])
1818
m4_include([m4/libuv-extra-automake-flags.m4])
1919
m4_include([m4/as_case.m4])

‎deps/uv/docs/src/fs.rst

+9
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,15 @@ Helper functions
403403
404404
.. versionadded:: 1.12.0
405405
406+
.. c:function:: int uv_open_osfhandle(uv_os_fd_t os_fd)
407+
408+
For a OS-dependent handle, get the file descriptor in the C runtime.
409+
On UNIX, returns the ``os_fd`` intact. On Windows, this calls `_open_osfhandle <https://msdn.microsoft.com/en-us/library/bdts1c9x.aspx>`_.
410+
Note that the return value is still owned by the CRT,
411+
any attempts to close it or to use it after closing the handle may lead to malfunction.
412+
413+
.. versionadded:: 1.23.0
414+
406415
File open constants
407416
-------------------
408417

‎deps/uv/docs/src/misc.rst

+28
Original file line numberDiff line numberDiff line change
@@ -517,3 +517,31 @@ API
517517
storage required to hold the value.
518518
519519
.. versionadded:: 1.12.0
520+
521+
.. c:function:: int uv_os_getpriority(uv_pid_t pid, int* priority)
522+
523+
Retrieves the scheduling priority of the process specified by `pid`. The
524+
returned value of `priority` is between -20 (high priority) and 19 (low
525+
priority).
526+
527+
.. note::
528+
On Windows, the returned priority will equal one of the `UV_PRIORITY`
529+
constants.
530+
531+
.. versionadded:: 1.23.0
532+
533+
.. c:function:: int uv_os_setpriority(uv_pid_t pid, int priority)
534+
535+
Sets the scheduling priority of the process specified by `pid`. The
536+
`priority` value range is between -20 (high priority) and 19 (low priority).
537+
The constants `UV_PRIORITY_LOW`, `UV_PRIORITY_BELOW_NORMAL`,
538+
`UV_PRIORITY_NORMAL`, `UV_PRIORITY_ABOVE_NORMAL`, `UV_PRIORITY_HIGH`, and
539+
`UV_PRIORITY_HIGHEST` are also provided for convenience.
540+
541+
.. note::
542+
On Windows, this function utilizes `SetPriorityClass()`. The `priority`
543+
argument is mapped to a Windows priority class. When retrieving the
544+
process priority, the result will equal one of the `UV_PRIORITY`
545+
constants, and not necessarily the exact value of `priority`.
546+
547+
.. versionadded:: 1.23.0

‎deps/uv/include/uv.h

+11
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,7 @@ UV_EXTERN int uv_set_process_title(const char* title);
10651065
UV_EXTERN int uv_resident_set_memory(size_t* rss);
10661066
UV_EXTERN int uv_uptime(double* uptime);
10671067
UV_EXTERN uv_os_fd_t uv_get_osfhandle(int fd);
1068+
UV_EXTERN int uv_open_osfhandle(uv_os_fd_t os_fd);
10681069

10691070
typedef struct {
10701071
long tv_sec;
@@ -1099,6 +1100,16 @@ UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd);
10991100
UV_EXTERN uv_pid_t uv_os_getpid(void);
11001101
UV_EXTERN uv_pid_t uv_os_getppid(void);
11011102

1103+
#define UV_PRIORITY_LOW 19
1104+
#define UV_PRIORITY_BELOW_NORMAL 10
1105+
#define UV_PRIORITY_NORMAL 0
1106+
#define UV_PRIORITY_ABOVE_NORMAL -7
1107+
#define UV_PRIORITY_HIGH -14
1108+
#define UV_PRIORITY_HIGHEST -20
1109+
1110+
UV_EXTERN int uv_os_getpriority(uv_pid_t pid, int* priority);
1111+
UV_EXTERN int uv_os_setpriority(uv_pid_t pid, int priority);
1112+
11021113
UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
11031114
UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);
11041115

‎deps/uv/include/uv/version.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
*/
3232

3333
#define UV_VERSION_MAJOR 1
34-
#define UV_VERSION_MINOR 22
34+
#define UV_VERSION_MINOR 23
3535
#define UV_VERSION_PATCH 0
3636
#define UV_VERSION_IS_RELEASE 1
3737
#define UV_VERSION_SUFFIX ""

‎deps/uv/src/unix/core.c

+31
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,9 @@ uv_os_fd_t uv_get_osfhandle(int fd) {
13381338
return fd;
13391339
}
13401340

1341+
int uv_open_osfhandle(uv_os_fd_t os_fd) {
1342+
return os_fd;
1343+
}
13411344

13421345
uv_pid_t uv_os_getpid(void) {
13431346
return getpid();
@@ -1347,3 +1350,31 @@ uv_pid_t uv_os_getpid(void) {
13471350
uv_pid_t uv_os_getppid(void) {
13481351
return getppid();
13491352
}
1353+
1354+
1355+
int uv_os_getpriority(uv_pid_t pid, int* priority) {
1356+
int r;
1357+
1358+
if (priority == NULL)
1359+
return UV_EINVAL;
1360+
1361+
errno = 0;
1362+
r = getpriority(PRIO_PROCESS, (int) pid);
1363+
1364+
if (r == -1 && errno != 0)
1365+
return UV__ERR(errno);
1366+
1367+
*priority = r;
1368+
return 0;
1369+
}
1370+
1371+
1372+
int uv_os_setpriority(uv_pid_t pid, int priority) {
1373+
if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW)
1374+
return UV_EINVAL;
1375+
1376+
if (setpriority(PRIO_PROCESS, (int) pid, priority) != 0)
1377+
return UV__ERR(errno);
1378+
1379+
return 0;
1380+
}

‎deps/uv/src/unix/stream.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -950,10 +950,16 @@ static void uv__write(uv_stream_t* stream) {
950950
static void uv__write_callbacks(uv_stream_t* stream) {
951951
uv_write_t* req;
952952
QUEUE* q;
953+
QUEUE pq;
953954

954-
while (!QUEUE_EMPTY(&stream->write_completed_queue)) {
955+
if (QUEUE_EMPTY(&stream->write_completed_queue))
956+
return;
957+
958+
QUEUE_MOVE(&stream->write_completed_queue, &pq);
959+
960+
while (!QUEUE_EMPTY(&pq)) {
955961
/* Pop a req off write_completed_queue. */
956-
q = QUEUE_HEAD(&stream->write_completed_queue);
962+
q = QUEUE_HEAD(&pq);
957963
req = QUEUE_DATA(q, uv_write_t, queue);
958964
QUEUE_REMOVE(q);
959965
uv__req_unregister(stream->loop, req);
@@ -969,8 +975,6 @@ static void uv__write_callbacks(uv_stream_t* stream) {
969975
if (req->cb)
970976
req->cb(req, req->error);
971977
}
972-
973-
assert(QUEUE_EMPTY(&stream->write_completed_queue));
974978
}
975979

976980

‎deps/uv/src/win/core.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,10 @@ int uv_loop_init(uv_loop_t* loop) {
249249
loop->endgame_handles = NULL;
250250

251251
loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap));
252-
if (timer_heap == NULL)
252+
if (timer_heap == NULL) {
253+
err = UV_ENOMEM;
253254
goto fail_timers_alloc;
255+
}
254256

255257
heap_init(timer_heap);
256258

‎deps/uv/src/win/getnameinfo.c

+28-21
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static void uv__getnameinfo_work(struct uv__work* w) {
4242
uv_getnameinfo_t* req;
4343
WCHAR host[NI_MAXHOST];
4444
WCHAR service[NI_MAXSERV];
45-
int ret = 0;
45+
int ret;
4646

4747
req = container_of(w, uv_getnameinfo_t, work_req);
4848
if (GetNameInfoW((struct sockaddr*)&req->storage,
@@ -53,27 +53,34 @@ static void uv__getnameinfo_work(struct uv__work* w) {
5353
ARRAY_SIZE(service),
5454
req->flags)) {
5555
ret = WSAGetLastError();
56+
req->retcode = uv__getaddrinfo_translate_error(ret);
57+
return;
58+
}
59+
60+
ret = WideCharToMultiByte(CP_UTF8,
61+
0,
62+
host,
63+
-1,
64+
req->host,
65+
sizeof(req->host),
66+
NULL,
67+
NULL);
68+
if (ret == 0) {
69+
req->retcode = uv_translate_sys_error(GetLastError());
70+
return;
71+
}
72+
73+
ret = WideCharToMultiByte(CP_UTF8,
74+
0,
75+
service,
76+
-1,
77+
req->service,
78+
sizeof(req->service),
79+
NULL,
80+
NULL);
81+
if (ret == 0) {
82+
req->retcode = uv_translate_sys_error(GetLastError());
5683
}
57-
req->retcode = uv__getaddrinfo_translate_error(ret);
58-
59-
/* convert results to UTF-8 */
60-
WideCharToMultiByte(CP_UTF8,
61-
0,
62-
host,
63-
-1,
64-
req->host,
65-
sizeof(req->host),
66-
NULL,
67-
NULL);
68-
69-
WideCharToMultiByte(CP_UTF8,
70-
0,
71-
service,
72-
-1,
73-
req->service,
74-
sizeof(req->service),
75-
NULL,
76-
NULL);
7784
}
7885

7986

‎deps/uv/src/win/handle.c

+4
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,7 @@ int uv_is_closing(const uv_handle_t* handle) {
157157
uv_os_fd_t uv_get_osfhandle(int fd) {
158158
return uv__get_osfhandle(fd);
159159
}
160+
161+
int uv_open_osfhandle(uv_os_fd_t os_fd) {
162+
return _open_osfhandle((intptr_t) os_fd, 0);
163+
}

‎deps/uv/src/win/internal.h

+10-2
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,15 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
6161
* TCP
6262
*/
6363

64+
typedef enum {
65+
UV__IPC_SOCKET_XFER_NONE = 0,
66+
UV__IPC_SOCKET_XFER_TCP_CONNECTION,
67+
UV__IPC_SOCKET_XFER_TCP_SERVER
68+
} uv__ipc_socket_xfer_type_t;
69+
6470
typedef struct {
6571
WSAPROTOCOL_INFOW socket_info;
6672
uint32_t delayed_error;
67-
uint32_t flags; /* Either zero or UV_HANDLE_CONNECTION. */
6873
} uv__ipc_socket_xfer_info_t;
6974

7075
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
@@ -89,8 +94,11 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
8994

9095
int uv__tcp_xfer_export(uv_tcp_t* handle,
9196
int pid,
97+
uv__ipc_socket_xfer_type_t* xfer_type,
98+
uv__ipc_socket_xfer_info_t* xfer_info);
99+
int uv__tcp_xfer_import(uv_tcp_t* tcp,
100+
uv__ipc_socket_xfer_type_t xfer_type,
92101
uv__ipc_socket_xfer_info_t* xfer_info);
93-
int uv__tcp_xfer_import(uv_tcp_t* tcp, uv__ipc_socket_xfer_info_t* xfer_info);
94102

95103

96104
/*

‎deps/uv/src/win/pipe.c

+113-59
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@
2525
#include <stdlib.h>
2626
#include <string.h>
2727

28-
#include "uv.h"
29-
#include "internal.h"
3028
#include "handle-inl.h"
31-
#include "stream-inl.h"
29+
#include "internal.h"
3230
#include "req-inl.h"
31+
#include "stream-inl.h"
32+
#include "uv-common.h"
33+
#include "uv.h"
3334

3435
#include <aclapi.h>
3536
#include <accctrl.h>
@@ -52,19 +53,36 @@ static const int pipe_prefix_len = sizeof(pipe_prefix) - 1;
5253

5354
/* IPC incoming xfer queue item. */
5455
typedef struct {
56+
uv__ipc_socket_xfer_type_t xfer_type;
5557
uv__ipc_socket_xfer_info_t xfer_info;
5658
QUEUE member;
5759
} uv__ipc_xfer_queue_item_t;
5860

59-
/* IPC frame types. */
60-
enum { UV__IPC_DATA_FRAME = 0, UV__IPC_XFER_FRAME = 1 };
61+
/* IPC frame header flags. */
62+
/* clang-format off */
63+
enum {
64+
UV__IPC_FRAME_HAS_DATA = 0x01,
65+
UV__IPC_FRAME_HAS_SOCKET_XFER = 0x02,
66+
UV__IPC_FRAME_XFER_IS_TCP_CONNECTION = 0x04,
67+
/* These are combinations of the flags above. */
68+
UV__IPC_FRAME_XFER_FLAGS = 0x06,
69+
UV__IPC_FRAME_VALID_FLAGS = 0x07
70+
};
71+
/* clang-format on */
6172

6273
/* IPC frame header. */
6374
typedef struct {
64-
uint32_t type;
65-
uint32_t payload_length;
75+
uint32_t flags;
76+
uint32_t reserved1; /* Ignored. */
77+
uint32_t data_length; /* Must be zero if there is no data. */
78+
uint32_t reserved2; /* Must be zero. */
6679
} uv__ipc_frame_header_t;
6780

81+
/* To implement the IPC protocol correctly, these structures must have exactly
82+
* the right size. */
83+
STATIC_ASSERT(sizeof(uv__ipc_frame_header_t) == 16);
84+
STATIC_ASSERT(sizeof(uv__ipc_socket_xfer_info_t) == 632);
85+
6886
/* Coalesced write request. */
6987
typedef struct {
7088
uv_write_t req; /* Internal heap-allocated write request. */
@@ -878,7 +896,8 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
878896
server->pipe.conn.ipc_xfer_queue_length--;
879897
item = QUEUE_DATA(q, uv__ipc_xfer_queue_item_t, member);
880898

881-
err = uv__tcp_xfer_import((uv_tcp_t*) client, &item->xfer_info);
899+
err = uv__tcp_xfer_import(
900+
(uv_tcp_t*) client, item->xfer_type, &item->xfer_info);
882901
if (err != 0)
883902
return err;
884903

@@ -1458,10 +1477,10 @@ int uv__pipe_write_ipc(uv_loop_t* loop,
14581477
uv_buf_t stack_bufs[6];
14591478
uv_buf_t* bufs;
14601479
size_t buf_count, buf_index;
1461-
uv__ipc_frame_header_t xfer_frame_header;
1480+
uv__ipc_frame_header_t frame_header;
1481+
uv__ipc_socket_xfer_type_t xfer_type = UV__IPC_SOCKET_XFER_NONE;
14621482
uv__ipc_socket_xfer_info_t xfer_info;
1463-
uv__ipc_frame_header_t data_frame_header;
1464-
size_t data_length;
1483+
uint64_t data_length;
14651484
size_t i;
14661485
int err;
14671486

@@ -1472,29 +1491,27 @@ int uv__pipe_write_ipc(uv_loop_t* loop,
14721491
if (data_length > UINT32_MAX)
14731492
return WSAENOBUFS; /* Maps to UV_ENOBUFS. */
14741493

1475-
/* Prepare xfer frame payload. */
1476-
if (send_handle) {
1494+
/* Prepare the frame's socket xfer payload. */
1495+
if (send_handle != NULL) {
14771496
uv_tcp_t* send_tcp_handle = (uv_tcp_t*) send_handle;
14781497

14791498
/* Verify that `send_handle` it is indeed a tcp handle. */
14801499
if (send_tcp_handle->type != UV_TCP)
14811500
return ERROR_NOT_SUPPORTED;
14821501

14831502
/* Export the tcp handle. */
1484-
err = uv__tcp_xfer_export(
1485-
send_tcp_handle, uv__pipe_get_ipc_remote_pid(handle), &xfer_info);
1503+
err = uv__tcp_xfer_export(send_tcp_handle,
1504+
uv__pipe_get_ipc_remote_pid(handle),
1505+
&xfer_type,
1506+
&xfer_info);
14861507
if (err != 0)
14871508
return err;
14881509
}
14891510

14901511
/* Compute the number of uv_buf_t's required. */
1491-
buf_count = 0;
1492-
if (send_handle != NULL) {
1493-
buf_count += 2; /* One for the frame header, one for the payload. */
1494-
}
1495-
if (data_buf_count > 0) {
1496-
buf_count += 1 + data_buf_count; /* One extra for the frame header. */
1497-
}
1512+
buf_count = 1 + data_buf_count; /* Frame header and data buffers. */
1513+
if (send_handle != NULL)
1514+
buf_count += 1; /* One extra for the socket xfer information. */
14981515

14991516
/* Use the on-stack buffer array if it is big enough; otherwise allocate
15001517
* space for it on the heap. */
@@ -1509,25 +1526,32 @@ int uv__pipe_write_ipc(uv_loop_t* loop,
15091526
}
15101527
buf_index = 0;
15111528

1512-
if (send_handle != NULL) {
1513-
/* Add xfer frame header. */
1514-
xfer_frame_header.type = UV__IPC_XFER_FRAME;
1515-
xfer_frame_header.payload_length = sizeof xfer_info;
1516-
bufs[buf_index++] =
1517-
uv_buf_init((char*) &xfer_frame_header, sizeof xfer_frame_header);
1529+
/* Initialize frame header and add it to the buffers list. */
1530+
memset(&frame_header, 0, sizeof frame_header);
1531+
bufs[buf_index++] = uv_buf_init((char*) &frame_header, sizeof frame_header);
15181532

1519-
/* Add xfer frame payload. */
1533+
if (send_handle != NULL) {
1534+
/* Add frame header flags. */
1535+
switch (xfer_type) {
1536+
case UV__IPC_SOCKET_XFER_TCP_CONNECTION:
1537+
frame_header.flags |= UV__IPC_FRAME_HAS_SOCKET_XFER |
1538+
UV__IPC_FRAME_XFER_IS_TCP_CONNECTION;
1539+
break;
1540+
case UV__IPC_SOCKET_XFER_TCP_SERVER:
1541+
frame_header.flags |= UV__IPC_FRAME_HAS_SOCKET_XFER;
1542+
break;
1543+
default:
1544+
assert(0); // Unreachable.
1545+
}
1546+
/* Add xfer info buffer. */
15201547
bufs[buf_index++] = uv_buf_init((char*) &xfer_info, sizeof xfer_info);
15211548
}
15221549

15231550
if (data_length > 0) {
1524-
/* Add data frame header. */
1525-
data_frame_header.type = UV__IPC_DATA_FRAME;
1526-
data_frame_header.payload_length = (uint32_t) data_length;
1527-
bufs[buf_index++] =
1528-
uv_buf_init((char*) &data_frame_header, sizeof data_frame_header);
1529-
1530-
/* Add data buffers. */
1551+
/* Update frame header. */
1552+
frame_header.flags |= UV__IPC_FRAME_HAS_DATA;
1553+
frame_header.data_length = (uint32_t) data_length;
1554+
/* Add data buffers to buffers list. */
15311555
for (i = 0; i < data_buf_count; i++)
15321556
bufs[buf_index++] = data_bufs[i];
15331557
}
@@ -1601,14 +1625,18 @@ static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle,
16011625

16021626

16031627
static void uv__pipe_queue_ipc_xfer_info(
1604-
uv_pipe_t* handle, uv__ipc_socket_xfer_info_t* xfer_info) {
1628+
uv_pipe_t* handle,
1629+
uv__ipc_socket_xfer_type_t xfer_type,
1630+
uv__ipc_socket_xfer_info_t* xfer_info) {
16051631
uv__ipc_xfer_queue_item_t* item;
16061632

16071633
item = (uv__ipc_xfer_queue_item_t*) uv__malloc(sizeof(*item));
16081634
if (item == NULL)
16091635
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
16101636

1611-
memcpy(&item->xfer_info, xfer_info, sizeof(item->xfer_info));
1637+
item->xfer_type = xfer_type;
1638+
item->xfer_info = *xfer_info;
1639+
16121640
QUEUE_INSERT_TAIL(&handle->pipe.conn.ipc_xfer_queue, &item->member);
16131641
handle->pipe.conn.ipc_xfer_queue_length++;
16141642
}
@@ -1678,7 +1706,7 @@ static DWORD uv__pipe_read_ipc(uv_loop_t* loop, uv_pipe_t* handle) {
16781706
int err;
16791707

16801708
if (*data_remaining > 0) {
1681-
/* Read data frame payload. */
1709+
/* Read frame data payload. */
16821710
DWORD bytes_read =
16831711
uv__pipe_read_data(loop, handle, *data_remaining, *data_remaining);
16841712
*data_remaining -= bytes_read;
@@ -1687,6 +1715,8 @@ static DWORD uv__pipe_read_ipc(uv_loop_t* loop, uv_pipe_t* handle) {
16871715
} else {
16881716
/* Start of a new IPC frame. */
16891717
uv__ipc_frame_header_t frame_header;
1718+
uint32_t xfer_flags;
1719+
uv__ipc_socket_xfer_type_t xfer_type;
16901720
uv__ipc_socket_xfer_info_t xfer_info;
16911721

16921722
/* Read the IPC frame header. */
@@ -1695,33 +1725,57 @@ static DWORD uv__pipe_read_ipc(uv_loop_t* loop, uv_pipe_t* handle) {
16951725
if (err)
16961726
goto error;
16971727

1698-
if (frame_header.type == UV__IPC_DATA_FRAME) {
1699-
/* Data frame: capture payload length. Actual data will be read in
1700-
* subsequent call to uv__pipe_read_ipc(). */
1701-
*data_remaining = frame_header.payload_length;
1728+
/* Validate that flags are valid. */
1729+
if ((frame_header.flags & ~UV__IPC_FRAME_VALID_FLAGS) != 0)
1730+
goto invalid;
1731+
/* Validate that reserved2 is zero. */
1732+
if (frame_header.reserved2 != 0)
1733+
goto invalid;
1734+
1735+
/* Parse xfer flags. */
1736+
xfer_flags = frame_header.flags & UV__IPC_FRAME_XFER_FLAGS;
1737+
if (xfer_flags & UV__IPC_FRAME_HAS_SOCKET_XFER) {
1738+
/* Socket coming -- determine the type. */
1739+
xfer_type = xfer_flags & UV__IPC_FRAME_XFER_IS_TCP_CONNECTION
1740+
? UV__IPC_SOCKET_XFER_TCP_CONNECTION
1741+
: UV__IPC_SOCKET_XFER_TCP_SERVER;
1742+
} else if (xfer_flags == 0) {
1743+
/* No socket. */
1744+
xfer_type = UV__IPC_SOCKET_XFER_NONE;
1745+
} else {
1746+
/* Invalid flags. */
1747+
goto invalid;
1748+
}
17021749

1703-
/* Return number of bytes read. */
1704-
return sizeof frame_header;
1750+
/* Parse data frame information. */
1751+
if (frame_header.flags & UV__IPC_FRAME_HAS_DATA) {
1752+
*data_remaining = frame_header.data_length;
1753+
} else if (frame_header.data_length != 0) {
1754+
/* Data length greater than zero but data flag not set -- invalid. */
1755+
goto invalid;
1756+
}
17051757

1706-
} else if (frame_header.type == UV__IPC_XFER_FRAME) {
1707-
/* Xfer frame: read the payload. */
1708-
assert(frame_header.payload_length == sizeof xfer_info);
1709-
err =
1710-
uv__pipe_read_exactly(handle->handle, &xfer_info, sizeof xfer_info);
1711-
if (err)
1712-
goto error;
1758+
/* If no socket xfer info follows, return here. Data will be read in a
1759+
* subsequent invocation of uv__pipe_read_ipc(). */
1760+
if (xfer_type == UV__IPC_SOCKET_XFER_NONE)
1761+
return sizeof frame_header; /* Number of bytes read. */
17131762

1714-
/* Store the pending socket info. */
1715-
uv__pipe_queue_ipc_xfer_info(handle, &xfer_info);
1763+
/* Read transferred socket information. */
1764+
err = uv__pipe_read_exactly(handle->handle, &xfer_info, sizeof xfer_info);
1765+
if (err)
1766+
goto error;
17161767

1717-
/* Return number of bytes read. */
1718-
return sizeof frame_header + sizeof xfer_info;
1719-
}
1768+
/* Store the pending socket info. */
1769+
uv__pipe_queue_ipc_xfer_info(handle, xfer_type, &xfer_info);
17201770

1721-
/* Invalid frame. */
1722-
err = WSAECONNABORTED; /* Maps to UV_ECONNABORTED. */
1771+
/* Return number of bytes read. */
1772+
return sizeof frame_header + sizeof xfer_info;
17231773
}
17241774

1775+
invalid:
1776+
/* Invalid frame. */
1777+
err = WSAECONNABORTED; /* Maps to UV_ECONNABORTED. */
1778+
17251779
error:
17261780
uv_pipe_read_error_or_eof(loop, handle, err, uv_null_buf_);
17271781
return 0; /* Break out of read loop. */

‎deps/uv/src/win/tcp.c

+21-13
Original file line numberDiff line numberDiff line change
@@ -1191,8 +1191,12 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
11911191

11921192
int uv__tcp_xfer_export(uv_tcp_t* handle,
11931193
int target_pid,
1194+
uv__ipc_socket_xfer_type_t* xfer_type,
11941195
uv__ipc_socket_xfer_info_t* xfer_info) {
1195-
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
1196+
if (handle->flags & UV_HANDLE_CONNECTION) {
1197+
*xfer_type = UV__IPC_SOCKET_XFER_TCP_CONNECTION;
1198+
} else {
1199+
*xfer_type = UV__IPC_SOCKET_XFER_TCP_SERVER;
11961200
/* We're about to share the socket with another process. Because this is a
11971201
* listening socket, we assume that the other process will be accepting
11981202
* connections on it. Thus, before sharing the socket with another process,
@@ -1208,12 +1212,9 @@ int uv__tcp_xfer_export(uv_tcp_t* handle,
12081212
}
12091213
}
12101214

1211-
if (WSADuplicateSocketW(
1212-
handle->socket, target_pid, &xfer_info->socket_info)) {
1215+
if (WSADuplicateSocketW(handle->socket, target_pid, &xfer_info->socket_info))
12131216
return WSAGetLastError();
1214-
}
12151217
xfer_info->delayed_error = handle->delayed_error;
1216-
xfer_info->flags = handle->flags & UV_HANDLE_CONNECTION;
12171218

12181219
/* Mark the local copy of the handle as 'shared' so we behave in a way that's
12191220
* friendly to the process(es) that we share the socket with. */
@@ -1223,14 +1224,21 @@ int uv__tcp_xfer_export(uv_tcp_t* handle,
12231224
}
12241225

12251226

1226-
int uv__tcp_xfer_import(uv_tcp_t* tcp, uv__ipc_socket_xfer_info_t* xfer_info) {
1227+
int uv__tcp_xfer_import(uv_tcp_t* tcp,
1228+
uv__ipc_socket_xfer_type_t xfer_type,
1229+
uv__ipc_socket_xfer_info_t* xfer_info) {
12271230
int err;
1228-
SOCKET socket = WSASocketW(FROM_PROTOCOL_INFO,
1229-
FROM_PROTOCOL_INFO,
1230-
FROM_PROTOCOL_INFO,
1231-
&xfer_info->socket_info,
1232-
0,
1233-
WSA_FLAG_OVERLAPPED);
1231+
SOCKET socket;
1232+
1233+
assert(xfer_type == UV__IPC_SOCKET_XFER_TCP_SERVER ||
1234+
xfer_type == UV__IPC_SOCKET_XFER_TCP_CONNECTION);
1235+
1236+
socket = WSASocketW(FROM_PROTOCOL_INFO,
1237+
FROM_PROTOCOL_INFO,
1238+
FROM_PROTOCOL_INFO,
1239+
&xfer_info->socket_info,
1240+
0,
1241+
WSA_FLAG_OVERLAPPED);
12341242

12351243
if (socket == INVALID_SOCKET) {
12361244
return WSAGetLastError();
@@ -1246,7 +1254,7 @@ int uv__tcp_xfer_import(uv_tcp_t* tcp, uv__ipc_socket_xfer_info_t* xfer_info) {
12461254
tcp->delayed_error = xfer_info->delayed_error;
12471255
tcp->flags |= UV_HANDLE_BOUND | UV_HANDLE_SHARED_TCP_SOCKET;
12481256

1249-
if (xfer_info->flags & UV_HANDLE_CONNECTION) {
1257+
if (xfer_type == UV__IPC_SOCKET_XFER_TCP_CONNECTION) {
12501258
uv_connection_init((uv_stream_t*)tcp);
12511259
tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
12521260
}

‎deps/uv/src/win/util.c

+94
Original file line numberDiff line numberDiff line change
@@ -1530,3 +1530,97 @@ int uv_os_gethostname(char* buffer, size_t* size) {
15301530
*size = len;
15311531
return 0;
15321532
}
1533+
1534+
1535+
static int uv__get_handle(uv_pid_t pid, int access, HANDLE* handle) {
1536+
int r;
1537+
1538+
if (pid == 0)
1539+
*handle = GetCurrentProcess();
1540+
else
1541+
*handle = OpenProcess(access, FALSE, pid);
1542+
1543+
if (*handle == NULL) {
1544+
r = GetLastError();
1545+
1546+
if (r == ERROR_INVALID_PARAMETER)
1547+
return UV_ESRCH;
1548+
else
1549+
return uv_translate_sys_error(r);
1550+
}
1551+
1552+
return 0;
1553+
}
1554+
1555+
1556+
int uv_os_getpriority(uv_pid_t pid, int* priority) {
1557+
HANDLE handle;
1558+
int r;
1559+
1560+
if (priority == NULL)
1561+
return UV_EINVAL;
1562+
1563+
r = uv__get_handle(pid, PROCESS_QUERY_LIMITED_INFORMATION, &handle);
1564+
1565+
if (r != 0)
1566+
return r;
1567+
1568+
r = GetPriorityClass(handle);
1569+
1570+
if (r == 0) {
1571+
r = uv_translate_sys_error(GetLastError());
1572+
} else {
1573+
/* Map Windows priority classes to Unix nice values. */
1574+
if (r == REALTIME_PRIORITY_CLASS)
1575+
*priority = UV_PRIORITY_HIGHEST;
1576+
else if (r == HIGH_PRIORITY_CLASS)
1577+
*priority = UV_PRIORITY_HIGH;
1578+
else if (r == ABOVE_NORMAL_PRIORITY_CLASS)
1579+
*priority = UV_PRIORITY_ABOVE_NORMAL;
1580+
else if (r == NORMAL_PRIORITY_CLASS)
1581+
*priority = UV_PRIORITY_NORMAL;
1582+
else if (r == BELOW_NORMAL_PRIORITY_CLASS)
1583+
*priority = UV_PRIORITY_BELOW_NORMAL;
1584+
else /* IDLE_PRIORITY_CLASS */
1585+
*priority = UV_PRIORITY_LOW;
1586+
1587+
r = 0;
1588+
}
1589+
1590+
CloseHandle(handle);
1591+
return r;
1592+
}
1593+
1594+
1595+
int uv_os_setpriority(uv_pid_t pid, int priority) {
1596+
HANDLE handle;
1597+
int priority_class;
1598+
int r;
1599+
1600+
/* Map Unix nice values to Windows priority classes. */
1601+
if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW)
1602+
return UV_EINVAL;
1603+
else if (priority < UV_PRIORITY_HIGH)
1604+
priority_class = REALTIME_PRIORITY_CLASS;
1605+
else if (priority < UV_PRIORITY_ABOVE_NORMAL)
1606+
priority_class = HIGH_PRIORITY_CLASS;
1607+
else if (priority < UV_PRIORITY_NORMAL)
1608+
priority_class = ABOVE_NORMAL_PRIORITY_CLASS;
1609+
else if (priority < UV_PRIORITY_BELOW_NORMAL)
1610+
priority_class = NORMAL_PRIORITY_CLASS;
1611+
else if (priority < UV_PRIORITY_LOW)
1612+
priority_class = BELOW_NORMAL_PRIORITY_CLASS;
1613+
else
1614+
priority_class = IDLE_PRIORITY_CLASS;
1615+
1616+
r = uv__get_handle(pid, PROCESS_SET_INFORMATION, &handle);
1617+
1618+
if (r != 0)
1619+
return r;
1620+
1621+
if (SetPriorityClass(handle, priority_class) == 0)
1622+
r = uv_translate_sys_error(GetLastError());
1623+
1624+
CloseHandle(handle);
1625+
return r;
1626+
}

‎deps/uv/test/test-fs.c

+46
Original file line numberDiff line numberDiff line change
@@ -3069,6 +3069,52 @@ TEST_IMPL(get_osfhandle_valid_handle) {
30693069
return 0;
30703070
}
30713071

3072+
TEST_IMPL(open_osfhandle_valid_handle) {
3073+
int r;
3074+
uv_os_fd_t handle;
3075+
int fd;
3076+
3077+
/* Setup. */
3078+
unlink("test_file");
3079+
3080+
loop = uv_default_loop();
3081+
3082+
r = uv_fs_open(NULL,
3083+
&open_req1,
3084+
"test_file",
3085+
O_RDWR | O_CREAT,
3086+
S_IWUSR | S_IRUSR,
3087+
NULL);
3088+
ASSERT(r >= 0);
3089+
ASSERT(open_req1.result >= 0);
3090+
uv_fs_req_cleanup(&open_req1);
3091+
3092+
handle = uv_get_osfhandle(open_req1.result);
3093+
#ifdef _WIN32
3094+
ASSERT(handle != INVALID_HANDLE_VALUE);
3095+
#else
3096+
ASSERT(handle >= 0);
3097+
#endif
3098+
3099+
fd = uv_open_osfhandle(handle);
3100+
#ifdef _WIN32
3101+
ASSERT(fd > 0);
3102+
#else
3103+
ASSERT(fd == open_req1.result);
3104+
#endif
3105+
3106+
r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
3107+
ASSERT(r == 0);
3108+
ASSERT(close_req.result == 0);
3109+
uv_fs_req_cleanup(&close_req);
3110+
3111+
/* Cleanup. */
3112+
unlink("test_file");
3113+
3114+
MAKE_VALGRIND_HAPPY();
3115+
return 0;
3116+
}
3117+
30723118
TEST_IMPL(fs_file_pos_after_op_with_offset) {
30733119
int r;
30743120

‎deps/uv/test/test-list.h

+7
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ TEST_DECLARE (tcp_bind6_error_addrnotavail)
121121
TEST_DECLARE (tcp_bind6_error_fault)
122122
TEST_DECLARE (tcp_bind6_error_inval)
123123
TEST_DECLARE (tcp_bind6_localhost_ok)
124+
TEST_DECLARE (tcp_write_ready)
124125
TEST_DECLARE (udp_alloc_cb_fail)
125126
TEST_DECLARE (udp_bind)
126127
TEST_DECLARE (udp_bind_reuseaddr)
@@ -213,6 +214,7 @@ TEST_DECLARE (pipe_close_stdout_read_stdin)
213214
TEST_DECLARE (pipe_set_non_blocking)
214215
TEST_DECLARE (pipe_set_chmod)
215216
TEST_DECLARE (process_ref)
217+
TEST_DECLARE (process_priority)
216218
TEST_DECLARE (has_ref)
217219
TEST_DECLARE (active)
218220
TEST_DECLARE (embed)
@@ -334,6 +336,7 @@ TEST_DECLARE (fs_rename_to_existing_file)
334336
TEST_DECLARE (fs_write_multiple_bufs)
335337
TEST_DECLARE (fs_read_write_null_arguments)
336338
TEST_DECLARE (get_osfhandle_valid_handle)
339+
TEST_DECLARE (open_osfhandle_valid_handle)
337340
TEST_DECLARE (fs_write_alotof_bufs)
338341
TEST_DECLARE (fs_write_alotof_bufs_with_offset)
339342
TEST_DECLARE (fs_file_pos_after_op_with_offset)
@@ -544,6 +547,8 @@ TASK_LIST_START
544547
TEST_ENTRY (tcp_open_bound)
545548
TEST_ENTRY (tcp_open_connected)
546549
TEST_HELPER (tcp_open_connected, tcp4_echo_server)
550+
TEST_ENTRY (tcp_write_ready)
551+
TEST_HELPER (tcp_write_ready, tcp4_echo_server)
547552

548553
TEST_ENTRY (tcp_shutdown_after_write)
549554
TEST_HELPER (tcp_shutdown_after_write, tcp4_echo_server)
@@ -685,6 +690,7 @@ TASK_LIST_START
685690
TEST_ENTRY (pipe_ref4)
686691
TEST_HELPER (pipe_ref4, pipe_echo_server)
687692
TEST_ENTRY (process_ref)
693+
TEST_ENTRY (process_priority)
688694
TEST_ENTRY (has_ref)
689695

690696
TEST_ENTRY (loop_handles)
@@ -887,6 +893,7 @@ TASK_LIST_START
887893
TEST_ENTRY (fs_fchmod_archive_readonly)
888894
#endif
889895
TEST_ENTRY (get_osfhandle_valid_handle)
896+
TEST_ENTRY (open_osfhandle_valid_handle)
890897
TEST_ENTRY (threadpool_queue_work_simple)
891898
TEST_ENTRY (threadpool_queue_work_einval)
892899
TEST_ENTRY (threadpool_multiple_event_loops)

‎deps/uv/test/test-process-priority.c

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/* Copyright libuv 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 "task.h"
24+
25+
26+
TEST_IMPL(process_priority) {
27+
int priority;
28+
int r;
29+
int i;
30+
31+
#if defined(__MVS__)
32+
if (uv_os_setpriority(0, 0) == UV_ENOSYS)
33+
RETURN_SKIP("functionality not supported on zOS");
34+
#endif
35+
36+
/* Verify that passing a NULL pointer returns UV_EINVAL. */
37+
r = uv_os_getpriority(0, NULL);
38+
ASSERT(r == UV_EINVAL);
39+
40+
/* Verify that all valid values work. */
41+
for (i = UV_PRIORITY_HIGHEST; i <= UV_PRIORITY_LOW; i++) {
42+
r = uv_os_setpriority(0, i);
43+
44+
/* If UV_EACCES is returned, the current user doesn't have permission to
45+
set this specific priority. */
46+
if (r == UV_EACCES)
47+
continue;
48+
49+
ASSERT(r == 0);
50+
ASSERT(uv_os_getpriority(0, &priority) == 0);
51+
52+
/* Verify that the priority values match on Unix, and are range mapped
53+
on Windows. */
54+
#ifndef _WIN32
55+
ASSERT(priority == i);
56+
#else
57+
if (i < UV_PRIORITY_HIGH)
58+
ASSERT(priority == UV_PRIORITY_HIGHEST);
59+
else if (i < UV_PRIORITY_ABOVE_NORMAL)
60+
ASSERT(priority == UV_PRIORITY_HIGH);
61+
else if (i < UV_PRIORITY_NORMAL)
62+
ASSERT(priority == UV_PRIORITY_ABOVE_NORMAL);
63+
else if (i < UV_PRIORITY_BELOW_NORMAL)
64+
ASSERT(priority == UV_PRIORITY_NORMAL);
65+
else if (i < UV_PRIORITY_LOW)
66+
ASSERT(priority == UV_PRIORITY_BELOW_NORMAL);
67+
else
68+
ASSERT(priority == UV_PRIORITY_LOW);
69+
#endif
70+
71+
/* Verify that the current PID and 0 are equivalent. */
72+
ASSERT(uv_os_getpriority(uv_os_getpid(), &r) == 0);
73+
ASSERT(priority == r);
74+
}
75+
76+
/* Verify that invalid priorities return UV_EINVAL. */
77+
ASSERT(uv_os_setpriority(0, UV_PRIORITY_HIGHEST - 1) == UV_EINVAL);
78+
ASSERT(uv_os_setpriority(0, UV_PRIORITY_LOW + 1) == UV_EINVAL);
79+
80+
return 0;
81+
}

‎deps/uv/test/test-tcp-open.c

+110-1
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,16 @@
3030
#endif
3131

3232
static int shutdown_cb_called = 0;
33+
static int shutdown_requested = 0;
3334
static int connect_cb_called = 0;
3435
static int write_cb_called = 0;
3536
static int close_cb_called = 0;
3637

3738
static uv_connect_t connect_req;
3839
static uv_shutdown_t shutdown_req;
3940
static uv_write_t write_req;
41+
static uv_timer_t tm;
42+
static uv_tcp_t client;
4043

4144

4245
static void startup(void) {
@@ -115,6 +118,20 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
115118
ASSERT(memcmp("PING", buf->base, nread) == 0);
116119
}
117120
else {
121+
ASSERT(nread == UV_EOF);
122+
uv_close((uv_handle_t*)tcp, close_cb);
123+
}
124+
}
125+
126+
127+
static void read1_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
128+
int i;
129+
ASSERT(tcp != NULL);
130+
131+
if (nread >= 0) {
132+
for (i = 0; i < nread; ++i)
133+
ASSERT(buf->base[i] == 'P');
134+
} else {
118135
ASSERT(nread == UV_EOF);
119136
printf("GOT EOF\n");
120137
uv_close((uv_handle_t*)tcp, close_cb);
@@ -134,6 +151,37 @@ static void write_cb(uv_write_t* req, int status) {
134151
}
135152

136153

154+
static void write1_cb(uv_write_t* req, int status) {
155+
uv_buf_t buf;
156+
int r;
157+
158+
ASSERT(req != NULL);
159+
if (status) {
160+
ASSERT(shutdown_cb_called);
161+
return;
162+
}
163+
164+
if (shutdown_requested)
165+
return;
166+
167+
buf = uv_buf_init("P", 1);
168+
r = uv_write(&write_req, req->handle, &buf, 1, write1_cb);
169+
ASSERT(r == 0);
170+
171+
write_cb_called++;
172+
}
173+
174+
175+
static void timer_cb(uv_timer_t* handle) {
176+
int r;
177+
178+
/* Shutdown on drain. */
179+
r = uv_shutdown(&shutdown_req, (uv_stream_t*) &client, shutdown_cb);
180+
ASSERT(r == 0);
181+
shutdown_requested++;
182+
}
183+
184+
137185
static void connect_cb(uv_connect_t* req, int status) {
138186
uv_buf_t buf = uv_buf_init("PING", 4);
139187
uv_stream_t* stream;
@@ -158,9 +206,35 @@ static void connect_cb(uv_connect_t* req, int status) {
158206
}
159207

160208

209+
static void connect1_cb(uv_connect_t* req, int status) {
210+
uv_buf_t buf;
211+
uv_stream_t* stream;
212+
int r;
213+
214+
ASSERT(req == &connect_req);
215+
ASSERT(status == 0);
216+
217+
stream = req->handle;
218+
connect_cb_called++;
219+
220+
r = uv_timer_init(uv_default_loop(), &tm);
221+
ASSERT(r == 0);
222+
223+
r = uv_timer_start(&tm, timer_cb, 2000, 0);
224+
ASSERT(r == 0);
225+
226+
buf = uv_buf_init("P", 1);
227+
r = uv_write(&write_req, stream, &buf, 1, write1_cb);
228+
ASSERT(r == 0);
229+
230+
/* Start reading */
231+
r = uv_read_start(stream, alloc_cb, read1_cb);
232+
ASSERT(r == 0);
233+
}
234+
235+
161236
TEST_IMPL(tcp_open) {
162237
struct sockaddr_in addr;
163-
uv_tcp_t client;
164238
uv_os_sock_t sock;
165239
int r;
166240

@@ -289,3 +363,38 @@ TEST_IMPL(tcp_open_connected) {
289363
MAKE_VALGRIND_HAPPY();
290364
return 0;
291365
}
366+
367+
368+
TEST_IMPL(tcp_write_ready) {
369+
struct sockaddr_in addr;
370+
uv_os_sock_t sock;
371+
int r;
372+
373+
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
374+
375+
startup();
376+
sock = create_tcp_socket();
377+
378+
r = uv_tcp_init(uv_default_loop(), &client);
379+
ASSERT(r == 0);
380+
381+
r = uv_tcp_open(&client, sock);
382+
ASSERT(r == 0);
383+
384+
r = uv_tcp_connect(&connect_req,
385+
&client,
386+
(const struct sockaddr*) &addr,
387+
connect1_cb);
388+
ASSERT(r == 0);
389+
390+
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
391+
392+
ASSERT(shutdown_cb_called == 1);
393+
ASSERT(shutdown_requested == 1);
394+
ASSERT(connect_cb_called == 1);
395+
ASSERT(write_cb_called > 0);
396+
ASSERT(close_cb_called == 1);
397+
398+
MAKE_VALGRIND_HAPPY();
399+
return 0;
400+
}

‎deps/uv/test/test.gyp

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
'test-poll-close-doesnt-corrupt-stack.c',
8181
'test-poll-closesocket.c',
8282
'test-poll-oob.c',
83+
'test-process-priority.c',
8384
'test-process-title.c',
8485
'test-process-title-threadsafe.c',
8586
'test-queue-foreach-delete.c',

0 commit comments

Comments
 (0)
Please sign in to comment.