1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * db_headers.h 23 * 24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #ifndef _DB_HEADERS_H 29 #define _DB_HEADERS_H 30 31 #include <rpc/rpc.h> 32 #include <syslog.h> 33 #include <stdlib.h> 34 #include <setjmp.h> 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 extern int verbose; 41 42 #ifdef __cplusplus 43 } 44 #endif 45 46 extern jmp_buf dbenv; 47 48 #define FATAL(msg, fcode) \ 49 { \ 50 syslog(LOG_ERR, "ERROR: %s", (msg)); \ 51 __nisdb_get_tsd()->fatalcode = (int)(fcode); \ 52 __nisdb_get_tsd()->fatalmsg = msg; \ 53 return; \ 54 } 55 #define FATAL3(msg, fcode, retval) \ 56 { \ 57 syslog(LOG_ERR, "ERROR: %s", (msg)); \ 58 __nisdb_get_tsd()->fatalcode = (int)(fcode); \ 59 __nisdb_get_tsd()->fatalmsg = msg; \ 60 return (retval); \ 61 } 62 63 #ifdef NISDB_MT_DEBUG 64 #define LOCKVAL(lockcall, msg, lockcode) \ 65 { \ 66 lockcode = lockcall(); \ 67 if (lockcode != 0) { \ 68 __nisdb_get_tsd()->fatalcode = lockcode; \ 69 __nisdb_get_tsd()->fatalmsg = msg; \ 70 abort(); \ 71 } \ 72 } 73 #else 74 #define LOCKVAL(lockcall, msg, lockcode) \ 75 { \ 76 lockcode = lockcall(); \ 77 if (lockcode != 0) { \ 78 __nisdb_get_tsd()->fatalcode = lockcode; \ 79 __nisdb_get_tsd()->fatalmsg = msg; \ 80 } \ 81 } 82 #endif /* NISDB_MT_DEBUG */ 83 84 #define LOCKV(lockcall, msg) \ 85 { \ 86 int lockcode; \ 87 LOCKVAL(lockcall, msg, lockcode); \ 88 if (lockcode != 0) \ 89 return; \ 90 } 91 #define LOCK(lockcall, retval, msg) \ 92 { \ 93 int lockcode; \ 94 LOCKVAL(lockcall, msg, lockcode); \ 95 if (lockcode != 0) \ 96 return (retval); \ 97 } 98 99 /* Read lock/unlock 'this', return 'retval' is unsuccessful, and save 'msg' */ 100 #define READLOCK(this, retval, msg) \ 101 LOCK(this->acqnonexcl, retval, msg) 102 #define READUNLOCK(this, retval, msg) \ 103 LOCK(this->relnonexcl, retval, msg) 104 105 /* Ditto, but return without a value (i.e., a "void" function */ 106 #define READLOCKV(this, msg) \ 107 LOCKV(this->acqnonexcl, msg) 108 #define READUNLOCKV(this, msg) \ 109 LOCKV(this->relnonexcl, msg) 110 111 /* As READLOCK/READUNLOCK, but set rescode instead of returning on failure */ 112 #define READLOCKNR(this, rescode, msg) \ 113 LOCKVAL(this->acqnonexcl, msg, rescode) 114 #define READUNLOCKNR(this, rescode, msg) \ 115 LOCKVAL(this->relnonexcl, msg, rescode) 116 117 /* As READLOCK/READUNLOCK, but use a write lock */ 118 #define WRITELOCK(this, retval, msg) \ 119 LOCK(this->acqexcl, retval, msg) 120 #define WRITEUNLOCK(this, retval, msg) \ 121 LOCK(this->relexcl, retval, msg) 122 123 /* Non-blocking write lock */ 124 #define TRYWRITELOCK(this, rescode, msg) \ 125 LOCKVAL(this->tryacqexcl, msg, rescode) 126 127 /* Ditto, but return without a value */ 128 #define WRITELOCKV(this, msg) \ 129 LOCKV(this->acqexcl, msg) 130 #define WRITEUNLOCKV(this, msg) \ 131 LOCKV(this->relexcl, msg) 132 133 /* As WRITELOCK/WRITEUNLOCK, but set rescode instead of returning on failure */ 134 #define WRITELOCKNR(this, rescode, msg) \ 135 LOCKVAL(this->acqexcl, msg, rescode) 136 #define WRITEUNLOCKNR(this, rescode, msg) \ 137 LOCKVAL(this->relexcl, msg, rescode) 138 139 /* Apply a second write lock when already holding another write lock */ 140 #define WRITELOCK2(this, retval, msg, that) \ 141 if (this != 0) { \ 142 int lockcode1, lockcode2; \ 143 WRITELOCKNR(this, lockcode2, msg); \ 144 if (lockcode2 != 0) { \ 145 if (that != 0) { \ 146 WRITEUNLOCKNR(that, lockcode1, msg); \ 147 } \ 148 return (retval); \ 149 } \ 150 } 151 /* Release two write locks */ 152 #define WRITEUNLOCK2(this, that, retval1, retval2, msg1, msg2) \ 153 { \ 154 int lockcode1 = 0, lockcode2 = 0; \ 155 if (this != 0) { \ 156 WRITEUNLOCKNR(this, lockcode1, msg1); \ 157 } \ 158 if (that != 0) { \ 159 WRITEUNLOCKNR(that, lockcode2, msg2); \ 160 } \ 161 if (lockcode2 != 0) { \ 162 return (retval2); \ 163 } else if (lockcode1 != 0) { \ 164 return (retval1); \ 165 } \ 166 } 167 168 /* Apply a second read lock when already holding another read lock */ 169 #define READLOCK2(this, retval, msg, that) \ 170 if (this != 0) { \ 171 int lockcode1, lockcode2; \ 172 READLOCKNR(this, lockcode2, msg); \ 173 if (lockcode2 != 0) { \ 174 if (that != 0) { \ 175 READUNLOCKNR(that, lockcode1, msg); \ 176 } \ 177 return (retval); \ 178 } \ 179 } 180 /* Release two read locks */ 181 #define READUNLOCK2(this, that, retval1, retval2, msg1, msg2) \ 182 { \ 183 int lockcode1 = 0, lockcode2 = 0; \ 184 if (this != 0) { \ 185 READUNLOCKNR(this, lockcode1, msg1); \ 186 } \ 187 if (that != 0) { \ 188 READUNLOCKNR(that, lockcode2, msg2); \ 189 } \ 190 if (lockcode2 != 0) { \ 191 return (retval2); \ 192 } else if (lockcode1 != 0) { \ 193 return (retval1); \ 194 } \ 195 } 196 197 #define ASSERTWRITELOCKHELD(lvar, retval, msg) \ 198 { \ 199 int lc; \ 200 if ((lc = __nisdb_assert_wheld(&lvar ## _rwlock)) != 0) { \ 201 __nisdb_get_tsd()->fatalcode = lc; \ 202 __nisdb_get_tsd()->fatalmsg = msg; \ 203 return (retval); \ 204 } \ 205 } 206 207 #define WARNING(x) { syslog(LOG_ERR, "WARNING: %s", (x)); } 208 209 #define WARNING_M(x) { syslog(LOG_ERR, "WARNING: %s: %m", (x)); } 210 211 212 enum db_status {DB_SUCCESS, DB_NOTFOUND, DB_NOTUNIQUE, 213 DB_BADTABLE, DB_BADQUERY, DB_BADOBJECT, 214 DB_MEMORY_LIMIT, DB_STORAGE_LIMIT, DB_INTERNAL_ERROR, 215 DB_BADDICTIONARY, DB_SYNC_FAILED, DB_LOCK_ERROR}; 216 typedef enum db_status db_status; 217 218 enum db_action {DB_LOOKUP, DB_REMOVE, DB_ADD, DB_FIRST, DB_NEXT, DB_ALL, 219 DB_RESET_NEXT, DB_ADD_NOLOG, 220 DB_ADD_NOSYNC, DB_REMOVE_NOSYNC }; 221 typedef enum db_action db_action; 222 223 #endif /* _DB_HEADERS_H */ 224