test-fs-poll.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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 "uv.h"
  22. #include "task.h"
  23. #include <string.h>
  24. #define FIXTURE "testfile"
  25. static void timer_cb(uv_timer_t* handle);
  26. static void close_cb(uv_handle_t* handle);
  27. static void poll_cb(uv_fs_poll_t* handle,
  28. int status,
  29. const uv_stat_t* prev,
  30. const uv_stat_t* curr);
  31. static void poll_cb_fail(uv_fs_poll_t* handle,
  32. int status,
  33. const uv_stat_t* prev,
  34. const uv_stat_t* curr);
  35. static void poll_cb_noop(uv_fs_poll_t* handle,
  36. int status,
  37. const uv_stat_t* prev,
  38. const uv_stat_t* curr);
  39. static uv_fs_poll_t poll_handle;
  40. static uv_timer_t timer_handle;
  41. static uv_loop_t* loop;
  42. static int poll_cb_called;
  43. static int timer_cb_called;
  44. static int close_cb_called;
  45. static void touch_file(const char* path) {
  46. static int count;
  47. FILE* fp;
  48. int i;
  49. ASSERT((fp = fopen(FIXTURE, "w+")));
  50. /* Need to change the file size because the poller may not pick up
  51. * sub-second mtime changes.
  52. */
  53. i = ++count;
  54. while (i--)
  55. fputc('*', fp);
  56. fclose(fp);
  57. }
  58. static void close_cb(uv_handle_t* handle) {
  59. close_cb_called++;
  60. }
  61. static void timer_cb(uv_timer_t* handle) {
  62. touch_file(FIXTURE);
  63. timer_cb_called++;
  64. }
  65. static void poll_cb_fail(uv_fs_poll_t* handle,
  66. int status,
  67. const uv_stat_t* prev,
  68. const uv_stat_t* curr) {
  69. ASSERT(0 && "fail_cb called");
  70. }
  71. static void poll_cb_noop(uv_fs_poll_t* handle,
  72. int status,
  73. const uv_stat_t* prev,
  74. const uv_stat_t* curr) {
  75. }
  76. static void poll_cb(uv_fs_poll_t* handle,
  77. int status,
  78. const uv_stat_t* prev,
  79. const uv_stat_t* curr) {
  80. uv_stat_t zero_statbuf;
  81. memset(&zero_statbuf, 0, sizeof(zero_statbuf));
  82. ASSERT(handle == &poll_handle);
  83. ASSERT(1 == uv_is_active((uv_handle_t*) handle));
  84. ASSERT(prev != NULL);
  85. ASSERT(curr != NULL);
  86. switch (poll_cb_called++) {
  87. case 0:
  88. ASSERT(status == UV_ENOENT);
  89. ASSERT(0 == memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
  90. ASSERT(0 == memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
  91. touch_file(FIXTURE);
  92. break;
  93. case 1:
  94. ASSERT(status == 0);
  95. ASSERT(0 == memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
  96. ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
  97. ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 20, 0));
  98. break;
  99. case 2:
  100. ASSERT(status == 0);
  101. ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
  102. ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
  103. ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 200, 0));
  104. break;
  105. case 3:
  106. ASSERT(status == 0);
  107. ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
  108. ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
  109. remove(FIXTURE);
  110. break;
  111. case 4:
  112. ASSERT(status == UV_ENOENT);
  113. ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
  114. ASSERT(0 == memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
  115. uv_close((uv_handle_t*)handle, close_cb);
  116. break;
  117. default:
  118. ASSERT(0);
  119. }
  120. }
  121. TEST_IMPL(fs_poll) {
  122. loop = uv_default_loop();
  123. remove(FIXTURE);
  124. ASSERT(0 == uv_timer_init(loop, &timer_handle));
  125. ASSERT(0 == uv_fs_poll_init(loop, &poll_handle));
  126. ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb, FIXTURE, 100));
  127. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  128. ASSERT(poll_cb_called == 5);
  129. ASSERT(timer_cb_called == 2);
  130. ASSERT(close_cb_called == 1);
  131. MAKE_VALGRIND_HAPPY();
  132. return 0;
  133. }
  134. TEST_IMPL(fs_poll_getpath) {
  135. char buf[1024];
  136. size_t len;
  137. loop = uv_default_loop();
  138. remove(FIXTURE);
  139. ASSERT(0 == uv_fs_poll_init(loop, &poll_handle));
  140. len = sizeof buf;
  141. ASSERT(UV_EINVAL == uv_fs_poll_getpath(&poll_handle, buf, &len));
  142. ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
  143. len = sizeof buf;
  144. ASSERT(0 == uv_fs_poll_getpath(&poll_handle, buf, &len));
  145. ASSERT(buf[len - 1] != 0);
  146. ASSERT(buf[len] == '\0');
  147. ASSERT(0 == memcmp(buf, FIXTURE, len));
  148. uv_close((uv_handle_t*) &poll_handle, close_cb);
  149. ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
  150. ASSERT(close_cb_called == 1);
  151. MAKE_VALGRIND_HAPPY();
  152. return 0;
  153. }
  154. TEST_IMPL(fs_poll_close_request) {
  155. uv_loop_t loop;
  156. uv_fs_poll_t poll_handle;
  157. remove(FIXTURE);
  158. ASSERT(0 == uv_loop_init(&loop));
  159. ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
  160. ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
  161. uv_close((uv_handle_t*) &poll_handle, close_cb);
  162. while (close_cb_called == 0)
  163. uv_run(&loop, UV_RUN_ONCE);
  164. ASSERT(close_cb_called == 1);
  165. ASSERT(0 == uv_loop_close(&loop));
  166. MAKE_VALGRIND_HAPPY();
  167. return 0;
  168. }
  169. TEST_IMPL(fs_poll_close_request_multi_start_stop) {
  170. uv_loop_t loop;
  171. uv_fs_poll_t poll_handle;
  172. int i;
  173. remove(FIXTURE);
  174. ASSERT(0 == uv_loop_init(&loop));
  175. ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
  176. for (i = 0; i < 10; ++i) {
  177. ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
  178. ASSERT(0 == uv_fs_poll_stop(&poll_handle));
  179. }
  180. uv_close((uv_handle_t*) &poll_handle, close_cb);
  181. while (close_cb_called == 0)
  182. uv_run(&loop, UV_RUN_ONCE);
  183. ASSERT(close_cb_called == 1);
  184. ASSERT(0 == uv_loop_close(&loop));
  185. MAKE_VALGRIND_HAPPY();
  186. return 0;
  187. }
  188. TEST_IMPL(fs_poll_close_request_multi_stop_start) {
  189. uv_loop_t loop;
  190. uv_fs_poll_t poll_handle;
  191. int i;
  192. remove(FIXTURE);
  193. ASSERT(0 == uv_loop_init(&loop));
  194. ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
  195. for (i = 0; i < 10; ++i) {
  196. ASSERT(0 == uv_fs_poll_stop(&poll_handle));
  197. ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
  198. }
  199. uv_close((uv_handle_t*) &poll_handle, close_cb);
  200. while (close_cb_called == 0)
  201. uv_run(&loop, UV_RUN_ONCE);
  202. ASSERT(close_cb_called == 1);
  203. ASSERT(0 == uv_loop_close(&loop));
  204. MAKE_VALGRIND_HAPPY();
  205. return 0;
  206. }
  207. TEST_IMPL(fs_poll_close_request_stop_when_active) {
  208. /* Regression test for https://github.com/libuv/libuv/issues/2287. */
  209. uv_loop_t loop;
  210. uv_fs_poll_t poll_handle;
  211. remove(FIXTURE);
  212. ASSERT(0 == uv_loop_init(&loop));
  213. /* Set up all handles. */
  214. ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
  215. ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_noop, FIXTURE, 100));
  216. uv_run(&loop, UV_RUN_ONCE);
  217. /* Close the timer handle, and do not crash. */
  218. ASSERT(0 == uv_fs_poll_stop(&poll_handle));
  219. uv_run(&loop, UV_RUN_ONCE);
  220. /* Clean up after the test. */
  221. uv_close((uv_handle_t*) &poll_handle, close_cb);
  222. uv_run(&loop, UV_RUN_ONCE);
  223. ASSERT(close_cb_called == 1);
  224. ASSERT(0 == uv_loop_close(&loop));
  225. MAKE_VALGRIND_HAPPY();
  226. return 0;
  227. }