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
31#if defined(_MSC_VER) && _MSC_VER < 1600
32# include "uv/stdint-msvc2008.h"
33#else
34# include <stdint.h>
35#endif
36
37#if !defined(_WIN32)
38# include <sys/time.h>
39# include <sys/resource.h> /* setrlimit() */
40#endif
41
42#ifdef __clang__
43# pragma clang diagnostic ignored "-Wvariadic-macros"
44# pragma clang diagnostic ignored "-Wc99-extensions"
45#endif
46
47#define TEST_PORT 9123
48#define TEST_PORT_2 9124
49
50#ifdef _WIN32
51# define TEST_PIPENAME "\\\\?\\pipe\\uv-test"
52# define TEST_PIPENAME_2 "\\\\?\\pipe\\uv-test2"
53# define TEST_PIPENAME_3 "\\\\?\\pipe\\uv-test3"
54#else
55# define TEST_PIPENAME "/tmp/uv-test-sock"
56# define TEST_PIPENAME_2 "/tmp/uv-test-sock2"
57# define TEST_PIPENAME_3 "/tmp/uv-test-sock3"
58#endif
59
60#ifdef _WIN32
61# include <io.h>
62# ifndef S_IRUSR
63# define S_IRUSR _S_IREAD
64# endif
65# ifndef S_IWUSR
66# define S_IWUSR _S_IWRITE
67# endif
68#endif
69
70#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
71
72#define container_of(ptr, type, member) \
73 ((type *) ((char *) (ptr) - offsetof(type, member)))
74
75typedef enum {
76 TCP = 0,
77 UDP,
78 PIPE
79} stream_type;
80
81/* Die with fatal error. */
82#define FATAL(msg) \
83 do { \
84 fprintf(stderr, \
85 "Fatal error in %s on line %d: %s\n", \
86 __FILE__, \
87 __LINE__, \
88 msg); \
89 fflush(stderr); \
90 abort(); \
91 } while (0)
92
93/* Have our own assert, so we are sure it does not get optimized away in
94 * a release build.
95 */
96#define ASSERT(expr) \
97 do { \
98 if (!(expr)) { \
99 fprintf(stderr, \
100 "Assertion failed in %s on line %d: %s\n", \
101 __FILE__, \
102 __LINE__, \
103 #expr); \
104 abort(); \
105 } \
106 } while (0)
107
108/* This macro cleans up the main loop. This is used to avoid valgrind
109 * warnings about memory being "leaked" by the main event loop.
110 */
111#define MAKE_VALGRIND_HAPPY() \
112 do { \
113 close_loop(uv_default_loop()); \
114 ASSERT(0 == uv_loop_close(uv_default_loop())); \
115 } while (0)
116
117/* Just sugar for wrapping the main() for a task or helper. */
118#define TEST_IMPL(name) \
119 int run_test_##name(void); \
120 int run_test_##name(void)
121
122#define BENCHMARK_IMPL(name) \
123 int run_benchmark_##name(void); \
124 int run_benchmark_##name(void)
125
126#define HELPER_IMPL(name) \
127 int run_helper_##name(void); \
128 int run_helper_##name(void)
129
130/* Pause the calling thread for a number of milliseconds. */
131void uv_sleep(int msec);
132
133/* Format big numbers nicely. WARNING: leaks memory. */
134const char* fmt(double d);
135
136/* Reserved test exit codes. */
137enum test_status {
138 TEST_OK = 0,
139 TEST_SKIP
140};
141
142#define RETURN_OK() \
143 do { \
144 return TEST_OK; \
145 } while (0)
146
147#define RETURN_SKIP(explanation) \
148 do { \
149 fprintf(stderr, "%s\n", explanation); \
150 fflush(stderr); \
151 return TEST_SKIP; \
152 } while (0)
153
154#if !defined(_WIN32)
155
156# define TEST_FILE_LIMIT(num) \
157 do { \
158 struct rlimit lim; \
159 lim.rlim_cur = (num); \
160 lim.rlim_max = lim.rlim_cur; \
161 if (setrlimit(RLIMIT_NOFILE, &lim)) \
162 RETURN_SKIP("File descriptor limit too low."); \
163 } while (0)
164
165#else /* defined(_WIN32) */
166
167# define TEST_FILE_LIMIT(num) do {} while (0)
168
169#endif
170
171#if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900
172extern int snprintf(char*, size_t, const char*, ...);
173#endif
174
175#if defined(__clang__) || \
176 defined(__GNUC__) || \
177 defined(__INTEL_COMPILER)
178# define UNUSED __attribute__((unused))
179#else
180# define UNUSED
181#endif
182
183#if defined(_WIN32)
184#define notify_parent_process() ((void) 0)
185#else
186extern void notify_parent_process(void);
187#endif
188
189/* Fully close a loop */
190static void close_walk_cb(uv_handle_t* handle, void* arg) {
191 if (!uv_is_closing(handle))
192 uv_close(handle, NULL);
193}
194
195UNUSED static void close_loop(uv_loop_t* loop) {
196 uv_walk(loop, close_walk_cb, NULL);
197 uv_run(loop, UV_RUN_DEFAULT);
198}
199
200UNUSED static int can_ipv6(void) {
201 uv_interface_address_t* addr;
202 int supported;
203 int count;
204 int i;
205
206 if (uv_interface_addresses(&addr, &count))
207 return 0; /* Assume no IPv6 support on failure. */
208
209 supported = 0;
210 for (i = 0; supported == 0 && i < count; i += 1)
211 supported = (AF_INET6 == addr[i].address.address6.sin6_family);
212
213 uv_free_interface_addresses(addr, count);
214 return supported;
215}
216
217#if defined(__CYGWIN__) || defined(__MSYS__)
218# define NO_FS_EVENTS "Filesystem watching not supported on this platform."
219#endif
220
221#if defined(__MSYS__)
222# define NO_SEND_HANDLE_ON_PIPE \
223 "MSYS2 runtime does not support sending handles on pipes."
224#elif defined(__CYGWIN__)
225# define NO_SEND_HANDLE_ON_PIPE \
226 "Cygwin runtime does not support sending handles on pipes."
227#endif
228
229#if defined(__MSYS__)
230# define NO_SELF_CONNECT \
231 "MSYS2 runtime hangs on listen+connect in same process."
232#elif defined(__CYGWIN__)
233# define NO_SELF_CONNECT \
234 "Cygwin runtime hangs on listen+connect in same process."
235#endif
236
237#endif /* TASK_H_ */
238