annotate third_party/libuv/src/unix/stream.c @ 279:b3b547563ec7

Add Google connector service and agent wiki Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code. Co-authored-by: Copilot <[email protected]> Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 22:22:36 -0700
parents 948de3f54cea
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
160
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
2 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
4 * of this software and associated documentation files (the "Software"), to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
5 * deal in the Software without restriction, including without limitation the
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
7 * sell copies of the Software, and to permit persons to whom the Software is
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
8 * furnished to do so, subject to the following conditions:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
9 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
10 * The above copyright notice and this permission notice shall be included in
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
11 * all copies or substantial portions of the Software.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
12 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
19 * IN THE SOFTWARE.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
20 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
21
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
22 #include "uv.h"
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
23 #include "internal.h"
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
24
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
25 #include <stdio.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
26 #include <stdlib.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
27 #include <string.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
28 #include <assert.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
29 #include <errno.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
30
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
31 #include <sys/types.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
32 #include <sys/socket.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
33 #include <sys/uio.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
34 #include <sys/un.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
35 #include <unistd.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
36 #include <limits.h> /* IOV_MAX */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
37
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
38 #if defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
39 # include <sys/event.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
40 # include <sys/time.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
41 # include <sys/select.h>
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
42
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
43 /* Forward declaration */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
44 typedef struct uv__stream_select_s uv__stream_select_t;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
45
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
46 struct uv__stream_select_s {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
47 uv_stream_t* stream;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
48 uv_thread_t thread;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
49 uv_sem_t close_sem;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
50 uv_sem_t async_sem;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
51 uv_async_t async;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
52 int events;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
53 int fake_fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
54 int int_fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
55 int fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
56 fd_set* sread;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
57 size_t sread_sz;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
58 fd_set* swrite;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
59 size_t swrite_sz;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
60 };
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
61 #endif /* defined(__APPLE__) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
62
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
63 union uv__cmsg {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
64 struct cmsghdr hdr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
65 /* This cannot be larger because of the IBMi PASE limitation that
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
66 * the total size of control messages cannot exceed 256 bytes.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
67 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
68 char pad[256];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
69 };
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
70
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
71 STATIC_ASSERT(256 == sizeof(union uv__cmsg));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
72
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
73 static void uv__stream_connect(uv_stream_t*);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
74 static void uv__write(uv_stream_t* stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
75 static void uv__read(uv_stream_t* stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
76 static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
77 static void uv__write_callbacks(uv_stream_t* stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
78 static size_t uv__write_req_size(uv_write_t* req);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
79 static void uv__drain(uv_stream_t* stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
80
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
81
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
82 void uv__stream_init(uv_loop_t* loop,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
83 uv_stream_t* stream,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
84 uv_handle_type type) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
85 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
86
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
87 uv__handle_init(loop, (uv_handle_t*)stream, type);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
88 stream->read_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
89 stream->alloc_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
90 stream->close_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
91 stream->connection_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
92 stream->connect_req = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
93 stream->shutdown_req = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
94 stream->accepted_fd = -1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
95 stream->queued_fds = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
96 stream->delayed_error = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
97 uv__queue_init(&stream->write_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
98 uv__queue_init(&stream->write_completed_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
99 stream->write_queue_size = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
100
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
101 if (loop->emfile_fd == -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
102 err = uv__open_cloexec("/dev/null", O_RDONLY);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
103 if (err < 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
104 /* In the rare case that "/dev/null" isn't mounted open "/"
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
105 * instead.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
106 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
107 err = uv__open_cloexec("/", O_RDONLY);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
108 if (err >= 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
109 loop->emfile_fd = err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
110 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
111
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
112 #if defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
113 stream->select = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
114 #endif /* defined(__APPLE_) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
115
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
116 uv__io_init(&stream->io_watcher, uv__stream_io, -1);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
117 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
118
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
119
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
120 static void uv__stream_osx_interrupt_select(uv_stream_t* stream) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
121 #if defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
122 /* Notify select() thread about state change */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
123 uv__stream_select_t* s;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
124 int r;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
125
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
126 s = stream->select;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
127 if (s == NULL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
128 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
129
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
130 /* Interrupt select() loop
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
131 * NOTE: fake_fd and int_fd are socketpair(), thus writing to one will
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
132 * emit read event on other side
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
133 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
134 do
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
135 r = write(s->fake_fd, "x", 1);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
136 while (r == -1 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
137
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
138 assert(r == 1);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
139 #else /* !defined(__APPLE__) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
140 /* No-op on any other platform */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
141 #endif /* !defined(__APPLE__) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
142 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
143
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
144
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
145 #if defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
146 static void uv__stream_osx_select(void* arg) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
147 uv_stream_t* stream;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
148 uv__stream_select_t* s;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
149 char buf[1024];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
150 int events;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
151 int fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
152 int r;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
153 int max_fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
154
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
155 stream = arg;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
156 s = stream->select;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
157 fd = s->fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
158
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
159 if (fd > s->int_fd)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
160 max_fd = fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
161 else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
162 max_fd = s->int_fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
163
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
164 for (;;) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
165 /* Terminate on semaphore */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
166 if (uv_sem_trywait(&s->close_sem) == 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
167 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
168
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
169 /* Watch fd using select(2) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
170 memset(s->sread, 0, s->sread_sz);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
171 memset(s->swrite, 0, s->swrite_sz);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
172
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
173 if (uv__io_active(&stream->io_watcher, POLLIN))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
174 FD_SET(fd, s->sread);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
175 if (uv__io_active(&stream->io_watcher, POLLOUT))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
176 FD_SET(fd, s->swrite);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
177 FD_SET(s->int_fd, s->sread);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
178
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
179 /* Wait indefinitely for fd events */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
180 r = select(max_fd + 1, s->sread, s->swrite, NULL, NULL);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
181 if (r == -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
182 if (errno == EINTR)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
183 continue;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
184
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
185 /* XXX: Possible?! */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
186 abort();
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
187 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
188
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
189 /* Ignore timeouts */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
190 if (r == 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
191 continue;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
192
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
193 /* Empty socketpair's buffer in case of interruption */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
194 if (FD_ISSET(s->int_fd, s->sread))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
195 for (;;) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
196 r = read(s->int_fd, buf, sizeof(buf));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
197
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
198 if (r == sizeof(buf))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
199 continue;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
200
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
201 if (r != -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
202 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
203
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
204 if (errno == EAGAIN || errno == EWOULDBLOCK)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
205 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
206
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
207 if (errno == EINTR)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
208 continue;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
209
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
210 abort();
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
211 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
212
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
213 /* Handle events */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
214 events = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
215 if (FD_ISSET(fd, s->sread))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
216 events |= POLLIN;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
217 if (FD_ISSET(fd, s->swrite))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
218 events |= POLLOUT;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
219
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
220 assert(events != 0 || FD_ISSET(s->int_fd, s->sread));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
221 if (events != 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
222 ACCESS_ONCE(int, s->events) = events;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
223
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
224 uv_async_send(&s->async);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
225 uv_sem_wait(&s->async_sem);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
226
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
227 /* Should be processed at this stage */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
228 assert((s->events == 0) || (stream->flags & UV_HANDLE_CLOSING));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
229 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
230 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
231 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
232
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
233
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
234 static void uv__stream_osx_select_cb(uv_async_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
235 uv__stream_select_t* s;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
236 uv_stream_t* stream;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
237 int events;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
238
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
239 s = container_of(handle, uv__stream_select_t, async);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
240 stream = s->stream;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
241
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
242 /* Get and reset stream's events */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
243 events = s->events;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
244 ACCESS_ONCE(int, s->events) = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
245
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
246 assert(events != 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
247 assert(events == (events & (POLLIN | POLLOUT)));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
248
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
249 /* Invoke callback on event-loop */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
250 if ((events & POLLIN) && uv__io_active(&stream->io_watcher, POLLIN))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
251 uv__stream_io(stream->loop, &stream->io_watcher, POLLIN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
252
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
253 if ((events & POLLOUT) && uv__io_active(&stream->io_watcher, POLLOUT))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
254 uv__stream_io(stream->loop, &stream->io_watcher, POLLOUT);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
255
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
256 if (stream->flags & UV_HANDLE_CLOSING)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
257 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
258
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
259 /* NOTE: It is important to do it here, otherwise `select()` might be called
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
260 * before the actual `uv__read()`, leading to the blocking syscall
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
261 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
262 uv_sem_post(&s->async_sem);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
263 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
264
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
265
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
266 static void uv__stream_osx_cb_close(uv_handle_t* async) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
267 uv__stream_select_t* s;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
268
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
269 s = container_of(async, uv__stream_select_t, async);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
270 uv__free(s);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
271 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
272
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
273
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
274 int uv__stream_try_select(uv_stream_t* stream, int* fd) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
275 /*
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
276 * kqueue doesn't work with some files from /dev mount on osx.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
277 * select(2) in separate thread for those fds
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
278 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
279
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
280 struct kevent filter[1];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
281 struct kevent events[1];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
282 struct timespec timeout;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
283 uv__stream_select_t* s;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
284 int fds[2];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
285 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
286 int ret;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
287 int kq;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
288 int old_fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
289 int max_fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
290 size_t sread_sz;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
291 size_t swrite_sz;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
292
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
293 kq = kqueue();
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
294 if (kq == -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
295 perror("(libuv) kqueue()");
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
296 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
297 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
298
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
299 EV_SET(&filter[0], *fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
300
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
301 /* Use small timeout, because we only want to capture EINVALs */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
302 timeout.tv_sec = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
303 timeout.tv_nsec = 1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
304
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
305 do
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
306 ret = kevent(kq, filter, 1, events, 1, &timeout);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
307 while (ret == -1 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
308
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
309 uv__close(kq);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
310
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
311 if (ret == -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
312 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
313
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
314 if (ret == 0 || (events[0].flags & EV_ERROR) == 0 || events[0].data != EINVAL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
315 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
316
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
317 /* At this point we definitely know that this fd won't work with kqueue */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
318
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
319 /*
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
320 * Create fds for io watcher and to interrupt the select() loop.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
321 * NOTE: do it ahead of malloc below to allocate enough space for fd_sets
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
322 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
323 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
324 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
325
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
326 max_fd = *fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
327 if (fds[1] > max_fd)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
328 max_fd = fds[1];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
329
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
330 sread_sz = ROUND_UP(max_fd + 1, sizeof(uint32_t) * NBBY) / NBBY;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
331 swrite_sz = sread_sz;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
332
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
333 s = uv__malloc(sizeof(*s) + sread_sz + swrite_sz);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
334 if (s == NULL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
335 err = UV_ENOMEM;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
336 goto failed_malloc;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
337 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
338
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
339 s->events = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
340 s->fd = *fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
341 s->sread = (fd_set*) ((char*) s + sizeof(*s));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
342 s->sread_sz = sread_sz;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
343 s->swrite = (fd_set*) ((char*) s->sread + sread_sz);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
344 s->swrite_sz = swrite_sz;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
345
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
346 err = uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
347 if (err)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
348 goto failed_async_init;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
349
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
350 s->async.flags |= UV_HANDLE_INTERNAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
351 uv__handle_unref(&s->async);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
352
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
353 err = uv_sem_init(&s->close_sem, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
354 if (err != 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
355 goto failed_close_sem_init;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
356
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
357 err = uv_sem_init(&s->async_sem, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
358 if (err != 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
359 goto failed_async_sem_init;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
360
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
361 s->fake_fd = fds[0];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
362 s->int_fd = fds[1];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
363
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
364 old_fd = *fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
365 s->stream = stream;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
366 stream->select = s;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
367 *fd = s->fake_fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
368
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
369 err = uv_thread_create(&s->thread, uv__stream_osx_select, stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
370 if (err != 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
371 goto failed_thread_create;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
372
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
373 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
374
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
375 failed_thread_create:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
376 s->stream = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
377 stream->select = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
378 *fd = old_fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
379
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
380 uv_sem_destroy(&s->async_sem);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
381
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
382 failed_async_sem_init:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
383 uv_sem_destroy(&s->close_sem);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
384
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
385 failed_close_sem_init:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
386 uv__close(fds[0]);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
387 uv__close(fds[1]);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
388 uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
389 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
390
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
391 failed_async_init:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
392 uv__free(s);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
393
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
394 failed_malloc:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
395 uv__close(fds[0]);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
396 uv__close(fds[1]);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
397
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
398 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
399 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
400 #endif /* defined(__APPLE__) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
401
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
402
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
403 int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
404 #if defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
405 int enable;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
406 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
407
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
408 if (!(stream->io_watcher.fd == -1 || stream->io_watcher.fd == fd))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
409 return UV_EBUSY;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
410
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
411 assert(fd >= 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
412 stream->flags |= flags;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
413
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
414 if (stream->type == UV_TCP) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
415 if ((stream->flags & UV_HANDLE_TCP_NODELAY) && uv__tcp_nodelay(fd, 1))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
416 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
417
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
418 /* TODO Use delay the user passed in. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
419 if ((stream->flags & UV_HANDLE_TCP_KEEPALIVE) &&
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
420 uv__tcp_keepalive(fd, 1, 60)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
421 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
422 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
423 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
424
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
425 #if defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
426 enable = 1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
427 if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) &&
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
428 errno != ENOTSOCK &&
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
429 errno != EINVAL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
430 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
431 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
432 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
433
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
434 stream->io_watcher.fd = fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
435
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
436 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
437 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
438
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
439
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
440 void uv__stream_flush_write_queue(uv_stream_t* stream, int error) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
441 uv_write_t* req;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
442 struct uv__queue* q;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
443 while (!uv__queue_empty(&stream->write_queue)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
444 q = uv__queue_head(&stream->write_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
445 uv__queue_remove(q);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
446
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
447 req = uv__queue_data(q, uv_write_t, queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
448 req->error = error;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
449
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
450 uv__queue_insert_tail(&stream->write_completed_queue, &req->queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
451 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
452 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
453
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
454
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
455 void uv__stream_destroy(uv_stream_t* stream) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
456 assert(!uv__io_active(&stream->io_watcher, POLLIN | POLLOUT));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
457 assert(stream->flags & UV_HANDLE_CLOSED);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
458
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
459 if (stream->connect_req) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
460 uv__req_unregister(stream->loop);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
461 stream->connect_req->cb(stream->connect_req, UV_ECANCELED);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
462 stream->connect_req = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
463 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
464
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
465 uv__stream_flush_write_queue(stream, UV_ECANCELED);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
466 uv__write_callbacks(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
467 uv__drain(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
468
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
469 assert(stream->write_queue_size == 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
470 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
471
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
472
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
473 /* Implements a best effort approach to mitigating accept() EMFILE errors.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
474 * We have a spare file descriptor stashed away that we close to get below
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
475 * the EMFILE limit. Next, we accept all pending connections and close them
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
476 * immediately to signal the clients that we're overloaded - and we are, but
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
477 * we still keep on trucking.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
478 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
479 * There is one caveat: it's not reliable in a multi-threaded environment.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
480 * The file descriptor limit is per process. Our party trick fails if another
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
481 * thread opens a file or creates a socket in the time window between us
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
482 * calling close() and accept().
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
483 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
484 static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
485 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
486 int emfile_fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
487
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
488 if (loop->emfile_fd == -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
489 return UV_EMFILE;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
490
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
491 uv__close(loop->emfile_fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
492 loop->emfile_fd = -1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
493
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
494 do {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
495 err = uv__accept(accept_fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
496 if (err >= 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
497 uv__close(err);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
498 } while (err >= 0 || err == UV_EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
499
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
500 emfile_fd = uv__open_cloexec("/", O_RDONLY);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
501 if (emfile_fd >= 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
502 loop->emfile_fd = emfile_fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
503
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
504 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
505 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
506
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
507
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
508 void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
509 uv_stream_t* stream;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
510 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
511 int fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
512
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
513 stream = container_of(w, uv_stream_t, io_watcher);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
514 assert(events & POLLIN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
515 assert(stream->accepted_fd == -1);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
516 assert(!(stream->flags & UV_HANDLE_CLOSING));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
517
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
518 fd = uv__stream_fd(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
519 err = uv__accept(fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
520
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
521 if (err == UV_EMFILE || err == UV_ENFILE)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
522 err = uv__emfile_trick(loop, fd); /* Shed load. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
523
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
524 if (err < 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
525 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
526
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
527 stream->accepted_fd = err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
528 stream->connection_cb(stream, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
529
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
530 if (stream->accepted_fd != -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
531 /* The user hasn't yet accepted called uv_accept() */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
532 uv__io_stop(loop, &stream->io_watcher, POLLIN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
533 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
534
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
535
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
536 int uv_accept(uv_stream_t* server, uv_stream_t* client) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
537 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
538
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
539 assert(server->loop == client->loop);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
540
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
541 if (server->accepted_fd == -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
542 return UV_EAGAIN;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
543
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
544 switch (client->type) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
545 case UV_NAMED_PIPE:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
546 case UV_TCP:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
547 err = uv__stream_open(client,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
548 server->accepted_fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
549 UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
550 if (err) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
551 /* TODO handle error */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
552 uv__close(server->accepted_fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
553 goto done;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
554 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
555 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
556
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
557 case UV_UDP:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
558 err = uv_udp_open((uv_udp_t*) client, server->accepted_fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
559 if (err) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
560 uv__close(server->accepted_fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
561 goto done;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
562 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
563 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
564
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
565 default:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
566 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
567 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
568
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
569 client->flags |= UV_HANDLE_BOUND;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
570
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
571 done:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
572 /* Process queued fds */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
573 if (server->queued_fds != NULL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
574 uv__stream_queued_fds_t* queued_fds;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
575
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
576 queued_fds = server->queued_fds;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
577
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
578 /* Read first */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
579 server->accepted_fd = queued_fds->fds[0];
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
580
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
581 /* All read, free */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
582 assert(queued_fds->offset > 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
583 if (--queued_fds->offset == 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
584 uv__free(queued_fds);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
585 server->queued_fds = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
586 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
587 /* Shift rest */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
588 memmove(queued_fds->fds,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
589 queued_fds->fds + 1,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
590 queued_fds->offset * sizeof(*queued_fds->fds));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
591 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
592 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
593 server->accepted_fd = -1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
594 if (err == 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
595 uv__io_start(server->loop, &server->io_watcher, POLLIN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
596 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
597 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
598 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
599
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
600
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
601 int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
602 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
603 if (uv__is_closing(stream)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
604 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
605 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
606 switch (stream->type) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
607 case UV_TCP:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
608 err = uv__tcp_listen((uv_tcp_t*)stream, backlog, cb);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
609 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
610
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
611 case UV_NAMED_PIPE:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
612 err = uv__pipe_listen((uv_pipe_t*)stream, backlog, cb);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
613 break;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
614
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
615 default:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
616 err = UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
617 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
618
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
619 if (err == 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
620 uv__handle_start(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
621
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
622 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
623 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
624
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
625
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
626 static void uv__drain(uv_stream_t* stream) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
627 uv_shutdown_t* req;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
628 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
629
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
630 assert(uv__queue_empty(&stream->write_queue));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
631 if (!(stream->flags & UV_HANDLE_CLOSING)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
632 uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
633 uv__stream_osx_interrupt_select(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
634 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
635
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
636 if (!uv__is_stream_shutting(stream))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
637 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
638
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
639 req = stream->shutdown_req;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
640 assert(req);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
641
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
642 if ((stream->flags & UV_HANDLE_CLOSING) ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
643 !(stream->flags & UV_HANDLE_SHUT)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
644 stream->shutdown_req = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
645 uv__req_unregister(stream->loop);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
646
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
647 err = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
648 if (stream->flags & UV_HANDLE_CLOSING)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
649 /* The user destroyed the stream before we got to do the shutdown. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
650 err = UV_ECANCELED;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
651 else if (shutdown(uv__stream_fd(stream), SHUT_WR))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
652 err = UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
653 else /* Success. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
654 stream->flags |= UV_HANDLE_SHUT;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
655
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
656 if (req->cb != NULL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
657 req->cb(req, err);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
658 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
659 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
660
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
661
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
662 static ssize_t uv__writev(int fd, struct iovec* vec, size_t n) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
663 if (n == 1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
664 return write(fd, vec->iov_base, vec->iov_len);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
665 else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
666 return writev(fd, vec, n);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
667 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
668
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
669
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
670 static size_t uv__write_req_size(uv_write_t* req) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
671 size_t size;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
672
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
673 assert(req->bufs != NULL);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
674 size = uv__count_bufs(req->bufs + req->write_index,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
675 req->nbufs - req->write_index);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
676 assert(req->handle->write_queue_size >= size);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
677
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
678 return size;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
679 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
680
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
681
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
682 /* Returns 1 if all write request data has been written, or 0 if there is still
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
683 * more data to write.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
684 *
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
685 * Note: the return value only says something about the *current* request.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
686 * There may still be other write requests sitting in the queue.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
687 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
688 static int uv__write_req_update(uv_stream_t* stream,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
689 uv_write_t* req,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
690 size_t n) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
691 uv_buf_t* buf;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
692 size_t len;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
693
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
694 assert(n <= stream->write_queue_size);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
695 stream->write_queue_size -= n;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
696
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
697 buf = req->bufs + req->write_index;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
698
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
699 do {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
700 len = n < buf->len ? n : buf->len;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
701 if (buf->len != 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
702 buf->base += len;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
703 buf->len -= len;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
704 buf += (buf->len == 0); /* Advance to next buffer if this one is empty. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
705 n -= len;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
706 } while (n > 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
707
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
708 req->write_index = buf - req->bufs;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
709
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
710 return req->write_index == req->nbufs;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
711 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
712
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
713
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
714 static void uv__write_req_finish(uv_write_t* req) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
715 uv_stream_t* stream = req->handle;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
716
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
717 /* Pop the req off tcp->write_queue. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
718 uv__queue_remove(&req->queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
719
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
720 /* Only free when there was no error. On error, we touch up write_queue_size
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
721 * right before making the callback. The reason we don't do that right away
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
722 * is that a write_queue_size > 0 is our only way to signal to the user that
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
723 * they should stop writing - which they should if we got an error. Something
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
724 * to revisit in future revisions of the libuv API.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
725 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
726 if (req->error == 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
727 if (req->bufs != req->bufsml)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
728 uv__free(req->bufs);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
729 req->bufs = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
730 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
731
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
732 /* Add it to the write_completed_queue where it will have its
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
733 * callback called in the near future.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
734 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
735 uv__queue_insert_tail(&stream->write_completed_queue, &req->queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
736 uv__io_feed(stream->loop, &stream->io_watcher);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
737 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
738
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
739
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
740 static int uv__handle_fd(uv_handle_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
741 switch (handle->type) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
742 case UV_NAMED_PIPE:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
743 case UV_TCP:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
744 return ((uv_stream_t*) handle)->io_watcher.fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
745
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
746 case UV_UDP:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
747 return ((uv_udp_t*) handle)->io_watcher.fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
748
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
749 default:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
750 return -1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
751 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
752 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
753
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
754 static int uv__try_write(uv_stream_t* stream,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
755 const uv_buf_t bufs[],
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
756 unsigned int nbufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
757 uv_stream_t* send_handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
758 struct iovec* iov;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
759 int iovmax;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
760 int iovcnt;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
761 ssize_t n;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
762
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
763 /*
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
764 * Cast to iovec. We had to have our own uv_buf_t instead of iovec
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
765 * because Windows's WSABUF is not an iovec.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
766 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
767 iov = (struct iovec*) bufs;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
768 iovcnt = nbufs;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
769
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
770 iovmax = uv__getiovmax();
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
771
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
772 /* Limit iov count to avoid EINVALs from writev() */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
773 if (iovcnt > iovmax)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
774 iovcnt = iovmax;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
775
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
776 /*
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
777 * Now do the actual writev. Note that we've been updating the pointers
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
778 * inside the iov each time we write. So there is no need to offset it.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
779 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
780 if (send_handle != NULL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
781 int fd_to_send;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
782 struct msghdr msg;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
783 union uv__cmsg cmsg;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
784
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
785 if (uv__is_closing(send_handle))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
786 return UV_EBADF;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
787
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
788 fd_to_send = uv__handle_fd((uv_handle_t*) send_handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
789
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
790 memset(&cmsg, 0, sizeof(cmsg));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
791
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
792 assert(fd_to_send >= 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
793
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
794 msg.msg_name = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
795 msg.msg_namelen = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
796 msg.msg_iov = iov;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
797 msg.msg_iovlen = iovcnt;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
798 msg.msg_flags = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
799
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
800 msg.msg_control = &cmsg.hdr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
801 msg.msg_controllen = CMSG_SPACE(sizeof(fd_to_send));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
802
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
803 cmsg.hdr.cmsg_level = SOL_SOCKET;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
804 cmsg.hdr.cmsg_type = SCM_RIGHTS;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
805 cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(fd_to_send));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
806 memcpy(CMSG_DATA(&cmsg.hdr), &fd_to_send, sizeof(fd_to_send));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
807
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
808 do
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
809 n = sendmsg(uv__stream_fd(stream), &msg, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
810 while (n == -1 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
811 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
812 do
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
813 n = uv__writev(uv__stream_fd(stream), iov, iovcnt);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
814 while (n == -1 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
815 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
816
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
817 if (n >= 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
818 return n;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
819
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
820 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
821 return UV_EAGAIN;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
822
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
823 #ifdef __APPLE__
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
824 /* macOS versions 10.10 and 10.15 - and presumbaly 10.11 to 10.14, too -
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
825 * have a bug where a race condition causes the kernel to return EPROTOTYPE
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
826 * because the socket isn't fully constructed. It's probably the result of
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
827 * the peer closing the connection and that is why libuv translates it to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
828 * ECONNRESET. Previously, libuv retried until the EPROTOTYPE error went
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
829 * away but some VPN software causes the same behavior except the error is
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
830 * permanent, not transient, turning the retry mechanism into an infinite
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
831 * loop. See https://github.com/libuv/libuv/pull/482.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
832 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
833 if (errno == EPROTOTYPE)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
834 return UV_ECONNRESET;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
835 #endif /* __APPLE__ */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
836
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
837 return UV__ERR(errno);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
838 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
839
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
840 static void uv__write(uv_stream_t* stream) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
841 struct uv__queue* q;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
842 uv_write_t* req;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
843 ssize_t n;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
844 int count;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
845
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
846 assert(uv__stream_fd(stream) >= 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
847
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
848 /* Prevent loop starvation when the consumer of this stream read as fast as
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
849 * (or faster than) we can write it. This `count` mechanism does not need to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
850 * change even if we switch to edge-triggered I/O.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
851 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
852 count = 32;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
853
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
854 for (;;) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
855 if (uv__queue_empty(&stream->write_queue))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
856 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
857
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
858 q = uv__queue_head(&stream->write_queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
859 req = uv__queue_data(q, uv_write_t, queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
860 assert(req->handle == stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
861
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
862 n = uv__try_write(stream,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
863 &(req->bufs[req->write_index]),
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
864 req->nbufs - req->write_index,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
865 req->send_handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
866
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
867 /* Ensure the handle isn't sent again in case this is a partial write. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
868 if (n >= 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
869 req->send_handle = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
870 if (uv__write_req_update(stream, req, n)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
871 uv__write_req_finish(req);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
872 if (count-- > 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
873 continue; /* Start trying to write the next request. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
874
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
875 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
876 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
877 } else if (n != UV_EAGAIN)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
878 goto error;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
879
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
880 /* If this is a blocking stream, try again. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
881 if (stream->flags & UV_HANDLE_BLOCKING_WRITES)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
882 continue;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
883
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
884 /* We're not done. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
885 uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
886
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
887 /* Notify select() thread about state change */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
888 uv__stream_osx_interrupt_select(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
889
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
890 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
891 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
892
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
893 error:
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
894 req->error = n;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
895 uv__write_req_finish(req);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
896 uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
897 uv__stream_osx_interrupt_select(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
898 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
899
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
900
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
901 static void uv__write_callbacks(uv_stream_t* stream) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
902 uv_write_t* req;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
903 struct uv__queue* q;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
904 struct uv__queue pq;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
905
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
906 if (uv__queue_empty(&stream->write_completed_queue))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
907 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
908
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
909 uv__queue_move(&stream->write_completed_queue, &pq);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
910
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
911 while (!uv__queue_empty(&pq)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
912 /* Pop a req off write_completed_queue. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
913 q = uv__queue_head(&pq);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
914 req = uv__queue_data(q, uv_write_t, queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
915 uv__queue_remove(q);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
916 uv__req_unregister(stream->loop);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
917
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
918 if (req->bufs != NULL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
919 stream->write_queue_size -= uv__write_req_size(req);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
920 if (req->bufs != req->bufsml)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
921 uv__free(req->bufs);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
922 req->bufs = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
923 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
924
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
925 /* NOTE: call callback AFTER freeing the request data. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
926 if (req->cb)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
927 req->cb(req, req->error);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
928 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
929 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
930
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
931
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
932 static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
933 stream->flags |= UV_HANDLE_READ_EOF;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
934 stream->flags &= ~UV_HANDLE_READING;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
935 uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
936 uv__handle_stop(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
937 uv__stream_osx_interrupt_select(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
938 stream->read_cb(stream, UV_EOF, buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
939 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
940
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
941
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
942 static int uv__stream_queue_fd(uv_stream_t* stream, int fd) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
943 uv__stream_queued_fds_t* queued_fds;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
944 unsigned int queue_size;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
945
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
946 queued_fds = stream->queued_fds;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
947 if (queued_fds == NULL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
948 queue_size = 8;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
949 queued_fds = uv__malloc((queue_size - 1) * sizeof(*queued_fds->fds) +
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
950 sizeof(*queued_fds));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
951 if (queued_fds == NULL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
952 return UV_ENOMEM;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
953 queued_fds->size = queue_size;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
954 queued_fds->offset = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
955 stream->queued_fds = queued_fds;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
956
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
957 /* Grow */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
958 } else if (queued_fds->size == queued_fds->offset) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
959 queue_size = queued_fds->size + 8;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
960 queued_fds = uv__realloc(queued_fds,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
961 (queue_size - 1) * sizeof(*queued_fds->fds) +
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
962 sizeof(*queued_fds));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
963
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
964 /*
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
965 * Allocation failure, report back.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
966 * NOTE: if it is fatal - sockets will be closed in uv__stream_close
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
967 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
968 if (queued_fds == NULL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
969 return UV_ENOMEM;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
970 queued_fds->size = queue_size;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
971 stream->queued_fds = queued_fds;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
972 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
973
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
974 /* Put fd in a queue */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
975 queued_fds->fds[queued_fds->offset++] = fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
976
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
977 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
978 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
979
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
980
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
981 static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
982 struct cmsghdr* cmsg;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
983 char* p;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
984 char* pe;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
985 int fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
986 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
987 size_t count;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
988
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
989 err = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
990 for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
991 if (cmsg->cmsg_type != SCM_RIGHTS) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
992 fprintf(stderr, "ignoring non-SCM_RIGHTS ancillary data: %d\n",
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
993 cmsg->cmsg_type);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
994 continue;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
995 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
996
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
997 assert(cmsg->cmsg_len >= CMSG_LEN(0));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
998 count = cmsg->cmsg_len - CMSG_LEN(0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
999 assert(count % sizeof(fd) == 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1000 count /= sizeof(fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1001
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1002 p = (void*) CMSG_DATA(cmsg);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1003 pe = p + count * sizeof(fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1004
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1005 while (p < pe) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1006 memcpy(&fd, p, sizeof(fd));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1007 p += sizeof(fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1008
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1009 if (err == 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1010 if (stream->accepted_fd == -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1011 stream->accepted_fd = fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1012 else
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1013 err = uv__stream_queue_fd(stream, fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1014 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1015
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1016 if (err != 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1017 uv__close(fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1018 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1019 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1020
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1021 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1022 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1023
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1024
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1025 static void uv__read(uv_stream_t* stream) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1026 uv_buf_t buf;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1027 ssize_t nread;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1028 struct msghdr msg;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1029 union uv__cmsg cmsg;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1030 int count;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1031 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1032 int is_ipc;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1033
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1034 stream->flags &= ~UV_HANDLE_READ_PARTIAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1035
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1036 /* Prevent loop starvation when the data comes in as fast as (or faster than)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1037 * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1038 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1039 count = 32;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1040
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1041 is_ipc = stream->type == UV_NAMED_PIPE && ((uv_pipe_t*) stream)->ipc;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1042
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1043 /* XXX: Maybe instead of having UV_HANDLE_READING we just test if
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1044 * tcp->read_cb is NULL or not?
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1045 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1046 while (stream->read_cb
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1047 && (stream->flags & UV_HANDLE_READING)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1048 && (count-- > 0)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1049 assert(stream->alloc_cb != NULL);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1050
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1051 buf = uv_buf_init(NULL, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1052 stream->alloc_cb((uv_handle_t*)stream, 64 * 1024, &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1053 if (buf.base == NULL || buf.len == 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1054 /* User indicates it can't or won't handle the read. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1055 stream->read_cb(stream, UV_ENOBUFS, &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1056 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1057 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1058
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1059 assert(buf.base != NULL);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1060 assert(uv__stream_fd(stream) >= 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1061
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1062 if (!is_ipc) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1063 do {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1064 nread = read(uv__stream_fd(stream), buf.base, buf.len);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1065 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1066 while (nread < 0 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1067 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1068 /* ipc uses recvmsg */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1069 msg.msg_flags = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1070 msg.msg_iov = (struct iovec*) &buf;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1071 msg.msg_iovlen = 1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1072 msg.msg_name = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1073 msg.msg_namelen = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1074 /* Set up to receive a descriptor even if one isn't in the message */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1075 msg.msg_controllen = sizeof(cmsg);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1076 msg.msg_control = &cmsg.hdr;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1077
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1078 do {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1079 nread = uv__recvmsg(uv__stream_fd(stream), &msg, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1080 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1081 while (nread < 0 && errno == EINTR);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1082 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1083
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1084 if (nread < 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1085 /* Error */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1086 if (errno == EAGAIN || errno == EWOULDBLOCK) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1087 /* Wait for the next one. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1088 if (stream->flags & UV_HANDLE_READING) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1089 uv__io_start(stream->loop, &stream->io_watcher, POLLIN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1090 uv__stream_osx_interrupt_select(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1091 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1092 stream->read_cb(stream, 0, &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1093 #if defined(__CYGWIN__) || defined(__MSYS__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1094 } else if (errno == ECONNRESET && stream->type == UV_NAMED_PIPE) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1095 uv__stream_eof(stream, &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1096 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1097 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1098 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1099 /* Error. User should call uv_close(). */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1100 stream->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1101 stream->read_cb(stream, UV__ERR(errno), &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1102 if (stream->flags & UV_HANDLE_READING) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1103 stream->flags &= ~UV_HANDLE_READING;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1104 uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1105 uv__handle_stop(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1106 uv__stream_osx_interrupt_select(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1107 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1108 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1109 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1110 } else if (nread == 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1111 uv__stream_eof(stream, &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1112 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1113 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1114 /* Successful read */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1115 ssize_t buflen = buf.len;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1116
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1117 if (is_ipc) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1118 err = uv__stream_recv_cmsg(stream, &msg);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1119 if (err != 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1120 stream->read_cb(stream, err, &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1121 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1122 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1123 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1124
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1125 #if defined(__MVS__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1126 if (is_ipc && msg.msg_controllen > 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1127 uv_buf_t blankbuf;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1128 int nread;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1129 struct iovec *old;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1130
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1131 blankbuf.base = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1132 blankbuf.len = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1133 old = msg.msg_iov;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1134 msg.msg_iov = (struct iovec*) &blankbuf;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1135 nread = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1136 do {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1137 nread = uv__recvmsg(uv__stream_fd(stream), &msg, 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1138 err = uv__stream_recv_cmsg(stream, &msg);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1139 if (err != 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1140 stream->read_cb(stream, err, &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1141 msg.msg_iov = old;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1142 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1143 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1144 } while (nread == 0 && msg.msg_controllen > 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1145 msg.msg_iov = old;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1146 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1147 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1148 stream->read_cb(stream, nread, &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1149
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1150 /* Return if we didn't fill the buffer, there is no more data to read. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1151 if (nread < buflen) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1152 stream->flags |= UV_HANDLE_READ_PARTIAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1153 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1154 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1155 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1156 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1157 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1158
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1159
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1160 int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1161 assert(stream->type == UV_TCP ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1162 stream->type == UV_TTY ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1163 stream->type == UV_NAMED_PIPE);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1164
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1165 if (!(stream->flags & UV_HANDLE_WRITABLE) ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1166 stream->flags & UV_HANDLE_SHUT ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1167 uv__is_stream_shutting(stream) ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1168 uv__is_closing(stream)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1169 return UV_ENOTCONN;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1170 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1171
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1172 assert(uv__stream_fd(stream) >= 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1173
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1174 /* Initialize request. The `shutdown(2)` call will always be deferred until
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1175 * `uv__drain`, just before the callback is run. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1176 uv__req_init(stream->loop, req, UV_SHUTDOWN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1177 req->handle = stream;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1178 req->cb = cb;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1179 stream->shutdown_req = req;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1180 stream->flags &= ~UV_HANDLE_WRITABLE;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1181
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1182 if (uv__queue_empty(&stream->write_queue))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1183 uv__io_feed(stream->loop, &stream->io_watcher);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1184
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1185 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1186 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1187
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1188
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1189 static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1190 uv_stream_t* stream;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1191
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1192 stream = container_of(w, uv_stream_t, io_watcher);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1193
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1194 assert(stream->type == UV_TCP ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1195 stream->type == UV_NAMED_PIPE ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1196 stream->type == UV_TTY);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1197 assert(!(stream->flags & UV_HANDLE_CLOSING));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1198
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1199 if (stream->connect_req) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1200 uv__stream_connect(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1201 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1202 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1203
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1204 assert(uv__stream_fd(stream) >= 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1205
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1206 /* Ignore POLLHUP here. Even if it's set, there may still be data to read. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1207 if (events & (POLLIN | POLLERR | POLLHUP))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1208 uv__read(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1209
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1210 if (uv__stream_fd(stream) == -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1211 return; /* read_cb closed stream. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1212
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1213 /* Short-circuit iff POLLHUP is set, the user is still interested in read
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1214 * events and uv__read() reported a partial read but not EOF. If the EOF
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1215 * flag is set, uv__read() called read_cb with err=UV_EOF and we don't
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1216 * have to do anything. If the partial read flag is not set, we can't
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1217 * report the EOF yet because there is still data to read.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1218 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1219 if ((events & POLLHUP) &&
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1220 (stream->flags & UV_HANDLE_READING) &&
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1221 (stream->flags & UV_HANDLE_READ_PARTIAL) &&
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1222 !(stream->flags & UV_HANDLE_READ_EOF)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1223 uv_buf_t buf = { NULL, 0 };
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1224 uv__stream_eof(stream, &buf);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1225 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1226
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1227 if (uv__stream_fd(stream) == -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1228 return; /* read_cb closed stream. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1229
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1230 if (events & (POLLOUT | POLLERR | POLLHUP)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1231 uv__write(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1232 uv__write_callbacks(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1233
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1234 /* Write queue drained. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1235 if (uv__queue_empty(&stream->write_queue))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1236 uv__drain(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1237 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1238 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1239
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1240
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1241 /**
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1242 * We get called here from directly following a call to connect(2).
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1243 * In order to determine if we've errored out or succeeded must call
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1244 * getsockopt.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1245 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1246 static void uv__stream_connect(uv_stream_t* stream) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1247 int error;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1248 uv_connect_t* req = stream->connect_req;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1249 socklen_t errorsize = sizeof(int);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1250
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1251 assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1252 assert(req);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1253
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1254 if (stream->delayed_error) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1255 /* To smooth over the differences between unixes errors that
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1256 * were reported synchronously on the first connect can be delayed
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1257 * until the next tick--which is now.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1258 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1259 error = stream->delayed_error;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1260 stream->delayed_error = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1261 } else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1262 /* Normal situation: we need to get the socket error from the kernel. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1263 assert(uv__stream_fd(stream) >= 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1264 getsockopt(uv__stream_fd(stream),
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1265 SOL_SOCKET,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1266 SO_ERROR,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1267 &error,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1268 &errorsize);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1269 error = UV__ERR(error);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1270 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1271
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1272 if (error == UV__ERR(EINPROGRESS))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1273 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1274
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1275 stream->connect_req = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1276 uv__req_unregister(stream->loop);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1277
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1278 if (error < 0 || uv__queue_empty(&stream->write_queue)) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1279 uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1280 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1281
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1282 if (req->cb)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1283 req->cb(req, error);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1284
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1285 if (uv__stream_fd(stream) == -1)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1286 return;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1287
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1288 if (error < 0) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1289 uv__stream_flush_write_queue(stream, UV_ECANCELED);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1290 uv__write_callbacks(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1291 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1292 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1293
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1294
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1295 static int uv__check_before_write(uv_stream_t* stream,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1296 unsigned int nbufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1297 uv_stream_t* send_handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1298 assert(nbufs > 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1299 assert((stream->type == UV_TCP ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1300 stream->type == UV_NAMED_PIPE ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1301 stream->type == UV_TTY) &&
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1302 "uv_write (unix) does not yet support other types of streams");
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1303
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1304 if (uv__stream_fd(stream) < 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1305 return UV_EBADF;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1306
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1307 if (!(stream->flags & UV_HANDLE_WRITABLE))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1308 return UV_EPIPE;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1309
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1310 if (send_handle != NULL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1311 if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1312 return UV_EINVAL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1313
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1314 /* XXX We abuse uv_write2() to send over UDP handles to child processes.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1315 * Don't call uv__stream_fd() on those handles, it's a macro that on OS X
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1316 * evaluates to a function that operates on a uv_stream_t with a couple of
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1317 * OS X specific fields. On other Unices it does (handle)->io_watcher.fd,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1318 * which works but only by accident.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1319 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1320 if (uv__handle_fd((uv_handle_t*) send_handle) < 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1321 return UV_EBADF;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1322
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1323 #if defined(__CYGWIN__) || defined(__MSYS__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1324 /* Cygwin recvmsg always sets msg_controllen to zero, so we cannot send it.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1325 See https://github.com/mirror/newlib-cygwin/blob/86fc4bf0/winsup/cygwin/fhandler_socket.cc#L1736-L1743 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1326 return UV_ENOSYS;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1327 #endif
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1328 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1329
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1330 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1331 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1332
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1333 int uv_write2(uv_write_t* req,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1334 uv_stream_t* stream,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1335 const uv_buf_t bufs[],
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1336 unsigned int nbufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1337 uv_stream_t* send_handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1338 uv_write_cb cb) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1339 int empty_queue;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1340 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1341
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1342 err = uv__check_before_write(stream, nbufs, send_handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1343 if (err < 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1344 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1345
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1346 /* It's legal for write_queue_size > 0 even when the write_queue is empty;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1347 * it means there are error-state requests in the write_completed_queue that
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1348 * will touch up write_queue_size later, see also uv__write_req_finish().
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1349 * We could check that write_queue is empty instead but that implies making
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1350 * a write() syscall when we know that the handle is in error mode.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1351 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1352 empty_queue = (stream->write_queue_size == 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1353
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1354 /* Initialize the req */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1355 uv__req_init(stream->loop, req, UV_WRITE);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1356 req->cb = cb;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1357 req->handle = stream;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1358 req->error = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1359 req->send_handle = send_handle;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1360 uv__queue_init(&req->queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1361
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1362 req->bufs = req->bufsml;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1363 if (nbufs > ARRAY_SIZE(req->bufsml))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1364 req->bufs = uv__malloc(nbufs * sizeof(bufs[0]));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1365
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1366 if (req->bufs == NULL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1367 return UV_ENOMEM;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1368
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1369 memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0]));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1370 req->nbufs = nbufs;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1371 req->write_index = 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1372 stream->write_queue_size += uv__count_bufs(bufs, nbufs);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1373
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1374 /* Append the request to write_queue. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1375 uv__queue_insert_tail(&stream->write_queue, &req->queue);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1376
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1377 /* If the queue was empty when this function began, we should attempt to
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1378 * do the write immediately. Otherwise start the write_watcher and wait
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1379 * for the fd to become writable.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1380 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1381 if (stream->connect_req) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1382 /* Still connecting, do nothing. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1383 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1384 else if (empty_queue) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1385 uv__write(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1386 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1387 else {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1388 /*
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1389 * blocking streams should never have anything in the queue.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1390 * if this assert fires then somehow the blocking stream isn't being
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1391 * sufficiently flushed in uv__write.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1392 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1393 assert(!(stream->flags & UV_HANDLE_BLOCKING_WRITES));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1394 uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1395 uv__stream_osx_interrupt_select(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1396 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1397
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1398 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1399 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1400
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1401
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1402 /* The buffers to be written must remain valid until the callback is called.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1403 * This is not required for the uv_buf_t array.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1404 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1405 int uv_write(uv_write_t* req,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1406 uv_stream_t* handle,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1407 const uv_buf_t bufs[],
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1408 unsigned int nbufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1409 uv_write_cb cb) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1410 return uv_write2(req, handle, bufs, nbufs, NULL, cb);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1411 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1412
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1413
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1414 int uv_try_write(uv_stream_t* stream,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1415 const uv_buf_t bufs[],
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1416 unsigned int nbufs) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1417 return uv_try_write2(stream, bufs, nbufs, NULL);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1418 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1419
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1420
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1421 int uv_try_write2(uv_stream_t* stream,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1422 const uv_buf_t bufs[],
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1423 unsigned int nbufs,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1424 uv_stream_t* send_handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1425 int err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1426
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1427 /* Connecting or already writing some data */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1428 if (stream->connect_req != NULL || stream->write_queue_size != 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1429 return UV_EAGAIN;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1430
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1431 err = uv__check_before_write(stream, nbufs, NULL);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1432 if (err < 0)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1433 return err;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1434
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1435 return uv__try_write(stream, bufs, nbufs, send_handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1436 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1437
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1438
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1439 int uv__read_start(uv_stream_t* stream,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1440 uv_alloc_cb alloc_cb,
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1441 uv_read_cb read_cb) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1442 assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1443 stream->type == UV_TTY);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1444
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1445 /* The UV_HANDLE_READING flag is irrelevant of the state of the stream - it
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1446 * just expresses the desired state of the user. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1447 stream->flags |= UV_HANDLE_READING;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1448 stream->flags &= ~UV_HANDLE_READ_EOF;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1449
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1450 /* TODO: try to do the read inline? */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1451 assert(uv__stream_fd(stream) >= 0);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1452 assert(alloc_cb);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1453
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1454 stream->read_cb = read_cb;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1455 stream->alloc_cb = alloc_cb;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1456
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1457 uv__io_start(stream->loop, &stream->io_watcher, POLLIN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1458 uv__handle_start(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1459 uv__stream_osx_interrupt_select(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1460
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1461 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1462 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1463
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1464
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1465 int uv_read_stop(uv_stream_t* stream) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1466 if (!(stream->flags & UV_HANDLE_READING))
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1467 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1468
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1469 stream->flags &= ~UV_HANDLE_READING;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1470 uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1471 uv__handle_stop(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1472 uv__stream_osx_interrupt_select(stream);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1473
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1474 stream->read_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1475 stream->alloc_cb = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1476 return 0;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1477 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1478
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1479
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1480 int uv_is_readable(const uv_stream_t* stream) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1481 return !!(stream->flags & UV_HANDLE_READABLE);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1482 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1483
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1484
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1485 int uv_is_writable(const uv_stream_t* stream) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1486 return !!(stream->flags & UV_HANDLE_WRITABLE);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1487 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1488
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1489
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1490 #if defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1491 int uv___stream_fd(const uv_stream_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1492 const uv__stream_select_t* s;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1493
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1494 assert(handle->type == UV_TCP ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1495 handle->type == UV_TTY ||
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1496 handle->type == UV_NAMED_PIPE);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1497
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1498 s = handle->select;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1499 if (s != NULL)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1500 return s->fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1501
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1502 return handle->io_watcher.fd;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1503 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1504 #endif /* defined(__APPLE__) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1505
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1506
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1507 void uv__stream_close(uv_stream_t* handle) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1508 unsigned int i;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1509 uv__stream_queued_fds_t* queued_fds;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1510
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1511 #if defined(__APPLE__)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1512 /* Terminate select loop first */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1513 if (handle->select != NULL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1514 uv__stream_select_t* s;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1515
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1516 s = handle->select;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1517
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1518 uv_sem_post(&s->close_sem);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1519 uv_sem_post(&s->async_sem);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1520 uv__stream_osx_interrupt_select(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1521 uv_thread_join(&s->thread);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1522 uv_sem_destroy(&s->close_sem);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1523 uv_sem_destroy(&s->async_sem);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1524 uv__close(s->fake_fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1525 uv__close(s->int_fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1526 uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1527
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1528 handle->select = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1529 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1530 #endif /* defined(__APPLE__) */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1531
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1532 uv__io_close(handle->loop, &handle->io_watcher);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1533 uv_read_stop(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1534 uv__handle_stop(handle);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1535 handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1536
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1537 if (handle->io_watcher.fd != -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1538 /* Don't close stdio file descriptors. Nothing good comes from it. */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1539 if (handle->io_watcher.fd > STDERR_FILENO)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1540 uv__close(handle->io_watcher.fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1541 handle->io_watcher.fd = -1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1542 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1543
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1544 if (handle->accepted_fd != -1) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1545 uv__close(handle->accepted_fd);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1546 handle->accepted_fd = -1;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1547 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1548
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1549 /* Close all queued fds */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1550 if (handle->queued_fds != NULL) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1551 queued_fds = handle->queued_fds;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1552 for (i = 0; i < queued_fds->offset; i++)
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1553 uv__close(queued_fds->fds[i]);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1554 uv__free(handle->queued_fds);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1555 handle->queued_fds = NULL;
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1556 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1557
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1558 assert(!uv__io_active(&handle->io_watcher, POLLIN | POLLOUT));
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1559 }
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1560
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1561
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1562 int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1563 /* Don't need to check the file descriptor, uv__nonblock()
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1564 * will fail with EBADF if it's not valid.
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1565 */
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1566 return uv__nonblock(uv__stream_fd(handle), !blocking);
948de3f54cea [ThirdParty] Added libuv
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1567 }