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#include <assert.h> 23 24#include "uv.h" 25#include "internal.h" 26#include "handle-inl.h" 27 28 29void uv__loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) { 30 if (handle->flags & UV_HANDLE_CLOSING) { 31 assert(!(handle->flags & UV_HANDLE_CLOSED)); 32 handle->flags |= UV_HANDLE_CLOSED; 33 uv__handle_close(handle); 34 } 35} 36 37 38#define UV_LOOP_WATCHER_DEFINE(name, NAME) \ 39 int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \ 40 uv__handle_init(loop, (uv_handle_t*) handle, UV_##NAME); \ 41 \ 42 return 0; \ 43 } \ 44 \ 45 \ 46 int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \ 47 uv_loop_t* loop = handle->loop; \ 48 uv_##name##_t* old_head; \ 49 \ 50 assert(handle->type == UV_##NAME); \ 51 \ 52 if (uv__is_active(handle)) \ 53 return 0; \ 54 \ 55 if (cb == NULL) \ 56 return UV_EINVAL; \ 57 \ 58 old_head = loop->name##_handles; \ 59 \ 60 handle->name##_next = old_head; \ 61 handle->name##_prev = NULL; \ 62 \ 63 if (old_head) { \ 64 old_head->name##_prev = handle; \ 65 } \ 66 \ 67 loop->name##_handles = handle; \ 68 \ 69 handle->name##_cb = cb; \ 70 uv__handle_start(handle); \ 71 \ 72 return 0; \ 73 } \ 74 \ 75 \ 76 int uv_##name##_stop(uv_##name##_t* handle) { \ 77 uv_loop_t* loop = handle->loop; \ 78 \ 79 assert(handle->type == UV_##NAME); \ 80 \ 81 if (!uv__is_active(handle)) \ 82 return 0; \ 83 \ 84 /* Update loop head if needed */ \ 85 if (loop->name##_handles == handle) { \ 86 loop->name##_handles = handle->name##_next; \ 87 } \ 88 \ 89 /* Update the iterator-next pointer of needed */ \ 90 if (loop->next_##name##_handle == handle) { \ 91 loop->next_##name##_handle = handle->name##_next; \ 92 } \ 93 \ 94 if (handle->name##_prev) { \ 95 handle->name##_prev->name##_next = handle->name##_next; \ 96 } \ 97 if (handle->name##_next) { \ 98 handle->name##_next->name##_prev = handle->name##_prev; \ 99 } \ 100 \ 101 uv__handle_stop(handle); \ 102 \ 103 return 0; \ 104 } \ 105 \ 106 \ 107 void uv__##name##_invoke(uv_loop_t* loop) { \ 108 uv_##name##_t* handle; \ 109 \ 110 (loop)->next_##name##_handle = (loop)->name##_handles; \ 111 \ 112 while ((loop)->next_##name##_handle != NULL) { \ 113 handle = (loop)->next_##name##_handle; \ 114 (loop)->next_##name##_handle = handle->name##_next; \ 115 \ 116 handle->name##_cb(handle); \ 117 } \ 118 } 119 120UV_LOOP_WATCHER_DEFINE(prepare, PREPARE) 121UV_LOOP_WATCHER_DEFINE(check, CHECK) 122UV_LOOP_WATCHER_DEFINE(idle, IDLE) 123