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 88INLINE 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 98INLINE 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 166INLINE 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_ */ 181