xref: /illumos-gate/usr/src/lib/libnisdb/db_headers.h (revision 8b80e8cb6855118d46f605e91b5ed4ce83417395)
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