loop-watcher.c 7.8 KB

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