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