|
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_HANDLE_INL_H_
|
|
|
23 #define UV_WIN_HANDLE_INL_H_
|
|
|
24
|
|
|
25 #include <assert.h>
|
|
|
26 #include <io.h>
|
|
|
27
|
|
|
28 #include "uv.h"
|
|
|
29 #include "internal.h"
|
|
|
30
|
|
|
31
|
|
|
32 #define DECREASE_ACTIVE_COUNT(loop, handle) \
|
|
|
33 do { \
|
|
|
34 if (--(handle)->activecnt == 0 && \
|
|
|
35 !((handle)->flags & UV_HANDLE_CLOSING)) { \
|
|
|
36 uv__handle_stop((handle)); \
|
|
|
37 } \
|
|
|
38 assert((handle)->activecnt >= 0); \
|
|
|
39 } while (0)
|
|
|
40
|
|
|
41
|
|
|
42 #define INCREASE_ACTIVE_COUNT(loop, handle) \
|
|
|
43 do { \
|
|
|
44 if ((handle)->activecnt++ == 0) { \
|
|
|
45 uv__handle_start((handle)); \
|
|
|
46 } \
|
|
|
47 assert((handle)->activecnt > 0); \
|
|
|
48 } while (0)
|
|
|
49
|
|
|
50
|
|
|
51 #define DECREASE_PENDING_REQ_COUNT(handle) \
|
|
|
52 do { \
|
|
|
53 assert(handle->reqs_pending > 0); \
|
|
|
54 handle->reqs_pending--; \
|
|
|
55 \
|
|
|
56 if (handle->flags & UV_HANDLE_CLOSING && \
|
|
|
57 handle->reqs_pending == 0) { \
|
|
|
58 uv__want_endgame(loop, (uv_handle_t*)handle); \
|
|
|
59 } \
|
|
|
60 } while (0)
|
|
|
61
|
|
|
62
|
|
|
63 #define uv__handle_closing(handle) \
|
|
|
64 do { \
|
|
|
65 assert(!((handle)->flags & UV_HANDLE_CLOSING)); \
|
|
|
66 \
|
|
|
67 if (!(((handle)->flags & UV_HANDLE_ACTIVE) && \
|
|
|
68 ((handle)->flags & UV_HANDLE_REF))) \
|
|
|
69 uv__active_handle_add((uv_handle_t*) (handle)); \
|
|
|
70 \
|
|
|
71 (handle)->flags |= UV_HANDLE_CLOSING; \
|
|
|
72 (handle)->flags &= ~UV_HANDLE_ACTIVE; \
|
|
|
73 } while (0)
|
|
|
74
|
|
|
75
|
|
|
76 #define uv__handle_close(handle) \
|
|
|
77 do { \
|
|
|
78 uv__queue_remove(&(handle)->handle_queue); \
|
|
|
79 uv__active_handle_rm((uv_handle_t*) (handle)); \
|
|
|
80 \
|
|
|
81 (handle)->flags |= UV_HANDLE_CLOSED; \
|
|
|
82 \
|
|
|
83 if ((handle)->close_cb) \
|
|
|
84 (handle)->close_cb((uv_handle_t*) (handle)); \
|
|
|
85 } while (0)
|
|
|
86
|
|
|
87
|
|
|
88 INLINE static void uv__want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
|
|
89 if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) {
|
|
|
90 handle->flags |= UV_HANDLE_ENDGAME_QUEUED;
|
|
|
91
|
|
|
92 handle->endgame_next = loop->endgame_handles;
|
|
|
93 loop->endgame_handles = handle;
|
|
|
94 }
|
|
|
95 }
|
|
|
96
|
|
|
97
|
|
|
98 INLINE static void uv__process_endgames(uv_loop_t* loop) {
|
|
|
99 uv_handle_t* handle;
|
|
|
100
|
|
|
101 while (loop->endgame_handles) {
|
|
|
102 handle = loop->endgame_handles;
|
|
|
103 loop->endgame_handles = handle->endgame_next;
|
|
|
104
|
|
|
105 handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
|
|
|
106
|
|
|
107 switch (handle->type) {
|
|
|
108 case UV_TCP:
|
|
|
109 uv__tcp_endgame(loop, (uv_tcp_t*) handle);
|
|
|
110 break;
|
|
|
111
|
|
|
112 case UV_NAMED_PIPE:
|
|
|
113 uv__pipe_endgame(loop, (uv_pipe_t*) handle);
|
|
|
114 break;
|
|
|
115
|
|
|
116 case UV_TTY:
|
|
|
117 uv__tty_endgame(loop, (uv_tty_t*) handle);
|
|
|
118 break;
|
|
|
119
|
|
|
120 case UV_UDP:
|
|
|
121 uv__udp_endgame(loop, (uv_udp_t*) handle);
|
|
|
122 break;
|
|
|
123
|
|
|
124 case UV_POLL:
|
|
|
125 uv__poll_endgame(loop, (uv_poll_t*) handle);
|
|
|
126 break;
|
|
|
127
|
|
|
128 case UV_TIMER:
|
|
|
129 uv__timer_close((uv_timer_t*) handle);
|
|
|
130 uv__handle_close(handle);
|
|
|
131 break;
|
|
|
132
|
|
|
133 case UV_PREPARE:
|
|
|
134 case UV_CHECK:
|
|
|
135 case UV_IDLE:
|
|
|
136 uv__loop_watcher_endgame(loop, handle);
|
|
|
137 break;
|
|
|
138
|
|
|
139 case UV_ASYNC:
|
|
|
140 uv__async_endgame(loop, (uv_async_t*) handle);
|
|
|
141 break;
|
|
|
142
|
|
|
143 case UV_SIGNAL:
|
|
|
144 uv__signal_endgame(loop, (uv_signal_t*) handle);
|
|
|
145 break;
|
|
|
146
|
|
|
147 case UV_PROCESS:
|
|
|
148 uv__process_endgame(loop, (uv_process_t*) handle);
|
|
|
149 break;
|
|
|
150
|
|
|
151 case UV_FS_EVENT:
|
|
|
152 uv__fs_event_endgame(loop, (uv_fs_event_t*) handle);
|
|
|
153 break;
|
|
|
154
|
|
|
155 case UV_FS_POLL:
|
|
|
156 uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle);
|
|
|
157 break;
|
|
|
158
|
|
|
159 default:
|
|
|
160 assert(0);
|
|
|
161 break;
|
|
|
162 }
|
|
|
163 }
|
|
|
164 }
|
|
|
165
|
|
|
166 INLINE static HANDLE uv__get_osfhandle(int fd)
|
|
|
167 {
|
|
|
168 /* _get_osfhandle() raises an assert in debug builds if the FD is invalid.
|
|
|
169 * But it also correctly checks the FD and returns INVALID_HANDLE_VALUE for
|
|
|
170 * invalid FDs in release builds (or if you let the assert continue). So this
|
|
|
171 * wrapper function disables asserts when calling _get_osfhandle. */
|
|
|
172
|
|
|
173 HANDLE handle;
|
|
|
174 UV_BEGIN_DISABLE_CRT_ASSERT();
|
|
|
175 handle = (HANDLE) _get_osfhandle(fd);
|
|
|
176 UV_END_DISABLE_CRT_ASSERT();
|
|
|
177 return handle;
|
|
|
178 }
|
|
|
179
|
|
|
180 #endif /* UV_WIN_HANDLE_INL_H_ */
|