Home | History | Annotate | Line # | Download | only in win
      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_ */
    181