1 /*- 2 * Copyright (c) 2014-2018 MongoDB, Inc. 3 * Copyright (c) 2008-2014 WiredTiger, Inc. 4 * All rights reserved. 5 * 6 * See the file LICENSE for redistribution information. 7 */ 8 #define WT_COMPAT_MSG_PREFIX "Version incompatibility detected: " 9 10 #define WT_DEBUG_POINT ((void *)(uintptr_t)0xdeadbeef) 11 #define WT_DEBUG_BYTE (0xab) 12 13 /* In DIAGNOSTIC mode, yield in places where we want to encourage races. */ 14 #ifdef HAVE_DIAGNOSTIC 15 #define WT_DIAGNOSTIC_YIELD do { \ 16 __wt_yield(); \ 17 } while (0) 18 #else 19 #define WT_DIAGNOSTIC_YIELD 20 #endif 21 22 #define __wt_err(session, error, ...) \ 23 __wt_err_func(session, error, __func__, __LINE__, __VA_ARGS__) 24 #define __wt_errx(session, ...) \ 25 __wt_errx_func(session, __func__, __LINE__, __VA_ARGS__) 26 #define __wt_set_return(session, error) \ 27 __wt_set_return_func(session, __func__, __LINE__, error) 28 29 /* Set "ret" and branch-to-err-label tests. */ 30 #define WT_ERR(a) do { \ 31 if ((ret = (a)) != 0) \ 32 goto err; \ 33 } while (0) 34 #define WT_ERR_MSG(session, v, ...) do { \ 35 ret = (v); \ 36 __wt_err(session, ret, __VA_ARGS__); \ 37 goto err; \ 38 } while (0) 39 #define WT_ERR_TEST(a, v) do { \ 40 if (a) { \ 41 ret = (v); \ 42 goto err; \ 43 } else \ 44 ret = 0; \ 45 } while (0) 46 #define WT_ERR_ERROR_OK(a, e) \ 47 WT_ERR_TEST((ret = (a)) != 0 && ret != (e), ret) 48 #define WT_ERR_BUSY_OK(a) WT_ERR_ERROR_OK(a, EBUSY) 49 #define WT_ERR_NOTFOUND_OK(a) WT_ERR_ERROR_OK(a, WT_NOTFOUND) 50 51 /* Return tests. */ 52 #define WT_RET(a) do { \ 53 int __ret; \ 54 if ((__ret = (a)) != 0) \ 55 return (__ret); \ 56 } while (0) 57 #define WT_RET_TRACK(a) do { \ 58 int __ret; \ 59 if ((__ret = (a)) != 0) { \ 60 WT_TRACK_OP_END(session); \ 61 return (__ret); \ 62 } \ 63 } while (0) 64 #define WT_RET_MSG(session, v, ...) do { \ 65 int __ret = (v); \ 66 __wt_err(session, __ret, __VA_ARGS__); \ 67 return (__ret); \ 68 } while (0) 69 #define WT_RET_TEST(a, v) do { \ 70 if (a) \ 71 return (v); \ 72 } while (0) 73 #define WT_RET_ERROR_OK(a, e) do { \ 74 int __ret = (a); \ 75 WT_RET_TEST(__ret != 0 && __ret != (e), __ret); \ 76 } while (0) 77 #define WT_RET_BUSY_OK(a) WT_RET_ERROR_OK(a, EBUSY) 78 #define WT_RET_NOTFOUND_OK(a) WT_RET_ERROR_OK(a, WT_NOTFOUND) 79 /* Set "ret" if not already set. */ 80 #define WT_TRET(a) do { \ 81 int __ret; \ 82 if ((__ret = (a)) != 0 && \ 83 (__ret == WT_PANIC || \ 84 ret == 0 || ret == WT_DUPLICATE_KEY || \ 85 ret == WT_NOTFOUND || ret == WT_RESTART)) \ 86 ret = __ret; \ 87 } while (0) 88 #define WT_TRET_ERROR_OK(a, e) do { \ 89 int __ret; \ 90 if ((__ret = (a)) != 0 && __ret != (e) && \ 91 (__ret == WT_PANIC || \ 92 ret == 0 || ret == WT_DUPLICATE_KEY || \ 93 ret == WT_NOTFOUND || ret == WT_RESTART)) \ 94 ret = __ret; \ 95 } while (0) 96 #define WT_TRET_BUSY_OK(a) WT_TRET_ERROR_OK(a, EBUSY) 97 #define WT_TRET_NOTFOUND_OK(a) WT_TRET_ERROR_OK(a, WT_NOTFOUND) 98 99 /* Called on unexpected code path: locate the failure. */ 100 #define __wt_illegal_value(session, v) \ 101 __wt_illegal_value_func(session, (uintmax_t)(v), __func__, __LINE__) 102 103 /* Return and branch-to-err-label cases for switch statements. */ 104 #define WT_ILLEGAL_VALUE(session, v) \ 105 default: \ 106 return (__wt_illegal_value(session, v)) 107 #define WT_ILLEGAL_VALUE_ERR(session, v) \ 108 default: \ 109 ret = __wt_illegal_value(session, v); \ 110 goto err 111 112 #define WT_PANIC_MSG(session, v, ...) do { \ 113 __wt_err(session, v, __VA_ARGS__); \ 114 WT_IGNORE_RET(__wt_panic(session)); \ 115 } while (0) 116 #define WT_PANIC_ERR(session, v, ...) do { \ 117 WT_PANIC_MSG(session, v, __VA_ARGS__); \ 118 /* Return WT_PANIC regardless of earlier return codes. */ \ 119 WT_ERR(WT_PANIC); \ 120 } while (0) 121 #define WT_PANIC_RET(session, v, ...) do { \ 122 WT_PANIC_MSG(session, v, __VA_ARGS__); \ 123 /* Return WT_PANIC regardless of earlier return codes. */ \ 124 return (WT_PANIC); \ 125 } while (0) 126 127 /* 128 * WT_ASSERT 129 * Assert an expression, aborting in diagnostic mode. Otherwise, 130 * "use" the session to keep the compiler quiet and don't evaluate the 131 * expression. 132 */ 133 #ifdef HAVE_DIAGNOSTIC 134 #define WT_ASSERT(session, exp) do { \ 135 if (!(exp)) { \ 136 __wt_errx(session, "%s", #exp); \ 137 __wt_abort(session); \ 138 } \ 139 } while (0) 140 #else 141 #define WT_ASSERT(session, exp) \ 142 WT_UNUSED(session) 143 #endif 144 145 /* 146 * __wt_verbose -- 147 * Display a verbose message. 148 * 149 * Not an inlined function because you can't inline functions taking variadic 150 * arguments and we don't want to make a function call in production systems 151 * just to find out a verbose flag isn't set. 152 * 153 * The macro must take a format string and at least one additional argument, 154 * there's no portable way to remove the comma before an empty __VA_ARGS__ 155 * value. 156 */ 157 #define __wt_verbose(session, flag, fmt, ...) do { \ 158 if (WT_VERBOSE_ISSET(session, flag)) \ 159 __wt_verbose_worker(session, fmt, __VA_ARGS__); \ 160 } while (0) 161