1 /*
2 Copyright (c) 2004, 2021, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef NDB_GLOBAL_H
26 #define NDB_GLOBAL_H
27
28 #ifdef _WIN32
29 /* Workaround for Bug#32082: VOID refdefinition results in compile errors */
30 #ifndef DONT_DEFINE_VOID
31 #define DONT_DEFINE_VOID
32 #endif
33 #endif
34
35 #include <my_global.h>
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39 #ifdef HAVE_SYS_TIME_H
40 #include <sys/time.h>
41 #endif
42 #ifdef _WIN32
43 #include <process.h>
44 #endif
45
46 #if defined __GNUC__
47 # define ATTRIBUTE_FORMAT(style, m, n) __attribute__((format(style, m, n)))
48 #else
49 # define ATTRIBUTE_FORMAT(style, m, n)
50 #endif
51
52 #ifdef HAVE_NDB_CONFIG_H
53 #include "ndb_config.h"
54 #endif
55
56 #include <mysql_com.h>
57 #include <ndb_types.h>
58
59 #ifndef NDB_PORT
60 /* Default port used by ndb_mgmd */
61 #define NDB_PORT 1186
62 #endif
63
64 #if defined(_WIN32)
65 #define NDB_WIN32 1
66 #define NDB_WIN 1
67 #define PATH_MAX 256
68 #define DIR_SEPARATOR "\\"
69
70 /* Disable a few compiler warnings on Windows */
71 /* 4355: 'this': used in base member initializer list */
72 #pragma warning(disable: 4355)
73
74 #else
75 #undef NDB_WIN32
76 #undef NDB_WIN
77 #define DIR_SEPARATOR "/"
78 #endif
79
80 #if ! (NDB_SIZEOF_CHAR == SIZEOF_CHAR)
81 #error "Invalid define for Uint8"
82 #endif
83
84 #if ! (NDB_SIZEOF_INT == SIZEOF_INT)
85 #error "Invalid define for Uint32"
86 #endif
87
88 #if ! (NDB_SIZEOF_LONG_LONG == SIZEOF_LONG_LONG)
89 #error "Invalid define for Uint64"
90 #endif
91
92 #include <signal.h>
93
94 #ifdef _AIX
95 #undef _H_STRINGS
96 #endif
97 #include <m_string.h>
98
99 #ifndef NDB_REMOVE_BZERO
100 /*
101 Make it possible to use bzero in NDB although
102 MySQL headers redefines it to an invalid symbol
103 */
104 #ifdef bzero
105 #undef bzero
106 #endif
107
108 #ifdef HAVE_STRINGS_H
109 #include <strings.h>
110 #endif
111
112 #if !defined(bzero) && !defined(HAVE_BZERO)
113 #define bzero(A,B) memset((A),0,(B))
114 #endif
115 #endif
116
117 #include <m_ctype.h>
118 #include <ctype.h>
119
120 #ifdef HAVE_STDARG_H
121 #include <stdarg.h>
122 #endif
123
124 #ifdef TIME_WITH_SYS_TIME
125 #include <time.h>
126 #endif
127
128 #ifdef HAVE_FCNTL_H
129 #include <fcntl.h>
130 #endif
131
132 #include <sys/stat.h>
133
134 #ifdef HAVE_SYS_PARAM_H
135 #include <sys/param.h>
136 #endif
137
138 #ifdef HAVE_SYS_RESOURCE_H
139 #include <sys/resource.h>
140 #endif
141
142 #ifdef HAVE_SYS_WAIT_H
143 #include <sys/wait.h>
144 #endif
145
146 #ifdef HAVE_SYS_MMAN_H
147 #include <sys/mman.h>
148 #endif
149
150 #ifndef HAVE_STRDUP
151 extern char * strdup(const char *s);
152 #endif
153
154 static const char table_name_separator = '/';
155
156 #if defined(_AIX) || defined(WIN32) || defined(NDB_VC98)
157 #define STATIC_CONST(x) enum { x }
158 #else
159 #define STATIC_CONST(x) static const Uint32 x
160 #endif
161
162 #ifdef __cplusplus
163 extern "C" {
164 #endif
165
166 #include <assert.h>
167
168 #ifdef __cplusplus
169 }
170 #endif
171
172 #include "ndb_init.h"
173
174 #ifndef PATH_MAX
175 #define PATH_MAX 1024
176 #endif
177
178 #ifndef MIN
179 #define MIN(x,y) (((x)<(y))?(x):(y))
180 #endif
181
182 #ifndef MAX
183 #define MAX(x,y) (((x)>(y))?(x):(y))
184 #endif
185
186 /*
187 Dont allow use of min() or max() macros
188 - in order to enforce forward compatibilty
189 */
190
191 #ifdef min
192 #undef min
193 #endif
194
195 #ifdef max
196 #undef max
197 #endif
198
199 #define NDB_O_DIRECT_WRITE_ALIGNMENT 512
200
201 #ifndef STATIC_ASSERT
202 #if defined VM_TRACE
203 /**
204 * Compile-time assert for use from procedure body
205 * Zero length array not allowed in C
206 * Add use of array to avoid compiler warning
207 */
208 #define STATIC_ASSERT(expr) { char a_static_assert[(expr)? 1 : 0] = {'\0'}; if (a_static_assert[0]) {}; }
209 #else
210 #define STATIC_ASSERT(expr)
211 #endif
212 #endif
213
214 #define NDB_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
215
216
217 /*
218 NDB_STATIC_ASSERT(expr)
219 - Check coding assumptions during compile time
220 by laying out code that will generate a compiler error
221 if the expression is false.
222 */
223
224 #if (_MSC_VER > 1500) || (defined __GXX_EXPERIMENTAL_CXX0X__)
225
226 /*
227 Prefer to use the 'static_assert' function from C++0x
228 to get best error message
229 */
230 #define NDB_STATIC_ASSERT(expr) static_assert(expr, #expr)
231
232 #else
233
234 /*
235 Fallback to use home grown solution
236 (i.e use mysys version)
237 */
238
239 #define NDB_STATIC_ASSERT(expr) compile_time_assert(expr)
240
241 #endif
242
243
244 #if (_MSC_VER > 1500)
245 #define HAVE___HAS_TRIVIAL_CONSTRUCTOR
246 #define HAVE___IS_POD
247 #endif
248
249 #ifdef HAVE___HAS_TRIVIAL_CONSTRUCTOR
250 #define ASSERT_TYPE_HAS_CONSTRUCTOR(x) \
251 NDB_STATIC_ASSERT(!__has_trivial_constructor(x))
252 #else
253 #define ASSERT_TYPE_HAS_CONSTRUCTOR(x)
254 #endif
255
256 /**
257 * visual studio is stricter than gcc for __is_pod, settle for __has_trivial_constructor
258 * until we really really made all signal data classes POD
259 *
260 * UPDATE: also gcc fails to compile our code with gcc4.4.3
261 */
262 #ifdef HAVE___HAS_TRIVIAL_CONSTRUCTOR
263 #define NDB_ASSERT_POD(x) \
264 NDB_STATIC_ASSERT(__has_trivial_constructor(x))
265 #else
266 #define NDB_ASSERT_POD(x)
267 #endif
268
269 /**
270 * __attribute__((noreturn)) was introduce in gcc 2.5
271 */
272 #if (GCC_VERSION >= 2005)
273 #define ATTRIBUTE_NORETURN __attribute__((noreturn))
274 #else
275 #define ATTRIBUTE_NORETURN
276 #endif
277
278 /**
279 * __attribute__((noinline)) was introduce in gcc 3.1
280 */
281 #if (GCC_VERSION >= 3001)
282 #define ATTRIBUTE_NOINLINE __attribute__((noinline))
283 #else
284 #define ATTRIBUTE_NOINLINE
285 #endif
286
287 /**
288 * sizeof cacheline (in bytes)
289 *
290 * TODO: Add configure check...
291 */
292 #define NDB_CL 64
293
294 /**
295 * Pad to NDB_CL size
296 */
297 #define NDB_CL_PADSZ(x) (NDB_CL - ((x) % NDB_CL))
298
299 /*
300 * require is like a normal assert, only it's always on (eg. in release)
301 */
302 C_MODE_START
303 /** see below */
304 typedef int(*RequirePrinter)(const char *fmt, ...);
305 void require_failed(int exitcode, RequirePrinter p,
306 const char* expr, const char* file, int line)
307 ATTRIBUTE_NORETURN;
308 int ndbout_printer(const char * fmt, ...);
309 C_MODE_END
310 /*
311 * this allows for an exit() call if exitcode is not zero
312 * and takes a Printer to print the error
313 */
314 #define require_exit_or_core_with_printer(v, exitcode, printer) \
315 do { if (likely(!(!(v)))) break; \
316 require_failed((exitcode), (printer), #v, __FILE__, __LINE__); \
317 } while (0)
318
319 /*
320 * this allows for an exit() call if exitcode is not zero
321 */
322 #define require_exit_or_core(v, exitcode) \
323 require_exit_or_core_with_printer((v), (exitcode), 0)
324
325 /*
326 * this require is like a normal assert. (only it's always on)
327 */
328 #define require(v) require_exit_or_core_with_printer((v), 0, 0)
329
330 struct LinearSectionPtr
331 {
332 Uint32 sz;
333 Uint32 * p;
334 };
335
336 struct SegmentedSectionPtrPOD
337 {
338 Uint32 sz;
339 Uint32 i;
340 struct SectionSegment * p;
341
342 #ifdef __cplusplus
setNullSegmentedSectionPtrPOD343 void setNull() { p = 0;}
isNullSegmentedSectionPtrPOD344 bool isNull() const { return p == 0;}
345 inline SegmentedSectionPtrPOD& assign(struct SegmentedSectionPtr&);
346 #endif
347 };
348
349 struct SegmentedSectionPtr
350 {
351 Uint32 sz;
352 Uint32 i;
353 struct SectionSegment * p;
354
355 #ifdef __cplusplus
SegmentedSectionPtrSegmentedSectionPtr356 SegmentedSectionPtr() {}
SegmentedSectionPtrSegmentedSectionPtr357 SegmentedSectionPtr(Uint32 sz_arg, Uint32 i_arg,
358 struct SectionSegment *p_arg)
359 :sz(sz_arg), i(i_arg), p(p_arg)
360 {}
SegmentedSectionPtrSegmentedSectionPtr361 SegmentedSectionPtr(const SegmentedSectionPtrPOD & src)
362 :sz(src.sz), i(src.i), p(src.p)
363 {}
364
setNullSegmentedSectionPtr365 void setNull() { p = 0;}
isNullSegmentedSectionPtr366 bool isNull() const { return p == 0;}
367 #endif
368 };
369
370 #ifdef __cplusplus
371 inline
372 SegmentedSectionPtrPOD&
assign(struct SegmentedSectionPtr & src)373 SegmentedSectionPtrPOD::assign(struct SegmentedSectionPtr& src)
374 {
375 this->i = src.i;
376 this->p = src.p;
377 this->sz = src.sz;
378 return *this;
379 }
380 #endif
381
382 /* Abstract interface for iterating over
383 * words in a section
384 */
385 #ifdef __cplusplus
386 struct GenericSectionIterator
387 {
~GenericSectionIteratorGenericSectionIterator388 virtual ~GenericSectionIterator() {};
389 virtual void reset()=0;
390 virtual const Uint32* getNextWords(Uint32& sz)=0;
391 };
392 #else
393 struct GenericSectionIterator;
394 #endif
395
396 struct GenericSectionPtr
397 {
398 Uint32 sz;
399 struct GenericSectionIterator* sectionIter;
400 };
401
402 #endif
403