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 #ifndef TASK_H_ 23 #define TASK_H_ 24 25 #include "uv.h" 26 27 #include <stdio.h> 28 #include <stddef.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <inttypes.h> 32 #include <stdint.h> 33 34 #if !defined(_WIN32) 35 # include <sys/time.h> 36 # include <sys/resource.h> /* setrlimit() */ 37 #endif 38 39 #ifdef __clang__ 40 # pragma clang diagnostic ignored "-Wvariadic-macros" 41 # pragma clang diagnostic ignored "-Wc99-extensions" 42 #endif 43 44 #ifdef __GNUC__ 45 # pragma GCC diagnostic ignored "-Wvariadic-macros" 46 #endif 47 48 #define TEST_PORT 9123 49 #define TEST_PORT_2 9124 50 #define TEST_PORT_3 9125 51 52 #ifdef _WIN32 53 # define TEST_PIPENAME "\\\\.\\pipe\\uv-test" 54 # define TEST_PIPENAME_2 "\\\\.\\pipe\\uv-test2" 55 # define TEST_PIPENAME_3 "\\\\.\\pipe\\uv-test3" 56 #elif __ANDROID__ 57 # define TEST_PIPENAME "/data/local/tmp/uv-test-sock" 58 # define TEST_PIPENAME_2 "/data/local/tmp/uv-test-sock2" 59 # define TEST_PIPENAME_3 "/data/local/tmp/uv-test-sock3" 60 #else 61 # define TEST_PIPENAME "/tmp/uv-test-sock" 62 # define TEST_PIPENAME_2 "/tmp/uv-test-sock2" 63 # define TEST_PIPENAME_3 "/tmp/uv-test-sock3" 64 #endif 65 66 #ifdef _WIN32 67 # include <io.h> 68 # ifndef S_IRUSR 69 # define S_IRUSR _S_IREAD 70 # endif 71 # ifndef S_IWUSR 72 # define S_IWUSR _S_IWRITE 73 # endif 74 #endif 75 76 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 77 78 #define container_of(ptr, type, member) \ 79 ((type *) ((char *) (ptr) - offsetof(type, member))) 80 81 typedef enum { 82 TCP = 0, 83 UDP, 84 PIPE 85 } stream_type; 86 87 /* Die with fatal error. */ 88 #define FATAL(msg) \ 89 do { \ 90 fprintf(stderr, \ 91 "Fatal error in %s on line %d: %s\n", \ 92 __FILE__, \ 93 __LINE__, \ 94 msg); \ 95 fflush(stderr); \ 96 abort(); \ 97 } while (0) 98 99 /* Have our own assert, so we are sure it does not get optimized away in 100 * a release build. 101 */ 102 #define ASSERT(expr) \ 103 do { \ 104 if (!(expr)) { \ 105 fprintf(stderr, \ 106 "Assertion failed in %s on line %d: %s\n", \ 107 __FILE__, \ 108 __LINE__, \ 109 #expr); \ 110 abort(); \ 111 } \ 112 } while (0) 113 114 #define ASSERT_BASE(a, operator, b, type, conv) \ 115 do { \ 116 volatile type eval_a = (type) (a); \ 117 volatile type eval_b = (type) (b); \ 118 if (!(eval_a operator eval_b)) { \ 119 fprintf(stderr, \ 120 "Assertion failed in %s on line %d: `%s %s %s` " \ 121 "(%"conv" %s %"conv")\n", \ 122 __FILE__, \ 123 __LINE__, \ 124 #a, \ 125 #operator, \ 126 #b, \ 127 eval_a, \ 128 #operator, \ 129 eval_b); \ 130 abort(); \ 131 } \ 132 } while (0) 133 134 #define ASSERT_BASE_STR(expr, a, operator, b, type, conv) \ 135 do { \ 136 if (!(expr)) { \ 137 fprintf(stderr, \ 138 "Assertion failed in %s on line %d: `%s %s %s` " \ 139 "(%"conv" %s %"conv")\n", \ 140 __FILE__, \ 141 __LINE__, \ 142 #a, \ 143 #operator, \ 144 #b, \ 145 (type)a, \ 146 #operator, \ 147 (type)b); \ 148 abort(); \ 149 } \ 150 } while (0) 151 152 #define ASSERT_BASE_LEN(expr, a, operator, b, conv, len) \ 153 do { \ 154 if (!(expr)) { \ 155 fprintf(stderr, \ 156 "Assertion failed in %s on line %d: `%s %s %s` " \ 157 "(%.*"#conv" %s %.*"#conv")\n", \ 158 __FILE__, \ 159 __LINE__, \ 160 #a, \ 161 #operator, \ 162 #b, \ 163 (int)len, \ 164 a, \ 165 #operator, \ 166 (int)len, \ 167 b); \ 168 abort(); \ 169 } \ 170 } while (0) 171 172 #define ASSERT_BASE_HEX(expr, a, operator, b, size) \ 173 do { \ 174 if (!(expr)) { \ 175 int i; \ 176 unsigned char* a_ = (unsigned char*)a; \ 177 unsigned char* b_ = (unsigned char*)b; \ 178 fprintf(stderr, \ 179 "Assertion failed in %s on line %d: `%s %s %s` (", \ 180 __FILE__, \ 181 __LINE__, \ 182 #a, \ 183 #operator, \ 184 #b); \ 185 for (i = 0; i < size; ++i) { \ 186 if (i > 0) fprintf(stderr, ":"); \ 187 fprintf(stderr, "%02X", a_[i]); \ 188 } \ 189 fprintf(stderr, " %s ", #operator); \ 190 for (i = 0; i < size; ++i) { \ 191 if (i > 0) fprintf(stderr, ":"); \ 192 fprintf(stderr, "%02X", b_[i]); \ 193 } \ 194 fprintf(stderr, ")\n"); \ 195 abort(); \ 196 } \ 197 } while (0) 198 199 #define ASSERT_EQ(a, b) ASSERT_BASE(a, ==, b, int64_t, PRId64) 200 #define ASSERT_GE(a, b) ASSERT_BASE(a, >=, b, int64_t, PRId64) 201 #define ASSERT_GT(a, b) ASSERT_BASE(a, >, b, int64_t, PRId64) 202 #define ASSERT_LE(a, b) ASSERT_BASE(a, <=, b, int64_t, PRId64) 203 #define ASSERT_LT(a, b) ASSERT_BASE(a, <, b, int64_t, PRId64) 204 #define ASSERT_NE(a, b) ASSERT_BASE(a, !=, b, int64_t, PRId64) 205 #define ASSERT_OK(a) ASSERT_BASE(a, ==, 0, int64_t, PRId64) 206 207 #define ASSERT_UINT64_EQ(a, b) ASSERT_BASE(a, ==, b, uint64_t, PRIu64) 208 #define ASSERT_UINT64_GE(a, b) ASSERT_BASE(a, >=, b, uint64_t, PRIu64) 209 #define ASSERT_UINT64_GT(a, b) ASSERT_BASE(a, >, b, uint64_t, PRIu64) 210 #define ASSERT_UINT64_LE(a, b) ASSERT_BASE(a, <=, b, uint64_t, PRIu64) 211 #define ASSERT_UINT64_LT(a, b) ASSERT_BASE(a, <, b, uint64_t, PRIu64) 212 #define ASSERT_UINT64_NE(a, b) ASSERT_BASE(a, !=, b, uint64_t, PRIu64) 213 214 #define ASSERT_DOUBLE_EQ(a, b) ASSERT_BASE(a, ==, b, double, "f") 215 #define ASSERT_DOUBLE_GE(a, b) ASSERT_BASE(a, >=, b, double, "f") 216 #define ASSERT_DOUBLE_GT(a, b) ASSERT_BASE(a, >, b, double, "f") 217 #define ASSERT_DOUBLE_LE(a, b) ASSERT_BASE(a, <=, b, double, "f") 218 #define ASSERT_DOUBLE_LT(a, b) ASSERT_BASE(a, <, b, double, "f") 219 #define ASSERT_DOUBLE_NE(a, b) ASSERT_BASE(a, !=, b, double, "f") 220 221 #define ASSERT_STR_EQ(a, b) \ 222 ASSERT_BASE_STR(strcmp(a, b) == 0, a, == , b, char*, "s") 223 224 #define ASSERT_STR_NE(a, b) \ 225 ASSERT_BASE_STR(strcmp(a, b) != 0, a, !=, b, char*, "s") 226 227 #define ASSERT_MEM_EQ(a, b, size) \ 228 ASSERT_BASE_LEN(memcmp(a, b, size) == 0, a, ==, b, s, size) 229 230 #define ASSERT_MEM_NE(a, b, size) \ 231 ASSERT_BASE_LEN(memcmp(a, b, size) != 0, a, !=, b, s, size) 232 233 #define ASSERT_MEM_HEX_EQ(a, b, size) \ 234 ASSERT_BASE_HEX(memcmp(a, b, size) == 0, a, ==, b, size) 235 236 #define ASSERT_MEM_HEX_NE(a, b, size) \ 237 ASSERT_BASE_HEX(memcmp(a, b, size) != 0, a, !=, b, size) 238 239 #define ASSERT_NULL(a) \ 240 ASSERT_BASE(a, ==, NULL, void*, "p") 241 242 #define ASSERT_NOT_NULL(a) \ 243 ASSERT_BASE(a, !=, NULL, void*, "p") 244 245 #define ASSERT_PTR_EQ(a, b) \ 246 ASSERT_BASE(a, ==, b, void*, "p") 247 248 #define ASSERT_PTR_NE(a, b) \ 249 ASSERT_BASE(a, !=, b, void*, "p") 250 251 #define ASSERT_PTR_LT(a, b) \ 252 ASSERT_BASE(a, <, b, void*, "p") 253 254 /* This macro cleans up the event loop. This is used to avoid valgrind 255 * warnings about memory being "leaked" by the event loop. 256 */ 257 #define MAKE_VALGRIND_HAPPY(loop) \ 258 do { \ 259 close_loop(loop); \ 260 ASSERT_EQ(0, uv_loop_close(loop)); \ 261 uv_library_shutdown(); \ 262 } while (0) 263 264 /* Just sugar for wrapping the main() for a task or helper. */ 265 #define TEST_IMPL(name) \ 266 int run_test_##name(void); \ 267 int run_test_##name(void) 268 269 #define BENCHMARK_IMPL(name) \ 270 int run_benchmark_##name(void); \ 271 int run_benchmark_##name(void) 272 273 #define HELPER_IMPL(name) \ 274 int run_helper_##name(void); \ 275 int run_helper_##name(void) 276 277 /* Format big numbers nicely. */ 278 char* fmt(char (*buf)[32], double d); 279 280 /* Reserved test exit codes. */ 281 enum test_status { 282 TEST_OK = 0, 283 TEST_SKIP = 7 284 }; 285 286 #define RETURN_OK() \ 287 do { \ 288 return TEST_OK; \ 289 } while (0) 290 291 #define RETURN_SKIP(explanation) \ 292 do { \ 293 fprintf(stderr, "%s\n", explanation); \ 294 fflush(stderr); \ 295 return TEST_SKIP; \ 296 } while (0) 297 298 #if !defined(_WIN32) 299 300 # define TEST_FILE_LIMIT(num) \ 301 do { \ 302 struct rlimit lim; \ 303 lim.rlim_cur = (num); \ 304 lim.rlim_max = lim.rlim_cur; \ 305 if (setrlimit(RLIMIT_NOFILE, &lim)) \ 306 RETURN_SKIP("File descriptor limit too low."); \ 307 } while (0) 308 309 #else /* defined(_WIN32) */ 310 311 # define TEST_FILE_LIMIT(num) do {} while (0) 312 313 #endif 314 315 #if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900 316 extern int snprintf(char*, size_t, const char*, ...); 317 #endif 318 319 #if defined(__clang__) || \ 320 defined(__GNUC__) || \ 321 defined(__INTEL_COMPILER) 322 # define UNUSED __attribute__((unused)) 323 #else 324 # define UNUSED 325 #endif 326 327 #if defined(_WIN32) 328 #define notify_parent_process() ((void) 0) 329 #else 330 extern void notify_parent_process(void); 331 #endif 332 333 /* Fully close a loop */ 334 static void close_walk_cb(uv_handle_t* handle, void* arg) { 335 if (!uv_is_closing(handle)) 336 uv_close(handle, NULL); 337 } 338 339 UNUSED static void close_loop(uv_loop_t* loop) { 340 uv_walk(loop, close_walk_cb, NULL); 341 uv_run(loop, UV_RUN_DEFAULT); 342 } 343 344 UNUSED static int can_ipv6(void) { 345 uv_interface_address_t* addr; 346 int supported; 347 int count; 348 int i; 349 350 if (uv_interface_addresses(&addr, &count)) 351 return 0; /* Assume no IPv6 support on failure. */ 352 353 supported = 0; 354 for (i = 0; supported == 0 && i < count; i += 1) 355 supported = (AF_INET6 == addr[i].address.address6.sin6_family); 356 357 uv_free_interface_addresses(addr, count); 358 return supported; 359 } 360 361 #if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__) 362 # define NO_FS_EVENTS "Filesystem watching not supported on this platform." 363 #endif 364 365 #if defined(__MSYS__) 366 # define NO_SEND_HANDLE_ON_PIPE \ 367 "MSYS2 runtime does not support sending handles on pipes." 368 #elif defined(__CYGWIN__) 369 # define NO_SEND_HANDLE_ON_PIPE \ 370 "Cygwin runtime does not support sending handles on pipes." 371 #endif 372 373 #if defined(__MSYS__) 374 # define NO_SELF_CONNECT \ 375 "MSYS2 runtime hangs on listen+connect in same process." 376 #elif defined(__CYGWIN__) 377 # define NO_SELF_CONNECT \ 378 "Cygwin runtime hangs on listen+connect in same process." 379 #endif 380 381 #if !defined(__linux__) && \ 382 !(defined(__FreeBSD__) && __FreeBSD_version >= 1301000) && \ 383 !defined(_WIN32) 384 # define NO_CPU_AFFINITY \ 385 "affinity not supported on this platform." 386 #endif 387 388 #endif /* TASK_H_ */ 389