1107665Simp/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2209583Simp *
3107665Simp * Permission is hereby granted, free of charge, to any person obtaining a copy
4107665Simp * of this software and associated documentation files (the "Software"), to
5107665Simp * deal in the Software without restriction, including without limitation the
6107665Simp * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7107665Simp * sell copies of the Software, and to permit persons to whom the Software is
8107665Simp * furnished to do so, subject to the following conditions:
9107665Simp *
10107665Simp * The above copyright notice and this permission notice shall be included in
11107665Simp * all copies or substantial portions of the Software.
12107665Simp *
13107665Simp * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14107665Simp * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15107665Simp * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16107665Simp * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17107665Simp * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18107665Simp * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19107665Simp * IN THE SOFTWARE.
20107665Simp */
21107665Simp
22107665Simp#ifndef UV_WIN_HANDLE_INL_H_
23107665Simp#define UV_WIN_HANDLE_INL_H_
24107665Simp
25209583Simp#include <assert.h>
26209583Simp#include <io.h>
27209583Simp
28209583Simp#include "uv.h"
29209583Simp#include "internal.h"
30209583Simp
31209583Simp
32209583Simp#define DECREASE_ACTIVE_COUNT(loop, handle)                             \
33209583Simp  do {                                                                  \
34209583Simp    if (--(handle)->activecnt == 0 &&                                   \
35209583Simp        !((handle)->flags & UV_HANDLE_CLOSING)) {                       \
36209583Simp      uv__handle_stop((handle));                                        \
37209583Simp    }                                                                   \
38209583Simp    assert((handle)->activecnt >= 0);                                   \
39209583Simp  } while (0)
40209583Simp
41209583Simp
42209583Simp#define INCREASE_ACTIVE_COUNT(loop, handle)                             \
43209583Simp  do {                                                                  \
44209583Simp    if ((handle)->activecnt++ == 0) {                                   \
45209583Simp      uv__handle_start((handle));                                       \
46209583Simp    }                                                                   \
47209583Simp    assert((handle)->activecnt > 0);                                    \
48209583Simp  } while (0)
49209583Simp
50209583Simp
51209583Simp#define DECREASE_PENDING_REQ_COUNT(handle)                              \
52209583Simp  do {                                                                  \
53209583Simp    assert(handle->reqs_pending > 0);                                   \
54107665Simp    handle->reqs_pending--;                                             \
55107665Simp                                                                        \
56107665Simp    if (handle->flags & UV_HANDLE_CLOSING &&                            \
57107665Simp        handle->reqs_pending == 0) {                                    \
58107665Simp      uv__want_endgame(loop, (uv_handle_t*)handle);                     \
59107665Simp    }                                                                   \
60107665Simp  } while (0)
61107665Simp
62131397Simp
63107665Simp#define uv__handle_closing(handle)                                      \
64107665Simp  do {                                                                  \
65107665Simp    assert(!((handle)->flags & UV_HANDLE_CLOSING));                     \
66107665Simp                                                                        \
67107665Simp    if (!(((handle)->flags & UV_HANDLE_ACTIVE) &&                       \
68107665Simp          ((handle)->flags & UV_HANDLE_REF)))                           \
69131397Simp      uv__active_handle_add((uv_handle_t*) (handle));                   \
70131397Simp                                                                        \
71131397Simp    (handle)->flags |= UV_HANDLE_CLOSING;                               \
72107665Simp    (handle)->flags &= ~UV_HANDLE_ACTIVE;                               \
73209583Simp  } while (0)
74131397Simp
75107665Simp
76250186Seadler#define uv__handle_close(handle)                                        \
77250186Seadler  do {                                                                  \
78250186Seadler    QUEUE_REMOVE(&(handle)->handle_queue);                              \
79250186Seadler    uv__active_handle_rm((uv_handle_t*) (handle));                      \
80250186Seadler                                                                        \
81250186Seadler    (handle)->flags |= UV_HANDLE_CLOSED;                                \
82252508Sasomers                                                                        \
83250186Seadler    if ((handle)->close_cb)                                             \
84107665Simp      (handle)->close_cb((uv_handle_t*) (handle));                      \
85107665Simp  } while (0)
86107665Simp
87155073Spjd
88209583SimpINLINE static void uv__want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
89246121Sian  if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) {
90108014Simp    handle->flags |= UV_HANDLE_ENDGAME_QUEUED;
91252481Sasomers
92107665Simp    handle->endgame_next = loop->endgame_handles;
93107665Simp    loop->endgame_handles = handle;
94108783Simp  }
95107665Simp}
96107665Simp
97131397Simp
98107665SimpINLINE static void uv__process_endgames(uv_loop_t* loop) {
99107665Simp  uv_handle_t* handle;
100114086Simp
101114086Simp  while (loop->endgame_handles) {
102107665Simp    handle = loop->endgame_handles;
103131397Simp    loop->endgame_handles = handle->endgame_next;
104107665Simp
105113787Simp    handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
106107665Simp
107260519Sasomers    switch (handle->type) {
108260519Sasomers      case UV_TCP:
109260519Sasomers        uv__tcp_endgame(loop, (uv_tcp_t*) handle);
110260519Sasomers        break;
111260519Sasomers
112260519Sasomers      case UV_NAMED_PIPE:
113260519Sasomers        uv__pipe_endgame(loop, (uv_pipe_t*) handle);
114260519Sasomers        break;
115260519Sasomers
116260519Sasomers      case UV_TTY:
117260519Sasomers        uv__tty_endgame(loop, (uv_tty_t*) handle);
118260519Sasomers        break;
119260519Sasomers
120107665Simp      case UV_UDP:
121107665Simp        uv__udp_endgame(loop, (uv_udp_t*) handle);
122107665Simp        break;
123107665Simp
124107665Simp      case UV_POLL:
125121487Simp        uv__poll_endgame(loop, (uv_poll_t*) handle);
126108783Simp        break;
127108783Simp
128108783Simp      case UV_TIMER:
129108783Simp        uv__timer_close((uv_timer_t*) handle);
130155073Spjd        uv__handle_close(handle);
131155073Spjd        break;
132263880Sasomers
133263880Sasomers      case UV_PREPARE:
134263880Sasomers      case UV_CHECK:
135252482Sasomers      case UV_IDLE:
136252482Sasomers        uv__loop_watcher_endgame(loop, handle);
137247754Seadler        break;
138107665Simp
139152770Sjkoshy      case UV_ASYNC:
140152770Sjkoshy        uv__async_endgame(loop, (uv_async_t*) handle);
141253046Sasomers        break;
142253046Sasomers
143107665Simp      case UV_SIGNAL:
144107665Simp        uv__signal_endgame(loop, (uv_signal_t*) handle);
145107665Simp        break;
146108783Simp
147108783Simp      case UV_PROCESS:
148108783Simp        uv__process_endgame(loop, (uv_process_t*) handle);
149108783Simp        break;
150108783Simp
151243931Seadler      case UV_FS_EVENT:
152108783Simp        uv__fs_event_endgame(loop, (uv_fs_event_t*) handle);
153108783Simp        break;
154108783Simp
155108783Simp      case UV_FS_POLL:
156107665Simp        uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle);
157107665Simp        break;
158107665Simp
159107665Simp      default:
160246134Sian        assert(0);
161107665Simp        break;
162107665Simp    }
163107665Simp  }
164107665Simp}
165152406Sbland
166107665SimpINLINE static HANDLE uv__get_osfhandle(int fd)
167107665Simp{
168107665Simp  /* _get_osfhandle() raises an assert in debug builds if the FD is invalid.
169107665Simp   * But it also correctly checks the FD and returns INVALID_HANDLE_VALUE for
170107665Simp   * invalid FDs in release builds (or if you let the assert continue). So this
171107665Simp   * wrapper function disables asserts when calling _get_osfhandle. */
172107665Simp
173107665Simp  HANDLE handle;
174107665Simp  UV_BEGIN_DISABLE_CRT_ASSERT();
175243930Seadler  handle = (HANDLE) _get_osfhandle(fd);
176107665Simp  UV_END_DISABLE_CRT_ASSERT();
177107665Simp  return handle;
178107665Simp}
179243931Seadler
180107665Simp#endif /* UV_WIN_HANDLE_INL_H_ */
181107665Simp