|
160
|
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
|
2 *
|
|
|
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
4 * of this software and associated documentation files (the "Software"), to
|
|
|
5 * deal in the Software without restriction, including without limitation the
|
|
|
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
|
7 * sell copies of the Software, and to permit persons to whom the Software is
|
|
|
8 * furnished to do so, subject to the following conditions:
|
|
|
9 *
|
|
|
10 * The above copyright notice and this permission notice shall be included in
|
|
|
11 * all copies or substantial portions of the Software.
|
|
|
12 *
|
|
|
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
|
19 * IN THE SOFTWARE.
|
|
|
20 */
|
|
|
21
|
|
|
22 #ifndef UV_WIN_REQ_INL_H_
|
|
|
23 #define UV_WIN_REQ_INL_H_
|
|
|
24
|
|
|
25 #include <assert.h>
|
|
|
26
|
|
|
27 #include "uv.h"
|
|
|
28 #include "internal.h"
|
|
|
29
|
|
|
30
|
|
|
31 #define SET_REQ_STATUS(req, status) \
|
|
|
32 (req)->u.io.overlapped.Internal = (ULONG_PTR) (status)
|
|
|
33
|
|
|
34 #define SET_REQ_ERROR(req, error) \
|
|
|
35 SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error)))
|
|
|
36
|
|
|
37 /* Note: used open-coded in UV_REQ_INIT() because of a circular dependency
|
|
|
38 * between src/uv-common.h and src/win/internal.h.
|
|
|
39 */
|
|
|
40 #define SET_REQ_SUCCESS(req) \
|
|
|
41 SET_REQ_STATUS((req), STATUS_SUCCESS)
|
|
|
42
|
|
|
43 #define GET_REQ_STATUS(req) \
|
|
|
44 ((NTSTATUS) (req)->u.io.overlapped.Internal)
|
|
|
45
|
|
|
46 #define REQ_SUCCESS(req) \
|
|
|
47 (NT_SUCCESS(GET_REQ_STATUS((req))))
|
|
|
48
|
|
|
49 #define GET_REQ_ERROR(req) \
|
|
|
50 (pRtlNtStatusToDosError(GET_REQ_STATUS((req))))
|
|
|
51
|
|
|
52 #define GET_REQ_SOCK_ERROR(req) \
|
|
|
53 (uv__ntstatus_to_winsock_error(GET_REQ_STATUS((req))))
|
|
|
54
|
|
|
55
|
|
|
56 #define REGISTER_HANDLE_REQ(loop, handle) \
|
|
|
57 do { \
|
|
|
58 INCREASE_ACTIVE_COUNT((loop), (handle)); \
|
|
|
59 uv__req_register((loop)); \
|
|
|
60 } while (0)
|
|
|
61
|
|
|
62 #define UNREGISTER_HANDLE_REQ(loop, handle) \
|
|
|
63 do { \
|
|
|
64 DECREASE_ACTIVE_COUNT((loop), (handle)); \
|
|
|
65 uv__req_unregister((loop)); \
|
|
|
66 } while (0)
|
|
|
67
|
|
|
68
|
|
|
69 #define UV_SUCCEEDED_WITHOUT_IOCP(result) \
|
|
|
70 ((result) && (handle->flags & UV_HANDLE_SYNC_BYPASS_IOCP))
|
|
|
71
|
|
|
72 #define UV_SUCCEEDED_WITH_IOCP(result) \
|
|
|
73 ((result) || (GetLastError() == ERROR_IO_PENDING))
|
|
|
74
|
|
|
75
|
|
|
76 #define POST_COMPLETION_FOR_REQ(loop, req) \
|
|
|
77 if (!PostQueuedCompletionStatus((loop)->iocp, \
|
|
|
78 0, \
|
|
|
79 0, \
|
|
|
80 &((req)->u.io.overlapped))) { \
|
|
|
81 uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \
|
|
|
82 }
|
|
|
83
|
|
|
84
|
|
|
85 INLINE static uv_req_t* uv__overlapped_to_req(OVERLAPPED* overlapped) {
|
|
|
86 return container_of(overlapped, uv_req_t, u.io.overlapped);
|
|
|
87 }
|
|
|
88
|
|
|
89
|
|
|
90 INLINE static void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
|
|
|
91 req->next_req = NULL;
|
|
|
92 if (loop->pending_reqs_tail) {
|
|
|
93 #ifdef _DEBUG
|
|
|
94 /* Ensure the request is not already in the queue, or the queue
|
|
|
95 * will get corrupted.
|
|
|
96 */
|
|
|
97 uv_req_t* current = loop->pending_reqs_tail;
|
|
|
98 do {
|
|
|
99 assert(req != current);
|
|
|
100 current = current->next_req;
|
|
|
101 } while(current != loop->pending_reqs_tail);
|
|
|
102 #endif
|
|
|
103
|
|
|
104 req->next_req = loop->pending_reqs_tail->next_req;
|
|
|
105 loop->pending_reqs_tail->next_req = req;
|
|
|
106 loop->pending_reqs_tail = req;
|
|
|
107 } else {
|
|
|
108 req->next_req = req;
|
|
|
109 loop->pending_reqs_tail = req;
|
|
|
110 }
|
|
|
111 }
|
|
|
112
|
|
|
113
|
|
|
114 #define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
|
|
|
115 do { \
|
|
|
116 switch (((uv_handle_t*) (req)->handle_at)->type) { \
|
|
|
117 case UV_TCP: \
|
|
|
118 uv__process_tcp_##method##_req(loop, \
|
|
|
119 (uv_tcp_t*) ((req)->handle_at), \
|
|
|
120 req); \
|
|
|
121 break; \
|
|
|
122 \
|
|
|
123 case UV_NAMED_PIPE: \
|
|
|
124 uv__process_pipe_##method##_req(loop, \
|
|
|
125 (uv_pipe_t*) ((req)->handle_at), \
|
|
|
126 req); \
|
|
|
127 break; \
|
|
|
128 \
|
|
|
129 case UV_TTY: \
|
|
|
130 uv__process_tty_##method##_req(loop, \
|
|
|
131 (uv_tty_t*) ((req)->handle_at), \
|
|
|
132 req); \
|
|
|
133 break; \
|
|
|
134 \
|
|
|
135 default: \
|
|
|
136 assert(0); \
|
|
|
137 } \
|
|
|
138 } while (0)
|
|
|
139
|
|
|
140
|
|
|
141 INLINE static void uv__process_reqs(uv_loop_t* loop) {
|
|
|
142 uv_req_t* req;
|
|
|
143 uv_req_t* first;
|
|
|
144 uv_req_t* next;
|
|
|
145
|
|
|
146 if (loop->pending_reqs_tail == NULL)
|
|
|
147 return;
|
|
|
148
|
|
|
149 first = loop->pending_reqs_tail->next_req;
|
|
|
150 next = first;
|
|
|
151 loop->pending_reqs_tail = NULL;
|
|
|
152
|
|
|
153 while (next != NULL) {
|
|
|
154 req = next;
|
|
|
155 next = req->next_req != first ? req->next_req : NULL;
|
|
|
156
|
|
|
157 switch (req->type) {
|
|
|
158 case UV_READ:
|
|
|
159 DELEGATE_STREAM_REQ(loop, req, read, data);
|
|
|
160 break;
|
|
|
161
|
|
|
162 case UV_WRITE:
|
|
|
163 DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle);
|
|
|
164 break;
|
|
|
165
|
|
|
166 case UV_ACCEPT:
|
|
|
167 DELEGATE_STREAM_REQ(loop, req, accept, data);
|
|
|
168 break;
|
|
|
169
|
|
|
170 case UV_CONNECT:
|
|
|
171 DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle);
|
|
|
172 break;
|
|
|
173
|
|
|
174 case UV_SHUTDOWN:
|
|
|
175 DELEGATE_STREAM_REQ(loop, (uv_shutdown_t*) req, shutdown, handle);
|
|
|
176 break;
|
|
|
177
|
|
|
178 case UV_UDP_RECV:
|
|
|
179 uv__process_udp_recv_req(loop, (uv_udp_t*) req->data, req);
|
|
|
180 break;
|
|
|
181
|
|
|
182 case UV_UDP_SEND:
|
|
|
183 uv__process_udp_send_req(loop,
|
|
|
184 ((uv_udp_send_t*) req)->handle,
|
|
|
185 (uv_udp_send_t*) req);
|
|
|
186 break;
|
|
|
187
|
|
|
188 case UV_WAKEUP:
|
|
|
189 uv__process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
|
|
|
190 break;
|
|
|
191
|
|
|
192 case UV_SIGNAL_REQ:
|
|
|
193 uv__process_signal_req(loop, (uv_signal_t*) req->data, req);
|
|
|
194 break;
|
|
|
195
|
|
|
196 case UV_POLL_REQ:
|
|
|
197 uv__process_poll_req(loop, (uv_poll_t*) req->data, req);
|
|
|
198 break;
|
|
|
199
|
|
|
200 case UV_PROCESS_EXIT:
|
|
|
201 uv__process_proc_exit(loop, (uv_process_t*) req->data);
|
|
|
202 break;
|
|
|
203
|
|
|
204 case UV_FS_EVENT_REQ:
|
|
|
205 uv__process_fs_event_req(loop, req, (uv_fs_event_t*) req->data);
|
|
|
206 break;
|
|
|
207
|
|
|
208 default:
|
|
|
209 assert(0);
|
|
|
210 }
|
|
|
211 }
|
|
|
212 }
|
|
|
213
|
|
|
214 #endif /* UV_WIN_REQ_INL_H_ */
|