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 78static uv_prepare_t prepare_1_handle; 79static uv_prepare_t prepare_2_handle; 80 81static uv_check_t check_handle; 82 83static uv_idle_t idle_1_handles[IDLE_COUNT]; 84static uv_idle_t idle_2_handle; 85 86static uv_timer_t timer_handle; 87 88 89static int loop_iteration = 0; 90 91static int prepare_1_cb_called = 0; 92static int prepare_1_close_cb_called = 0; 93 94static int prepare_2_cb_called = 0; 95static int prepare_2_close_cb_called = 0; 96 97static int check_cb_called = 0; 98static int check_close_cb_called = 0; 99 100static int idle_1_cb_called = 0; 101static int idle_1_close_cb_called = 0; 102static int idles_1_active = 0; 103 104static int idle_2_cb_called = 0; 105static int idle_2_close_cb_called = 0; 106static int idle_2_cb_started = 0; 107static int idle_2_is_active = 0; 108 109 110static void timer_cb(uv_timer_t* handle) { 111 ASSERT_PTR_EQ(handle, &timer_handle); 112} 113 114 115static void idle_2_close_cb(uv_handle_t* handle) { 116 fprintf(stderr, "%s", "IDLE_2_CLOSE_CB\n"); 117 fflush(stderr); 118 119 ASSERT_PTR_EQ(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 128static void idle_2_cb(uv_idle_t* handle) { 129 fprintf(stderr, "%s", "IDLE_2_CB\n"); 130 fflush(stderr); 131 132 ASSERT_PTR_EQ(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 140static 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_GT(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_OK(r); 153 r = uv_idle_start(&idle_2_handle, idle_2_cb); 154 ASSERT_OK(r); 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_OK(r); 164 idles_1_active--; 165 } 166} 167 168 169static 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 179static void prepare_1_close_cb(uv_handle_t* handle) { 180 fprintf(stderr, "%s", "PREPARE_1_CLOSE_CB"); 181 fflush(stderr); 182 ASSERT_PTR_EQ(handle, (uv_handle_t*)&prepare_1_handle); 183 184 prepare_1_close_cb_called++; 185} 186 187 188static void check_close_cb(uv_handle_t* handle) { 189 fprintf(stderr, "%s", "CHECK_CLOSE_CB\n"); 190 fflush(stderr); 191 ASSERT_PTR_EQ(handle, (uv_handle_t*)&check_handle); 192 193 check_close_cb_called++; 194} 195 196 197static void prepare_2_close_cb(uv_handle_t* handle) { 198 fprintf(stderr, "%s", "PREPARE_2_CLOSE_CB\n"); 199 fflush(stderr); 200 ASSERT_PTR_EQ(handle, (uv_handle_t*)&prepare_2_handle); 201 202 prepare_2_close_cb_called++; 203} 204 205 206static void check_cb(uv_check_t* handle) { 207 int i, r; 208 209 fprintf(stderr, "%s", "CHECK_CB\n"); 210 fflush(stderr); 211 ASSERT_PTR_EQ(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_OK(r); 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 242static 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_PTR_EQ(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_NE(0, loop_iteration % 2); 254 255 r = uv_prepare_stop((uv_prepare_t*)handle); 256 ASSERT_OK(r); 257 258 prepare_2_cb_called++; 259} 260 261 262static 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_PTR_EQ(handle, &prepare_1_handle); 268 269 if (loop_iteration % 2 == 0) { 270 r = uv_prepare_start(&prepare_2_handle, prepare_2_cb); 271 ASSERT_OK(r); 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 281TEST_IMPL(loop_handles) { 282 int i; 283 int r; 284 285 r = uv_prepare_init(uv_default_loop(), &prepare_1_handle); 286 ASSERT_OK(r); 287 r = uv_prepare_start(&prepare_1_handle, prepare_1_cb); 288 ASSERT_OK(r); 289 290 r = uv_check_init(uv_default_loop(), &check_handle); 291 ASSERT_OK(r); 292 r = uv_check_start(&check_handle, check_cb); 293 ASSERT_OK(r); 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_OK(r); 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_OK(r); 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_OK(r); 311 r = uv_timer_start(&timer_handle, timer_cb, TIMEOUT, TIMEOUT); 312 ASSERT_OK(r); 313 uv_unref((uv_handle_t*)&timer_handle); 314 315 r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); 316 ASSERT_OK(r); 317 318 ASSERT_EQ(loop_iteration, ITERATIONS); 319 320 ASSERT_EQ(prepare_1_cb_called, ITERATIONS); 321 ASSERT_EQ(1, prepare_1_close_cb_called); 322 323 ASSERT_EQ(prepare_2_cb_called, ITERATIONS / 2); 324 ASSERT_EQ(1, prepare_2_close_cb_called); 325 326 ASSERT_EQ(check_cb_called, ITERATIONS); 327 ASSERT_EQ(1, check_close_cb_called); 328 329 /* idle_1_cb should be called a lot */ 330 ASSERT_EQ(idle_1_close_cb_called, IDLE_COUNT); 331 332 ASSERT_EQ(idle_2_close_cb_called, idle_2_cb_started); 333 ASSERT_OK(idle_2_is_active); 334 335 MAKE_VALGRIND_HAPPY(uv_default_loop()); 336 return 0; 337} 338