1e66f31c5Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2e66f31c5Sopenharmony_ci *
3e66f31c5Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
4e66f31c5Sopenharmony_ci * of this software and associated documentation files (the "Software"), to
5e66f31c5Sopenharmony_ci * deal in the Software without restriction, including without limitation the
6e66f31c5Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7e66f31c5Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is
8e66f31c5Sopenharmony_ci * furnished to do so, subject to the following conditions:
9e66f31c5Sopenharmony_ci *
10e66f31c5Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
11e66f31c5Sopenharmony_ci * all copies or substantial portions of the Software.
12e66f31c5Sopenharmony_ci *
13e66f31c5Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14e66f31c5Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15e66f31c5Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16e66f31c5Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17e66f31c5Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18e66f31c5Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19e66f31c5Sopenharmony_ci * IN THE SOFTWARE.
20e66f31c5Sopenharmony_ci */
21e66f31c5Sopenharmony_ci
22e66f31c5Sopenharmony_ci#include <assert.h>
23e66f31c5Sopenharmony_ci
24e66f31c5Sopenharmony_ci#include "uv.h"
25e66f31c5Sopenharmony_ci#include "internal.h"
26e66f31c5Sopenharmony_ci#include "handle-inl.h"
27e66f31c5Sopenharmony_ci
28e66f31c5Sopenharmony_ci
29e66f31c5Sopenharmony_civoid uv__loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
30e66f31c5Sopenharmony_ci  if (handle->flags & UV_HANDLE_CLOSING) {
31e66f31c5Sopenharmony_ci    assert(!(handle->flags & UV_HANDLE_CLOSED));
32e66f31c5Sopenharmony_ci    handle->flags |= UV_HANDLE_CLOSED;
33e66f31c5Sopenharmony_ci    uv__handle_close(handle);
34e66f31c5Sopenharmony_ci  }
35e66f31c5Sopenharmony_ci}
36e66f31c5Sopenharmony_ci
37e66f31c5Sopenharmony_ci
38e66f31c5Sopenharmony_ci#define UV_LOOP_WATCHER_DEFINE(name, NAME)                                    \
39e66f31c5Sopenharmony_ci  int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) {              \
40e66f31c5Sopenharmony_ci    uv__handle_init(loop, (uv_handle_t*) handle, UV_##NAME);                  \
41e66f31c5Sopenharmony_ci                                                                              \
42e66f31c5Sopenharmony_ci    return 0;                                                                 \
43e66f31c5Sopenharmony_ci  }                                                                           \
44e66f31c5Sopenharmony_ci                                                                              \
45e66f31c5Sopenharmony_ci                                                                              \
46e66f31c5Sopenharmony_ci  int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) {           \
47e66f31c5Sopenharmony_ci    uv_loop_t* loop = handle->loop;                                           \
48e66f31c5Sopenharmony_ci    uv_##name##_t* old_head;                                                  \
49e66f31c5Sopenharmony_ci                                                                              \
50e66f31c5Sopenharmony_ci    assert(handle->type == UV_##NAME);                                        \
51e66f31c5Sopenharmony_ci                                                                              \
52e66f31c5Sopenharmony_ci    if (uv__is_active(handle))                                                \
53e66f31c5Sopenharmony_ci      return 0;                                                               \
54e66f31c5Sopenharmony_ci                                                                              \
55e66f31c5Sopenharmony_ci    if (cb == NULL)                                                           \
56e66f31c5Sopenharmony_ci      return UV_EINVAL;                                                       \
57e66f31c5Sopenharmony_ci                                                                              \
58e66f31c5Sopenharmony_ci    old_head = loop->name##_handles;                                          \
59e66f31c5Sopenharmony_ci                                                                              \
60e66f31c5Sopenharmony_ci    handle->name##_next = old_head;                                           \
61e66f31c5Sopenharmony_ci    handle->name##_prev = NULL;                                               \
62e66f31c5Sopenharmony_ci                                                                              \
63e66f31c5Sopenharmony_ci    if (old_head) {                                                           \
64e66f31c5Sopenharmony_ci      old_head->name##_prev = handle;                                         \
65e66f31c5Sopenharmony_ci    }                                                                         \
66e66f31c5Sopenharmony_ci                                                                              \
67e66f31c5Sopenharmony_ci    loop->name##_handles = handle;                                            \
68e66f31c5Sopenharmony_ci                                                                              \
69e66f31c5Sopenharmony_ci    handle->name##_cb = cb;                                                   \
70e66f31c5Sopenharmony_ci    uv__handle_start(handle);                                                 \
71e66f31c5Sopenharmony_ci                                                                              \
72e66f31c5Sopenharmony_ci    return 0;                                                                 \
73e66f31c5Sopenharmony_ci  }                                                                           \
74e66f31c5Sopenharmony_ci                                                                              \
75e66f31c5Sopenharmony_ci                                                                              \
76e66f31c5Sopenharmony_ci  int uv_##name##_stop(uv_##name##_t* handle) {                               \
77e66f31c5Sopenharmony_ci    uv_loop_t* loop = handle->loop;                                           \
78e66f31c5Sopenharmony_ci                                                                              \
79e66f31c5Sopenharmony_ci    assert(handle->type == UV_##NAME);                                        \
80e66f31c5Sopenharmony_ci                                                                              \
81e66f31c5Sopenharmony_ci    if (!uv__is_active(handle))                                               \
82e66f31c5Sopenharmony_ci      return 0;                                                               \
83e66f31c5Sopenharmony_ci                                                                              \
84e66f31c5Sopenharmony_ci    /* Update loop head if needed */                                          \
85e66f31c5Sopenharmony_ci    if (loop->name##_handles == handle) {                                     \
86e66f31c5Sopenharmony_ci      loop->name##_handles = handle->name##_next;                             \
87e66f31c5Sopenharmony_ci    }                                                                         \
88e66f31c5Sopenharmony_ci                                                                              \
89e66f31c5Sopenharmony_ci    /* Update the iterator-next pointer of needed */                          \
90e66f31c5Sopenharmony_ci    if (loop->next_##name##_handle == handle) {                               \
91e66f31c5Sopenharmony_ci      loop->next_##name##_handle = handle->name##_next;                       \
92e66f31c5Sopenharmony_ci    }                                                                         \
93e66f31c5Sopenharmony_ci                                                                              \
94e66f31c5Sopenharmony_ci    if (handle->name##_prev) {                                                \
95e66f31c5Sopenharmony_ci      handle->name##_prev->name##_next = handle->name##_next;                 \
96e66f31c5Sopenharmony_ci    }                                                                         \
97e66f31c5Sopenharmony_ci    if (handle->name##_next) {                                                \
98e66f31c5Sopenharmony_ci      handle->name##_next->name##_prev = handle->name##_prev;                 \
99e66f31c5Sopenharmony_ci    }                                                                         \
100e66f31c5Sopenharmony_ci                                                                              \
101e66f31c5Sopenharmony_ci    uv__handle_stop(handle);                                                  \
102e66f31c5Sopenharmony_ci                                                                              \
103e66f31c5Sopenharmony_ci    return 0;                                                                 \
104e66f31c5Sopenharmony_ci  }                                                                           \
105e66f31c5Sopenharmony_ci                                                                              \
106e66f31c5Sopenharmony_ci                                                                              \
107e66f31c5Sopenharmony_ci  void uv__##name##_invoke(uv_loop_t* loop) {                                 \
108e66f31c5Sopenharmony_ci    uv_##name##_t* handle;                                                    \
109e66f31c5Sopenharmony_ci                                                                              \
110e66f31c5Sopenharmony_ci    (loop)->next_##name##_handle = (loop)->name##_handles;                    \
111e66f31c5Sopenharmony_ci                                                                              \
112e66f31c5Sopenharmony_ci    while ((loop)->next_##name##_handle != NULL) {                            \
113e66f31c5Sopenharmony_ci      handle = (loop)->next_##name##_handle;                                  \
114e66f31c5Sopenharmony_ci      (loop)->next_##name##_handle = handle->name##_next;                     \
115e66f31c5Sopenharmony_ci                                                                              \
116e66f31c5Sopenharmony_ci      handle->name##_cb(handle);                                              \
117e66f31c5Sopenharmony_ci    }                                                                         \
118e66f31c5Sopenharmony_ci  }
119e66f31c5Sopenharmony_ci
120e66f31c5Sopenharmony_ciUV_LOOP_WATCHER_DEFINE(prepare, PREPARE)
121e66f31c5Sopenharmony_ciUV_LOOP_WATCHER_DEFINE(check, CHECK)
122e66f31c5Sopenharmony_ciUV_LOOP_WATCHER_DEFINE(idle, IDLE)
123