10e552da7Schristos /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
20e552da7Schristos *
30e552da7Schristos * Permission is hereby granted, free of charge, to any person obtaining a copy
40e552da7Schristos * of this software and associated documentation files (the "Software"), to
50e552da7Schristos * deal in the Software without restriction, including without limitation the
60e552da7Schristos * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
70e552da7Schristos * sell copies of the Software, and to permit persons to whom the Software is
80e552da7Schristos * furnished to do so, subject to the following conditions:
90e552da7Schristos *
100e552da7Schristos * The above copyright notice and this permission notice shall be included in
110e552da7Schristos * all copies or substantial portions of the Software.
120e552da7Schristos *
130e552da7Schristos * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
140e552da7Schristos * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
150e552da7Schristos * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
160e552da7Schristos * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
170e552da7Schristos * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
180e552da7Schristos * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
190e552da7Schristos * IN THE SOFTWARE.
200e552da7Schristos */
210e552da7Schristos
220e552da7Schristos #include <assert.h>
230e552da7Schristos
240e552da7Schristos #include "uv.h"
250e552da7Schristos #include "internal.h"
260e552da7Schristos #include "handle-inl.h"
270e552da7Schristos
280e552da7Schristos
uv__loop_watcher_endgame(uv_loop_t * loop,uv_handle_t * handle)29*5f2f4271Schristos void uv__loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
300e552da7Schristos if (handle->flags & UV_HANDLE_CLOSING) {
310e552da7Schristos assert(!(handle->flags & UV_HANDLE_CLOSED));
320e552da7Schristos handle->flags |= UV_HANDLE_CLOSED;
330e552da7Schristos uv__handle_close(handle);
340e552da7Schristos }
350e552da7Schristos }
360e552da7Schristos
370e552da7Schristos
380e552da7Schristos #define UV_LOOP_WATCHER_DEFINE(name, NAME) \
390e552da7Schristos int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
400e552da7Schristos uv__handle_init(loop, (uv_handle_t*) handle, UV_##NAME); \
410e552da7Schristos \
420e552da7Schristos return 0; \
430e552da7Schristos } \
440e552da7Schristos \
450e552da7Schristos \
460e552da7Schristos int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \
470e552da7Schristos uv_loop_t* loop = handle->loop; \
480e552da7Schristos uv_##name##_t* old_head; \
490e552da7Schristos \
500e552da7Schristos assert(handle->type == UV_##NAME); \
510e552da7Schristos \
520e552da7Schristos if (uv__is_active(handle)) \
530e552da7Schristos return 0; \
540e552da7Schristos \
550e552da7Schristos if (cb == NULL) \
560e552da7Schristos return UV_EINVAL; \
570e552da7Schristos \
580e552da7Schristos old_head = loop->name##_handles; \
590e552da7Schristos \
600e552da7Schristos handle->name##_next = old_head; \
610e552da7Schristos handle->name##_prev = NULL; \
620e552da7Schristos \
630e552da7Schristos if (old_head) { \
640e552da7Schristos old_head->name##_prev = handle; \
650e552da7Schristos } \
660e552da7Schristos \
670e552da7Schristos loop->name##_handles = handle; \
680e552da7Schristos \
690e552da7Schristos handle->name##_cb = cb; \
700e552da7Schristos uv__handle_start(handle); \
710e552da7Schristos \
720e552da7Schristos return 0; \
730e552da7Schristos } \
740e552da7Schristos \
750e552da7Schristos \
760e552da7Schristos int uv_##name##_stop(uv_##name##_t* handle) { \
770e552da7Schristos uv_loop_t* loop = handle->loop; \
780e552da7Schristos \
790e552da7Schristos assert(handle->type == UV_##NAME); \
800e552da7Schristos \
810e552da7Schristos if (!uv__is_active(handle)) \
820e552da7Schristos return 0; \
830e552da7Schristos \
840e552da7Schristos /* Update loop head if needed */ \
850e552da7Schristos if (loop->name##_handles == handle) { \
860e552da7Schristos loop->name##_handles = handle->name##_next; \
870e552da7Schristos } \
880e552da7Schristos \
890e552da7Schristos /* Update the iterator-next pointer of needed */ \
900e552da7Schristos if (loop->next_##name##_handle == handle) { \
910e552da7Schristos loop->next_##name##_handle = handle->name##_next; \
920e552da7Schristos } \
930e552da7Schristos \
940e552da7Schristos if (handle->name##_prev) { \
950e552da7Schristos handle->name##_prev->name##_next = handle->name##_next; \
960e552da7Schristos } \
970e552da7Schristos if (handle->name##_next) { \
980e552da7Schristos handle->name##_next->name##_prev = handle->name##_prev; \
990e552da7Schristos } \
1000e552da7Schristos \
1010e552da7Schristos uv__handle_stop(handle); \
1020e552da7Schristos \
1030e552da7Schristos return 0; \
1040e552da7Schristos } \
1050e552da7Schristos \
1060e552da7Schristos \
107*5f2f4271Schristos void uv__##name##_invoke(uv_loop_t* loop) { \
1080e552da7Schristos uv_##name##_t* handle; \
1090e552da7Schristos \
1100e552da7Schristos (loop)->next_##name##_handle = (loop)->name##_handles; \
1110e552da7Schristos \
1120e552da7Schristos while ((loop)->next_##name##_handle != NULL) { \
1130e552da7Schristos handle = (loop)->next_##name##_handle; \
1140e552da7Schristos (loop)->next_##name##_handle = handle->name##_next; \
1150e552da7Schristos \
1160e552da7Schristos handle->name##_cb(handle); \
1170e552da7Schristos } \
1180e552da7Schristos }
1190e552da7Schristos
1200e552da7Schristos UV_LOOP_WATCHER_DEFINE(prepare, PREPARE)
1210e552da7Schristos UV_LOOP_WATCHER_DEFINE(check, CHECK)
1220e552da7Schristos UV_LOOP_WATCHER_DEFINE(idle, IDLE)
123