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 /* Tests commented out with XXX are ones that are failing on Linux */ 23 24 /* 25 * Purpose of this test is to check semantics of starting and stopping 26 * prepare, check and idle watchers. 27 * 28 * - A watcher must be able to safely stop or close itself; 29 * - Once a watcher is stopped or closed its callback should never be called. 30 * - If a watcher is closed, it is implicitly stopped and its close_cb should 31 * be called exactly once. 32 * - A watcher can safely start and stop other watchers of the same type. 33 * - Prepare and check watchers are called once per event loop iterations. 34 * - All active idle watchers are queued when the event loop has no more work 35 * to do. This is done repeatedly until all idle watchers are inactive. 36 * - If a watcher starts another watcher of the same type its callback is not 37 * immediately queued. For check and prepare watchers, that means that if 38 * a watcher makes another of the same type active, it'll not be called until 39 * the next event loop iteration. For idle. watchers this means that the 40 * newly activated idle watcher might not be queued immediately. 41 * - Prepare, check, idle watchers keep the event loop alive even when they're 42 * not active. 43 * 44 * This is what the test globally does: 45 * 46 * - prepare_1 is always active and counts event loop iterations. It also 47 * creates and starts prepare_2 every other iteration. Finally it verifies 48 * that no idle watchers are active before polling. 49 * - prepare_2 is started by prepare_1 every other iteration. It immediately 50 * stops itself. It verifies that a watcher is not queued immediately 51 * if created by another watcher of the same type. 52 * - There's a check watcher that stops the event loop after a certain number 53 * of iterations. It starts a varying number of idle_1 watchers. 54 * - Idle_1 watchers stop themselves after being called a few times. All idle_1 55 * watchers try to start the idle_2 watcher if it is not already started or 56 * awaiting its close callback. 57 * - The idle_2 watcher always exists but immediately closes itself after 58 * being started by a check_1 watcher. It verifies that a watcher is 59 * implicitly stopped when closed, and that a watcher can close itself 60 * safely. 61 * - There is a repeating timer. It does not keep the event loop alive 62 * (ev_unref) but makes sure that the loop keeps polling the system for 63 * events. 64 */ 65 66 67 #include "uv.h" 68 #include "task.h" 69 70 #include <math.h> 71 72 73 #define IDLE_COUNT 7 74 #define ITERATIONS 21 75 #define TIMEOUT 100 76 77 78 static uv_prepare_t prepare_1_handle; 79 static uv_prepare_t prepare_2_handle; 80 81 static uv_check_t check_handle; 82 83 static uv_idle_t idle_1_handles[IDLE_COUNT]; 84 static uv_idle_t idle_2_handle; 85 86 static uv_timer_t timer_handle; 87 88 89 static int loop_iteration = 0; 90 91 static int prepare_1_cb_called = 0; 92 static int prepare_1_close_cb_called = 0; 93 94 static int prepare_2_cb_called = 0; 95 static int prepare_2_close_cb_called = 0; 96 97 static int check_cb_called = 0; 98 static int check_close_cb_called = 0; 99 100 static int idle_1_cb_called = 0; 101 static int idle_1_close_cb_called = 0; 102 static int idles_1_active = 0; 103 104 static int idle_2_cb_called = 0; 105 static int idle_2_close_cb_called = 0; 106 static int idle_2_cb_started = 0; 107 static int idle_2_is_active = 0; 108 109 110 static void timer_cb(uv_timer_t* handle) { 111 ASSERT(handle == &timer_handle); 112 } 113 114 115 static void idle_2_close_cb(uv_handle_t* handle) { 116 fprintf(stderr, "%s", "IDLE_2_CLOSE_CB\n"); 117 fflush(stderr); 118 119 ASSERT(handle == (uv_handle_t*)&idle_2_handle); 120 121 ASSERT(idle_2_is_active); 122 123 idle_2_close_cb_called++; 124 idle_2_is_active = 0; 125 } 126 127 128 static void idle_2_cb(uv_idle_t* handle) { 129 fprintf(stderr, "%s", "IDLE_2_CB\n"); 130 fflush(stderr); 131 132 ASSERT(handle == &idle_2_handle); 133 134 idle_2_cb_called++; 135 136 uv_close((uv_handle_t*)handle, idle_2_close_cb); 137 } 138 139 140 static void idle_1_cb(uv_idle_t* handle) { 141 int r; 142 143 fprintf(stderr, "%s", "IDLE_1_CB\n"); 144 fflush(stderr); 145 146 ASSERT_NOT_NULL(handle); 147 ASSERT(idles_1_active > 0); 148 149 /* Init idle_2 and make it active */ 150 if (!idle_2_is_active && !uv_is_closing((uv_handle_t*)&idle_2_handle)) { 151 r = uv_idle_init(uv_default_loop(), &idle_2_handle); 152 ASSERT(r == 0); 153 r = uv_idle_start(&idle_2_handle, idle_2_cb); 154 ASSERT(r == 0); 155 idle_2_is_active = 1; 156 idle_2_cb_started++; 157 } 158 159 idle_1_cb_called++; 160 161 if (idle_1_cb_called % 5 == 0) { 162 r = uv_idle_stop((uv_idle_t*)handle); 163 ASSERT(r == 0); 164 idles_1_active--; 165 } 166 } 167 168 169 static void idle_1_close_cb(uv_handle_t* handle) { 170 fprintf(stderr, "%s", "IDLE_1_CLOSE_CB\n"); 171 fflush(stderr); 172 173 ASSERT_NOT_NULL(handle); 174 175 idle_1_close_cb_called++; 176 } 177 178 179 static void prepare_1_close_cb(uv_handle_t* handle) { 180 fprintf(stderr, "%s", "PREPARE_1_CLOSE_CB"); 181 fflush(stderr); 182 ASSERT(handle == (uv_handle_t*)&prepare_1_handle); 183 184 prepare_1_close_cb_called++; 185 } 186 187 188 static void check_close_cb(uv_handle_t* handle) { 189 fprintf(stderr, "%s", "CHECK_CLOSE_CB\n"); 190 fflush(stderr); 191 ASSERT(handle == (uv_handle_t*)&check_handle); 192 193 check_close_cb_called++; 194 } 195 196 197 static void prepare_2_close_cb(uv_handle_t* handle) { 198 fprintf(stderr, "%s", "PREPARE_2_CLOSE_CB\n"); 199 fflush(stderr); 200 ASSERT(handle == (uv_handle_t*)&prepare_2_handle); 201 202 prepare_2_close_cb_called++; 203 } 204 205 206 static void check_cb(uv_check_t* handle) { 207 int i, r; 208 209 fprintf(stderr, "%s", "CHECK_CB\n"); 210 fflush(stderr); 211 ASSERT(handle == &check_handle); 212 213 if (loop_iteration < ITERATIONS) { 214 /* Make some idle watchers active */ 215 for (i = 0; i < 1 + (loop_iteration % IDLE_COUNT); i++) { 216 r = uv_idle_start(&idle_1_handles[i], idle_1_cb); 217 ASSERT(r == 0); 218 idles_1_active++; 219 } 220 221 } else { 222 /* End of the test - close all handles */ 223 uv_close((uv_handle_t*)&prepare_1_handle, prepare_1_close_cb); 224 uv_close((uv_handle_t*)&check_handle, check_close_cb); 225 uv_close((uv_handle_t*)&prepare_2_handle, prepare_2_close_cb); 226 227 for (i = 0; i < IDLE_COUNT; i++) { 228 uv_close((uv_handle_t*)&idle_1_handles[i], idle_1_close_cb); 229 } 230 231 /* This handle is closed/recreated every time, close it only if it is 232 * active. */ 233 if (idle_2_is_active) { 234 uv_close((uv_handle_t*)&idle_2_handle, idle_2_close_cb); 235 } 236 } 237 238 check_cb_called++; 239 } 240 241 242 static void prepare_2_cb(uv_prepare_t* handle) { 243 int r; 244 245 fprintf(stderr, "%s", "PREPARE_2_CB\n"); 246 fflush(stderr); 247 ASSERT(handle == &prepare_2_handle); 248 249 /* Prepare_2 gets started by prepare_1 when (loop_iteration % 2 == 0), and it 250 * stops itself immediately. A started watcher is not queued until the next 251 * round, so when this callback is made (loop_iteration % 2 == 0) cannot be 252 * true. */ 253 ASSERT(loop_iteration % 2 != 0); 254 255 r = uv_prepare_stop((uv_prepare_t*)handle); 256 ASSERT(r == 0); 257 258 prepare_2_cb_called++; 259 } 260 261 262 static void prepare_1_cb(uv_prepare_t* handle) { 263 int r; 264 265 fprintf(stderr, "%s", "PREPARE_1_CB\n"); 266 fflush(stderr); 267 ASSERT(handle == &prepare_1_handle); 268 269 if (loop_iteration % 2 == 0) { 270 r = uv_prepare_start(&prepare_2_handle, prepare_2_cb); 271 ASSERT(r == 0); 272 } 273 274 prepare_1_cb_called++; 275 loop_iteration++; 276 277 printf("Loop iteration %d of %d.\n", loop_iteration, ITERATIONS); 278 } 279 280 281 TEST_IMPL(loop_handles) { 282 int i; 283 int r; 284 285 r = uv_prepare_init(uv_default_loop(), &prepare_1_handle); 286 ASSERT(r == 0); 287 r = uv_prepare_start(&prepare_1_handle, prepare_1_cb); 288 ASSERT(r == 0); 289 290 r = uv_check_init(uv_default_loop(), &check_handle); 291 ASSERT(r == 0); 292 r = uv_check_start(&check_handle, check_cb); 293 ASSERT(r == 0); 294 295 /* initialize only, prepare_2 is started by prepare_1_cb */ 296 r = uv_prepare_init(uv_default_loop(), &prepare_2_handle); 297 ASSERT(r == 0); 298 299 for (i = 0; i < IDLE_COUNT; i++) { 300 /* initialize only, idle_1 handles are started by check_cb */ 301 r = uv_idle_init(uv_default_loop(), &idle_1_handles[i]); 302 ASSERT(r == 0); 303 } 304 305 /* don't init or start idle_2, both is done by idle_1_cb */ 306 307 /* The timer callback is there to keep the event loop polling unref it as it 308 * is not supposed to keep the loop alive */ 309 r = uv_timer_init(uv_default_loop(), &timer_handle); 310 ASSERT(r == 0); 311 r = uv_timer_start(&timer_handle, timer_cb, TIMEOUT, TIMEOUT); 312 ASSERT(r == 0); 313 uv_unref((uv_handle_t*)&timer_handle); 314 315 r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); 316 ASSERT(r == 0); 317 318 ASSERT(loop_iteration == ITERATIONS); 319 320 ASSERT(prepare_1_cb_called == ITERATIONS); 321 ASSERT(prepare_1_close_cb_called == 1); 322 323 ASSERT(prepare_2_cb_called == ITERATIONS / 2); 324 ASSERT(prepare_2_close_cb_called == 1); 325 326 ASSERT(check_cb_called == ITERATIONS); 327 ASSERT(check_close_cb_called == 1); 328 329 /* idle_1_cb should be called a lot */ 330 ASSERT(idle_1_close_cb_called == IDLE_COUNT); 331 332 ASSERT(idle_2_close_cb_called == idle_2_cb_started); 333 ASSERT(idle_2_is_active == 0); 334 335 MAKE_VALGRIND_HAPPY(); 336 return 0; 337 } 338