noderb 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/noderb_extension/extconf.rb +4 -2
- data/ext/noderb_extension/libuv/AUTHORS +2 -0
- data/ext/noderb_extension/libuv/Makefile +1 -1
- data/ext/noderb_extension/libuv/common.gypi +51 -51
- data/ext/noderb_extension/libuv/config-mingw.mk +3 -9
- data/ext/noderb_extension/libuv/config-unix.mk +10 -1
- data/ext/noderb_extension/libuv/include/uv-private/uv-unix.h +3 -2
- data/ext/noderb_extension/libuv/include/uv-private/uv-win.h +7 -6
- data/ext/noderb_extension/libuv/include/uv.h +47 -13
- data/ext/noderb_extension/libuv/src/ares/config_netbsd/ares_config.h +510 -0
- data/ext/noderb_extension/libuv/src/unix/core.c +20 -65
- data/ext/noderb_extension/libuv/src/unix/darwin.c +1 -0
- data/ext/noderb_extension/libuv/src/unix/eio/config_netbsd.h +81 -0
- data/ext/noderb_extension/libuv/src/unix/error.c +9 -1
- data/ext/noderb_extension/libuv/src/unix/ev/config_netbsd.h +120 -0
- data/ext/noderb_extension/libuv/src/unix/fs.c +151 -21
- data/ext/noderb_extension/libuv/src/unix/internal.h +30 -0
- data/ext/noderb_extension/libuv/src/unix/netbsd.c +68 -0
- data/ext/noderb_extension/libuv/src/unix/pipe.c +20 -30
- data/ext/noderb_extension/libuv/src/unix/process.c +13 -0
- data/ext/noderb_extension/libuv/src/unix/stream.c +105 -63
- data/ext/noderb_extension/libuv/src/unix/tcp.c +75 -21
- data/ext/noderb_extension/libuv/src/unix/tty.c +69 -0
- data/ext/noderb_extension/libuv/src/unix/udp.c +31 -0
- data/ext/noderb_extension/libuv/src/uv-common.c +2 -0
- data/ext/noderb_extension/libuv/src/uv-common.h +0 -6
- data/ext/noderb_extension/libuv/src/win/cares.c +7 -7
- data/ext/noderb_extension/libuv/src/win/core.c +25 -17
- data/ext/noderb_extension/libuv/src/win/error.c +7 -0
- data/ext/noderb_extension/libuv/src/win/fs.c +587 -92
- data/ext/noderb_extension/libuv/src/win/getaddrinfo.c +3 -1
- data/ext/noderb_extension/libuv/src/win/handle.c +0 -17
- data/ext/noderb_extension/libuv/src/win/internal.h +15 -5
- data/ext/noderb_extension/libuv/src/win/loop-watcher.c +1 -1
- data/ext/noderb_extension/libuv/src/win/pipe.c +6 -0
- data/ext/noderb_extension/libuv/src/win/process.c +90 -43
- data/ext/noderb_extension/libuv/src/win/tcp.c +37 -4
- data/ext/noderb_extension/libuv/src/win/threads.c +81 -0
- data/ext/noderb_extension/libuv/src/win/timer.c +15 -15
- data/ext/noderb_extension/libuv/src/win/tty.c +37 -0
- data/ext/noderb_extension/libuv/src/win/udp.c +8 -2
- data/ext/noderb_extension/libuv/src/win/winapi.c +12 -0
- data/ext/noderb_extension/libuv/src/win/winapi.h +1146 -1015
- data/ext/noderb_extension/libuv/test/benchmark-ares.c +0 -1
- data/ext/noderb_extension/libuv/test/benchmark-getaddrinfo.c +0 -1
- data/ext/noderb_extension/libuv/test/benchmark-ping-pongs.c +0 -1
- data/ext/noderb_extension/libuv/test/benchmark-pound.c +0 -1
- data/ext/noderb_extension/libuv/test/benchmark-pump.c +4 -6
- data/ext/noderb_extension/libuv/test/benchmark-spawn.c +0 -1
- data/ext/noderb_extension/libuv/test/benchmark-udp-packet-storm.c +0 -1
- data/ext/noderb_extension/libuv/test/dns-server.c +2 -2
- data/ext/noderb_extension/libuv/test/echo-server.c +4 -5
- data/ext/noderb_extension/libuv/test/run-tests.c +0 -2
- data/ext/noderb_extension/libuv/test/test-async.c +0 -2
- data/ext/noderb_extension/libuv/test/test-callback-stack.c +0 -2
- data/ext/noderb_extension/libuv/test/test-connection-fail.c +3 -5
- data/ext/noderb_extension/libuv/test/test-delayed-accept.c +2 -3
- data/ext/noderb_extension/libuv/test/test-fs.c +578 -42
- data/ext/noderb_extension/libuv/test/test-get-currentexe.c +12 -2
- data/ext/noderb_extension/libuv/test/test-getaddrinfo.c +10 -5
- data/ext/noderb_extension/libuv/test/test-gethostbyname.c +0 -2
- data/ext/noderb_extension/libuv/test/test-getsockname.c +92 -72
- data/ext/noderb_extension/libuv/test/test-idle.c +0 -3
- data/ext/noderb_extension/libuv/test/test-list.h +13 -0
- data/ext/noderb_extension/libuv/test/test-loop-handles.c +0 -3
- data/ext/noderb_extension/libuv/test/test-ping-pong.c +13 -19
- data/ext/noderb_extension/libuv/test/test-pipe-bind-error.c +0 -12
- data/ext/noderb_extension/libuv/test/test-ref.c +0 -7
- data/ext/noderb_extension/libuv/test/test-shutdown-eof.c +3 -3
- data/ext/noderb_extension/libuv/test/test-spawn.c +2 -11
- data/ext/noderb_extension/libuv/test/test-tcp-bind-error.c +0 -19
- data/ext/noderb_extension/libuv/test/test-tcp-bind6-error.c +0 -15
- data/ext/noderb_extension/libuv/test/test-tcp-close.c +129 -0
- data/ext/noderb_extension/libuv/test/test-tcp-writealot.c +0 -3
- data/ext/noderb_extension/libuv/test/test-threadpool.c +0 -2
- data/ext/noderb_extension/libuv/test/test-timer-again.c +0 -3
- data/ext/noderb_extension/libuv/test/test-timer.c +0 -2
- data/ext/noderb_extension/libuv/test/test-udp-dgram-too-big.c +0 -2
- data/ext/noderb_extension/libuv/test/test-udp-ipv6.c +0 -2
- data/ext/noderb_extension/libuv/test/test-udp-send-and-recv.c +0 -2
- data/ext/noderb_extension/libuv/uv.gyp +18 -2
- data/ext/noderb_extension/noderb_fs.c +1 -2
- data/lib/noderb/version.rb +1 -1
- metadata +10 -2
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
/*
|
|
30
30
|
* MinGW is missing this
|
|
31
31
|
*/
|
|
32
|
-
#
|
|
32
|
+
#if !defined(_MSC_VER) && !defined(__MINGW64_VERSION_MAJOR)
|
|
33
33
|
typedef struct addrinfoW {
|
|
34
34
|
int ai_flags;
|
|
35
35
|
int ai_family;
|
|
@@ -255,6 +255,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
|
|
255
255
|
goto error;
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
+
uv_req_init(loop, (uv_req_t*)handle);
|
|
259
|
+
|
|
258
260
|
handle->getaddrinfo_cb = getaddrinfo_cb;
|
|
259
261
|
handle->res = NULL;
|
|
260
262
|
handle->type = UV_GETADDRINFO;
|
|
@@ -39,23 +39,6 @@ int uv_is_active(uv_handle_t* handle) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
int uv_getsockname(uv_handle_t* handle, struct sockaddr* name, int* namelen) {
|
|
43
|
-
uv_loop_t* loop = handle->loop;
|
|
44
|
-
|
|
45
|
-
switch (handle->type) {
|
|
46
|
-
case UV_TCP:
|
|
47
|
-
return uv_tcp_getsockname(loop, (uv_tcp_t*) handle, name, namelen);
|
|
48
|
-
|
|
49
|
-
case UV_UDP:
|
|
50
|
-
return uv_udp_getsockname(loop, (uv_udp_t*) handle, name, namelen);
|
|
51
|
-
|
|
52
|
-
default:
|
|
53
|
-
uv_set_sys_error(loop, WSAENOTSOCK);
|
|
54
|
-
return -1;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
42
|
void uv_close(uv_handle_t* handle, uv_close_cb cb) {
|
|
60
43
|
uv_tcp_t* tcp;
|
|
61
44
|
uv_pipe_t* pipe;
|
|
@@ -123,8 +123,6 @@ int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
|
|
|
123
123
|
uv_read_cb read_cb);
|
|
124
124
|
int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
|
|
125
125
|
uv_buf_t bufs[], int bufcnt, uv_write_cb cb);
|
|
126
|
-
int uv_tcp_getsockname(uv_loop_t* loop, uv_tcp_t* handle,
|
|
127
|
-
struct sockaddr* name, int* namelen);
|
|
128
126
|
|
|
129
127
|
void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req);
|
|
130
128
|
void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|
@@ -140,9 +138,6 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
|
|
|
140
138
|
/*
|
|
141
139
|
* UDP
|
|
142
140
|
*/
|
|
143
|
-
int uv_udp_getsockname(uv_loop_t* loop, uv_udp_t* handle,
|
|
144
|
-
struct sockaddr* name, int* namelen);
|
|
145
|
-
|
|
146
141
|
void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req);
|
|
147
142
|
void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
|
|
148
143
|
uv_udp_send_t* req);
|
|
@@ -284,4 +279,19 @@ void uv_winsock_init();
|
|
|
284
279
|
int uv_ntstatus_to_winsock_error(NTSTATUS status);
|
|
285
280
|
|
|
286
281
|
|
|
282
|
+
/* Threads and synchronization */
|
|
283
|
+
typedef struct uv_once_s {
|
|
284
|
+
unsigned char ran;
|
|
285
|
+
/* The actual event handle must be aligned to sizeof(HANDLE), so in */
|
|
286
|
+
/* practice it might overlap padding a little. */
|
|
287
|
+
HANDLE event;
|
|
288
|
+
HANDLE padding;
|
|
289
|
+
} uv_once_t;
|
|
290
|
+
|
|
291
|
+
#define UV_ONCE_INIT \
|
|
292
|
+
{ 0, NULL, NULL }
|
|
293
|
+
|
|
294
|
+
void uv_once(uv_once_t* guard, void (*callback)(void));
|
|
295
|
+
|
|
296
|
+
|
|
287
297
|
#endif /* UV_WIN_INTERNAL_H_ */
|
|
@@ -61,12 +61,9 @@ static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
|
|
|
61
61
|
handle->wait_handle = INVALID_HANDLE_VALUE;
|
|
62
62
|
handle->process_handle = INVALID_HANDLE_VALUE;
|
|
63
63
|
handle->close_handle = INVALID_HANDLE_VALUE;
|
|
64
|
-
handle->
|
|
65
|
-
handle->
|
|
66
|
-
handle->
|
|
67
|
-
handle->stdio_pipes[1].child_pipe = INVALID_HANDLE_VALUE;
|
|
68
|
-
handle->stdio_pipes[2].server_pipe = NULL;
|
|
69
|
-
handle->stdio_pipes[2].child_pipe = INVALID_HANDLE_VALUE;
|
|
64
|
+
handle->child_stdio[0] = INVALID_HANDLE_VALUE;
|
|
65
|
+
handle->child_stdio[1] = INVALID_HANDLE_VALUE;
|
|
66
|
+
handle->child_stdio[2] = INVALID_HANDLE_VALUE;
|
|
70
67
|
|
|
71
68
|
uv_req_init(loop, (uv_req_t*)&handle->exit_req);
|
|
72
69
|
handle->exit_req.type = UV_PROCESS_EXIT;
|
|
@@ -625,7 +622,7 @@ static DWORD WINAPI spawn_failure(void* data) {
|
|
|
625
622
|
char unknown[] = "unknown error\n";
|
|
626
623
|
uv_process_t* process = (uv_process_t*) data;
|
|
627
624
|
uv_loop_t* loop = process->loop;
|
|
628
|
-
HANDLE child_stderr = process->
|
|
625
|
+
HANDLE child_stderr = process->child_stdio[2];
|
|
629
626
|
char* buf = NULL;
|
|
630
627
|
DWORD count, written;
|
|
631
628
|
|
|
@@ -657,18 +654,23 @@ static DWORD WINAPI spawn_failure(void* data) {
|
|
|
657
654
|
}
|
|
658
655
|
|
|
659
656
|
|
|
660
|
-
|
|
661
|
-
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
|
|
657
|
+
static void close_child_stdio(uv_process_t* process) {
|
|
662
658
|
int i;
|
|
663
|
-
|
|
659
|
+
HANDLE handle;
|
|
664
660
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
if (handle
|
|
668
|
-
CloseHandle(handle
|
|
669
|
-
|
|
661
|
+
for (i = 0; i < COUNTOF(process->child_stdio); i++) {
|
|
662
|
+
handle = process->child_stdio[i];
|
|
663
|
+
if (handle != NULL && handle != INVALID_HANDLE_VALUE) {
|
|
664
|
+
CloseHandle(handle);
|
|
665
|
+
process->child_stdio[i] = INVALID_HANDLE_VALUE;
|
|
670
666
|
}
|
|
671
667
|
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
/* Called on main thread after a child process has exited. */
|
|
672
|
+
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
|
|
673
|
+
DWORD exit_code;
|
|
672
674
|
|
|
673
675
|
/* Unregister from process notification. */
|
|
674
676
|
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
|
|
@@ -686,6 +688,10 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
|
|
|
686
688
|
CloseHandle(handle->process_handle);
|
|
687
689
|
handle->process_handle = INVALID_HANDLE_VALUE;
|
|
688
690
|
} else {
|
|
691
|
+
/* We probably left the child stdio handles open to report the error */
|
|
692
|
+
/* asynchronously, so close them now. */
|
|
693
|
+
close_child_stdio(handle);
|
|
694
|
+
|
|
689
695
|
/* The process never even started in the first place. */
|
|
690
696
|
exit_code = 127;
|
|
691
697
|
}
|
|
@@ -805,13 +811,45 @@ done:
|
|
|
805
811
|
}
|
|
806
812
|
|
|
807
813
|
|
|
814
|
+
static int duplicate_std_handle(uv_loop_t* loop, DWORD id, HANDLE* dup) {
|
|
815
|
+
HANDLE handle;
|
|
816
|
+
HANDLE current_process = GetCurrentProcess();
|
|
817
|
+
|
|
818
|
+
handle = GetStdHandle(id);
|
|
819
|
+
|
|
820
|
+
if (handle == NULL) {
|
|
821
|
+
*dup = NULL;
|
|
822
|
+
return 0;
|
|
823
|
+
} else if (handle == INVALID_HANDLE_VALUE) {
|
|
824
|
+
*dup = INVALID_HANDLE_VALUE;
|
|
825
|
+
uv_set_sys_error(loop, GetLastError());
|
|
826
|
+
return -1;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
if (!DuplicateHandle(current_process,
|
|
830
|
+
handle,
|
|
831
|
+
current_process,
|
|
832
|
+
dup,
|
|
833
|
+
0,
|
|
834
|
+
TRUE,
|
|
835
|
+
DUPLICATE_SAME_ACCESS)) {
|
|
836
|
+
*dup = INVALID_HANDLE_VALUE;
|
|
837
|
+
uv_set_sys_error(loop, GetLastError());
|
|
838
|
+
return -1;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
return 0;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
|
|
808
845
|
int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
|
809
846
|
uv_process_options_t options) {
|
|
810
|
-
int err = 0,
|
|
847
|
+
int err = 0, keep_child_stdio_open = 0;
|
|
811
848
|
wchar_t* path;
|
|
812
849
|
int size;
|
|
813
850
|
BOOL result;
|
|
814
851
|
wchar_t* application_path, *application, *arguments, *env, *cwd;
|
|
852
|
+
HANDLE* child_stdio = process->child_stdio;
|
|
815
853
|
STARTUPINFOW startup;
|
|
816
854
|
PROCESS_INFORMATION info;
|
|
817
855
|
|
|
@@ -864,41 +902,41 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
|
|
864
902
|
err = uv_create_stdio_pipe_pair(
|
|
865
903
|
loop,
|
|
866
904
|
options.stdin_stream,
|
|
867
|
-
&
|
|
905
|
+
&child_stdio[0],
|
|
868
906
|
PIPE_ACCESS_OUTBOUND,
|
|
869
907
|
GENERIC_READ | FILE_WRITE_ATTRIBUTES);
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
908
|
+
} else {
|
|
909
|
+
err = duplicate_std_handle(loop, STD_INPUT_HANDLE, &child_stdio[0]);
|
|
910
|
+
}
|
|
911
|
+
if (err) {
|
|
912
|
+
goto done;
|
|
875
913
|
}
|
|
876
914
|
|
|
877
915
|
if (options.stdout_stream) {
|
|
878
916
|
err = uv_create_stdio_pipe_pair(
|
|
879
917
|
loop, options.stdout_stream,
|
|
880
|
-
&
|
|
918
|
+
&child_stdio[1],
|
|
881
919
|
PIPE_ACCESS_INBOUND,
|
|
882
920
|
GENERIC_WRITE);
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
921
|
+
} else {
|
|
922
|
+
err = duplicate_std_handle(loop, STD_OUTPUT_HANDLE, &child_stdio[1]);
|
|
923
|
+
}
|
|
924
|
+
if (err) {
|
|
925
|
+
goto done;
|
|
888
926
|
}
|
|
889
927
|
|
|
890
928
|
if (options.stderr_stream) {
|
|
891
929
|
err = uv_create_stdio_pipe_pair(
|
|
892
930
|
loop,
|
|
893
931
|
options.stderr_stream,
|
|
894
|
-
&
|
|
932
|
+
&child_stdio[2],
|
|
895
933
|
PIPE_ACCESS_INBOUND,
|
|
896
934
|
GENERIC_WRITE);
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
935
|
+
} else {
|
|
936
|
+
err = duplicate_std_handle(loop, STD_ERROR_HANDLE, &child_stdio[2]);
|
|
937
|
+
}
|
|
938
|
+
if (err) {
|
|
939
|
+
goto done;
|
|
902
940
|
}
|
|
903
941
|
|
|
904
942
|
startup.cb = sizeof(startup);
|
|
@@ -908,9 +946,9 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
|
|
908
946
|
startup.dwFlags = STARTF_USESTDHANDLES;
|
|
909
947
|
startup.cbReserved2 = 0;
|
|
910
948
|
startup.lpReserved2 = NULL;
|
|
911
|
-
startup.hStdInput =
|
|
912
|
-
startup.hStdOutput =
|
|
913
|
-
startup.hStdError =
|
|
949
|
+
startup.hStdInput = child_stdio[0];
|
|
950
|
+
startup.hStdOutput = child_stdio[1];
|
|
951
|
+
startup.hStdError = child_stdio[2];
|
|
914
952
|
|
|
915
953
|
if (CreateProcessW(application_path,
|
|
916
954
|
arguments,
|
|
@@ -942,6 +980,7 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
|
|
942
980
|
/* succeeded, and start a thread instead that prints an error */
|
|
943
981
|
/* to the child's intended stderr. */
|
|
944
982
|
process->spawn_errno = GetLastError();
|
|
983
|
+
keep_child_stdio_open = 1;
|
|
945
984
|
if (!QueueUserWorkItem(spawn_failure, process, WT_EXECUTEDEFAULT)) {
|
|
946
985
|
uv_fatal_error(GetLastError(), "QueueUserWorkItem");
|
|
947
986
|
}
|
|
@@ -957,14 +996,22 @@ done:
|
|
|
957
996
|
free(env);
|
|
958
997
|
free(path);
|
|
959
998
|
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
999
|
+
/* Under normal circumstances we should close the stdio handles now - */
|
|
1000
|
+
/* the child now has its own duplicates, or something went horribly wrong. */
|
|
1001
|
+
/* The only exception is when CreateProcess has failed, then we actually */
|
|
1002
|
+
/* need to keep the stdio handles to report the error asynchronously. */
|
|
1003
|
+
if (!keep_child_stdio_open) {
|
|
1004
|
+
close_child_stdio(process);
|
|
1005
|
+
} else {
|
|
1006
|
+
/* We're keeping the handles open, the thread pool is going to have */
|
|
1007
|
+
/* it's way with them. But at least make them noninheritable. */
|
|
1008
|
+
int i;
|
|
1009
|
+
for (i = 0; i < COUNTOF(process->child_stdio); i++) {
|
|
1010
|
+
SetHandleInformation(child_stdio[i], HANDLE_FLAG_INHERIT, 0);
|
|
966
1011
|
}
|
|
1012
|
+
}
|
|
967
1013
|
|
|
1014
|
+
if (err) {
|
|
968
1015
|
if (process->wait_handle != INVALID_HANDLE_VALUE) {
|
|
969
1016
|
UnregisterWait(process->wait_handle);
|
|
970
1017
|
process->wait_handle = INVALID_HANDLE_VALUE;
|
|
@@ -419,6 +419,8 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
|
|
|
419
419
|
rv = -1;
|
|
420
420
|
} else {
|
|
421
421
|
uv_connection_init((uv_stream_t*) client);
|
|
422
|
+
/* AcceptEx() implicitly binds the accepted socket. */
|
|
423
|
+
client->flags |= UV_HANDLE_BOUND;
|
|
422
424
|
}
|
|
423
425
|
|
|
424
426
|
/* Prepare the req to pick up a new connection */
|
|
@@ -573,12 +575,18 @@ int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
|
|
|
573
575
|
}
|
|
574
576
|
|
|
575
577
|
|
|
576
|
-
int uv_tcp_getsockname(
|
|
577
|
-
|
|
578
|
+
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
|
|
579
|
+
int* namelen) {
|
|
580
|
+
uv_loop_t* loop = handle->loop;
|
|
578
581
|
int result;
|
|
579
582
|
|
|
580
|
-
if (handle->flags &
|
|
581
|
-
uv_set_sys_error(loop,
|
|
583
|
+
if (!(handle->flags & UV_HANDLE_BOUND)) {
|
|
584
|
+
uv_set_sys_error(loop, WSAEINVAL);
|
|
585
|
+
return -1;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if (handle->flags & UV_HANDLE_BIND_ERROR) {
|
|
589
|
+
loop->last_error = handle->bind_error;
|
|
582
590
|
return -1;
|
|
583
591
|
}
|
|
584
592
|
|
|
@@ -592,6 +600,31 @@ int uv_tcp_getsockname(uv_loop_t* loop, uv_tcp_t* handle,
|
|
|
592
600
|
}
|
|
593
601
|
|
|
594
602
|
|
|
603
|
+
int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
|
|
604
|
+
int* namelen) {
|
|
605
|
+
uv_loop_t* loop = handle->loop;
|
|
606
|
+
int result;
|
|
607
|
+
|
|
608
|
+
if (!(handle->flags & UV_HANDLE_BOUND)) {
|
|
609
|
+
uv_set_sys_error(loop, WSAEINVAL);
|
|
610
|
+
return -1;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
if (handle->flags & UV_HANDLE_BIND_ERROR) {
|
|
614
|
+
loop->last_error = handle->bind_error;
|
|
615
|
+
return -1;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
result = getpeername(handle->socket, name, namelen);
|
|
619
|
+
if (result != 0) {
|
|
620
|
+
uv_set_sys_error(loop, WSAGetLastError());
|
|
621
|
+
return -1;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
return 0;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
|
|
595
628
|
int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
|
|
596
629
|
uv_buf_t bufs[], int bufcnt, uv_write_cb cb) {
|
|
597
630
|
int result;
|
|
@@ -0,0 +1,81 @@
|
|
|
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 <assert.h>
|
|
23
|
+
|
|
24
|
+
#include "uv.h"
|
|
25
|
+
#include "../uv-common.h"
|
|
26
|
+
#include "internal.h"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
#ifdef _MSC_VER /* msvc */
|
|
30
|
+
# define NOINLINE __declspec (noinline)
|
|
31
|
+
#else /* gcc */
|
|
32
|
+
# define NOINLINE __attribute__ ((noinline))
|
|
33
|
+
#endif
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
static NOINLINE void uv__once_inner(uv_once_t* guard,
|
|
37
|
+
void (*callback)(void)) {
|
|
38
|
+
DWORD result;
|
|
39
|
+
HANDLE existing_event, created_event;
|
|
40
|
+
HANDLE* event_ptr;
|
|
41
|
+
|
|
42
|
+
/* Fetch and align event_ptr */
|
|
43
|
+
event_ptr = (HANDLE*) (((uintptr_t) &guard->event + (sizeof(HANDLE) - 1)) &
|
|
44
|
+
~(sizeof(HANDLE) - 1));
|
|
45
|
+
|
|
46
|
+
created_event = CreateEvent(NULL, 1, 0, NULL);
|
|
47
|
+
if (created_event == 0) {
|
|
48
|
+
/* Could fail in a low-memory situation? */
|
|
49
|
+
uv_fatal_error(GetLastError(), "CreateEvent");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
existing_event = InterlockedCompareExchangePointer(event_ptr,
|
|
53
|
+
created_event,
|
|
54
|
+
NULL);
|
|
55
|
+
|
|
56
|
+
if (existing_event == NULL) {
|
|
57
|
+
/* We won the race */
|
|
58
|
+
callback();
|
|
59
|
+
|
|
60
|
+
result = SetEvent(created_event);
|
|
61
|
+
assert(result);
|
|
62
|
+
guard->ran = 1;
|
|
63
|
+
|
|
64
|
+
} else {
|
|
65
|
+
/* We lost the race. Destroy the event we created and wait for the */
|
|
66
|
+
/* existing one to become signaled. */
|
|
67
|
+
CloseHandle(created_event);
|
|
68
|
+
result = WaitForSingleObject(existing_event, INFINITE);
|
|
69
|
+
assert(result == WAIT_OBJECT_0);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
void uv_once(uv_once_t* guard, void (*callback)(void)) {
|
|
75
|
+
/* Fast case - avoid WaitForSingleObject. */
|
|
76
|
+
if (guard->ran) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
uv__once_inner(guard, callback);
|
|
81
|
+
}
|