Add BSD license file
[platform/upstream/db4.git] / build_windows / db_int.h
1 /* DO NOT EDIT: automatically built by dist/s_windows. */
2 /*-
3  * See the file LICENSE for redistribution information.
4  *
5  * Copyright (c) 1996-2009 Oracle.  All rights reserved.
6  *
7  * $Id$
8  */
9
10 #ifndef _DB_INT_H_
11 #define _DB_INT_H_
12
13 /*******************************************************
14  * Berkeley DB ANSI/POSIX include files.
15  *******************************************************/
16 #ifdef HAVE_SYSTEM_INCLUDE_FILES
17 #include <sys/types.h>
18 #ifdef DIAG_MVCC
19 #include <sys/mman.h>
20 #endif
21 #include <sys/stat.h>
22
23 #if defined(__INCLUDE_SELECT_H)
24 #ifdef HAVE_SYS_SELECT_H
25 #include <sys/select.h>
26 #endif
27 #ifdef HAVE_VXWORKS
28 #include <selectLib.h>
29 #endif
30 #endif
31
32 #if TIME_WITH_SYS_TIME
33 #include <sys/time.h>
34 #include <time.h>
35 #else
36 #if HAVE_SYS_TIME_H
37 #include <sys/time.h>
38 #else
39 #include <time.h>
40 #endif
41 #endif
42
43 #ifdef HAVE_VXWORKS
44 #include <net/uio.h>
45 #else
46 #include <sys/uio.h>
47 #endif
48
49 #if defined(__INCLUDE_NETWORKING)
50 #ifdef HAVE_SYS_SOCKET_H
51 #include <sys/socket.h>
52 #endif
53 #include <netinet/in.h>
54 #include <netdb.h>
55 #include <arpa/inet.h>
56 #endif
57
58 #if defined(STDC_HEADERS) || defined(__cplusplus)
59 #include <stdarg.h>
60 #else
61 #include <varargs.h>
62 #endif
63
64 #include <ctype.h>
65 #include <errno.h>
66 #include <fcntl.h>
67 #include <limits.h>
68 #include <signal.h>
69 #include <stddef.h>
70 #include <stdio.h>
71 #include <stdlib.h>
72 #include <string.h>
73 #include <unistd.h>
74
75 #if defined(__INCLUDE_DIRECTORY)
76 #if HAVE_DIRENT_H
77 # include <dirent.h>
78 # define NAMLEN(dirent) strlen((dirent)->d_name)
79 #else
80 # define dirent direct
81 # define NAMLEN(dirent) (dirent)->d_namlen
82 # if HAVE_SYS_NDIR_H
83 #  include <sys/ndir.h>
84 # endif
85 # if HAVE_SYS_DIR_H
86 #  include <sys/dir.h>
87 # endif
88 # if HAVE_NDIR_H
89 #  include <ndir.h>
90 # endif
91 #endif
92 #endif /* __INCLUDE_DIRECTORY */
93
94 #endif /* !HAVE_SYSTEM_INCLUDE_FILES */
95
96 #ifdef DB_WIN32
97 #include "dbinc/win_db.h"
98 #endif
99
100 #include "db.h"
101 #include "clib_port.h"
102
103 #include "dbinc/queue.h"
104 #include "dbinc/shqueue.h"
105
106 #if defined(__cplusplus)
107 extern "C" {
108 #endif
109
110 /*******************************************************
111  * Forward structure declarations.
112  *******************************************************/
113 struct __db_reginfo_t;  typedef struct __db_reginfo_t REGINFO;
114 struct __db_txnhead;    typedef struct __db_txnhead DB_TXNHEAD;
115 struct __db_txnlist;    typedef struct __db_txnlist DB_TXNLIST;
116 struct __vrfy_childinfo;typedef struct __vrfy_childinfo VRFY_CHILDINFO;
117 struct __vrfy_dbinfo;   typedef struct __vrfy_dbinfo VRFY_DBINFO;
118 struct __vrfy_pageinfo; typedef struct __vrfy_pageinfo VRFY_PAGEINFO;
119
120 typedef SH_TAILQ_HEAD(__hash_head) DB_HASHTAB;
121
122 /*******************************************************
123  * General purpose constants and macros.
124  *******************************************************/
125 #undef  FALSE
126 #define FALSE           0
127 #undef  TRUE
128 #define TRUE            (!FALSE)
129
130 #define MEGABYTE        1048576
131 #define GIGABYTE        1073741824
132
133 #define NS_PER_MS       1000000         /* Nanoseconds in a millisecond */
134 #define NS_PER_US       1000            /* Nanoseconds in a microsecond */
135 #define NS_PER_SEC      1000000000      /* Nanoseconds in a second */
136 #define US_PER_MS       1000            /* Microseconds in a millisecond */
137 #define US_PER_SEC      1000000         /* Microseconds in a second */
138 #define MS_PER_SEC      1000            /* Milliseconds in a second */
139
140 #define RECNO_OOB       0               /* Illegal record number. */
141
142 /* Test for a power-of-two (tests true for zero, which doesn't matter here). */
143 #define POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)
144
145 /* Test for valid page sizes. */
146 #define DB_MIN_PGSIZE   0x000200        /* Minimum page size (512). */
147 #define DB_MAX_PGSIZE   0x010000        /* Maximum page size (65536). */
148 #define IS_VALID_PAGESIZE(x)                                            \
149         (POWER_OF_TWO(x) && (x) >= DB_MIN_PGSIZE && ((x) <= DB_MAX_PGSIZE))
150
151 /* Minimum number of pages cached, by default. */
152 #define DB_MINPAGECACHE 16
153
154 /*
155  * If we are unable to determine the underlying filesystem block size, use
156  * 8K on the grounds that most OS's use less than 8K for a VM page size.
157  */
158 #define DB_DEF_IOSIZE   (8 * 1024)
159
160 /* Align an integer to a specific boundary. */
161 #undef  DB_ALIGN
162 #define DB_ALIGN(v, bound)                                              \
163         (((v) + (bound) - 1) & ~(((uintmax_t)(bound)) - 1))
164
165 /* Increment a pointer to a specific boundary. */
166 #undef  ALIGNP_INC
167 #define ALIGNP_INC(p, bound)                                            \
168         (void *)(((uintptr_t)(p) + (bound) - 1) & ~(((uintptr_t)(bound)) - 1))
169
170 /*
171  * Print an address as a u_long (a u_long is the largest type we can print
172  * portably).  Most 64-bit systems have made longs 64-bits, so this should
173  * work.
174  */
175 #define P_TO_ULONG(p)   ((u_long)(uintptr_t)(p))
176
177 /*
178  * Convert a pointer to a small integral value.
179  *
180  * The (u_int16_t)(uintptr_t) cast avoids warnings: the (uintptr_t) cast
181  * converts the value to an integral type, and the (u_int16_t) cast converts
182  * it to a small integral type so we don't get complaints when we assign the
183  * final result to an integral type smaller than uintptr_t.
184  */
185 #define P_TO_UINT32(p)  ((u_int32_t)(uintptr_t)(p))
186 #define P_TO_UINT16(p)  ((u_int16_t)(uintptr_t)(p))
187
188 /*
189  * There are several on-page structures that are declared to have a number of
190  * fields followed by a variable length array of items.  The structure size
191  * without including the variable length array or the address of the first of
192  * those elements can be found using SSZ.
193  *
194  * This macro can also be used to find the offset of a structure element in a
195  * structure.  This is used in various places to copy structure elements from
196  * unaligned memory references, e.g., pointers into a packed page.
197  *
198  * There are two versions because compilers object if you take the address of
199  * an array.
200  */
201 #undef  SSZ
202 #define SSZ(name, field)  P_TO_UINT16(&(((name *)0)->field))
203
204 #undef  SSZA
205 #define SSZA(name, field) P_TO_UINT16(&(((name *)0)->field[0]))
206
207 /* Structure used to print flag values. */
208 typedef struct __fn {
209         u_int32_t mask;                 /* Flag value. */
210         const char *name;               /* Flag name. */
211 } FN;
212
213 /* Set, clear and test flags. */
214 #define FLD_CLR(fld, f)         (fld) &= ~(f)
215 #define FLD_ISSET(fld, f)       ((fld) & (f))
216 #define FLD_SET(fld, f)         (fld) |= (f)
217 #define F_CLR(p, f)             (p)->flags &= ~(f)
218 #define F_ISSET(p, f)           ((p)->flags & (f))
219 #define F_SET(p, f)             (p)->flags |= (f)
220 #define LF_CLR(f)               ((flags) &= ~(f))
221 #define LF_ISSET(f)             ((flags) & (f))
222 #define LF_SET(f)               ((flags) |= (f))
223
224 /*
225  * Calculate a percentage.  The values can overflow 32-bit integer arithmetic
226  * so we use floating point.
227  *
228  * When calculating a bytes-vs-page size percentage, we're getting the inverse
229  * of the percentage in all cases, that is, we want 100 minus the percentage we
230  * calculate.
231  */
232 #define DB_PCT(v, total)                                                \
233         ((int)((total) == 0 ? 0 : ((double)(v) * 100) / (total)))
234 #define DB_PCT_PG(v, total, pgsize)                                     \
235         ((int)((total) == 0 ? 0 :                                       \
236             100 - ((double)(v) * 100) / (((double)total) * (pgsize))))
237
238 /*
239  * Statistics update shared memory and so are expensive -- don't update the
240  * values unless we're going to display the results.
241  */
242 #undef  STAT
243 #ifdef  HAVE_STATISTICS
244 #define STAT(x) x
245 #else
246 #define STAT(x)
247 #endif
248
249 /*
250  * Structure used for callback message aggregation.
251  *
252  * Display values in XXX_stat_print calls.
253  */
254 typedef struct __db_msgbuf {
255         char *buf;                      /* Heap allocated buffer. */
256         char *cur;                      /* Current end of message. */
257         size_t len;                     /* Allocated length of buffer. */
258 } DB_MSGBUF;
259 #define DB_MSGBUF_INIT(a) do {                                          \
260         (a)->buf = (a)->cur = NULL;                                     \
261         (a)->len = 0;                                                   \
262 } while (0)
263 #define DB_MSGBUF_FLUSH(env, a) do {                                    \
264         if ((a)->buf != NULL) {                                         \
265                 if ((a)->cur != (a)->buf)                               \
266                         __db_msg(env, "%s", (a)->buf);          \
267                 __os_free(env, (a)->buf);                               \
268                 DB_MSGBUF_INIT(a);                                      \
269         }                                                               \
270 } while (0)
271 #define STAT_FMT(msg, fmt, type, v) do {                                \
272         DB_MSGBUF __mb;                                                 \
273         DB_MSGBUF_INIT(&__mb);                                          \
274         __db_msgadd(env, &__mb, fmt, (type)(v));                        \
275         __db_msgadd(env, &__mb, "\t%s", msg);                           \
276         DB_MSGBUF_FLUSH(env, &__mb);                                    \
277 } while (0)
278 #define STAT_HEX(msg, v)                                                \
279         __db_msg(env, "%#lx\t%s", (u_long)(v), msg)
280 #define STAT_ISSET(msg, p)                                              \
281         __db_msg(env, "%sSet\t%s", (p) == NULL ? "!" : " ", msg)
282 #define STAT_LONG(msg, v)                                               \
283         __db_msg(env, "%ld\t%s", (long)(v), msg)
284 #define STAT_LSN(msg, lsnp)                                             \
285         __db_msg(env, "%lu/%lu\t%s",                                    \
286             (u_long)(lsnp)->file, (u_long)(lsnp)->offset, msg)
287 #define STAT_POINTER(msg, v)                                            \
288         __db_msg(env, "%#lx\t%s", P_TO_ULONG(v), msg)
289 #define STAT_STRING(msg, p) do {                                        \
290         const char *__p = p;    /* p may be a function call. */         \
291         __db_msg(env, "%s\t%s", __p == NULL ? "!Set" : __p, msg);       \
292 } while (0)
293 #define STAT_ULONG(msg, v)                                              \
294         __db_msg(env, "%lu\t%s", (u_long)(v), msg)
295
296 /*
297  * There are quite a few places in Berkeley DB where we want to initialize
298  * a DBT from a string or other random pointer type, using a length typed
299  * to size_t in most cases.  This macro avoids a lot of casting.  The macro
300  * comes in two flavors because we often want to clear the DBT first.
301  */
302 #define DB_SET_DBT(dbt, d, s)  do {                                     \
303         (dbt).data = (void *)(d);                                       \
304         (dbt).size = (u_int32_t)(s);                                    \
305 } while (0)
306 #define DB_INIT_DBT(dbt, d, s)  do {                                    \
307         memset(&(dbt), 0, sizeof(dbt));                                 \
308         DB_SET_DBT(dbt, d, s);                                          \
309 } while (0)
310
311 /*******************************************************
312  * API return values
313  *******************************************************/
314 /*
315  * Return values that are OK for each different call.  Most calls have a
316  * standard 'return of 0 is only OK value', but some, like db->get have
317  * DB_NOTFOUND as a return value, but it really isn't an error.
318  */
319 #define DB_RETOK_STD(ret)       ((ret) == 0)
320 #define DB_RETOK_DBCDEL(ret)    ((ret) == 0 || (ret) == DB_KEYEMPTY || \
321                                     (ret) == DB_NOTFOUND)
322 #define DB_RETOK_DBCGET(ret)    ((ret) == 0 || (ret) == DB_KEYEMPTY || \
323                                     (ret) == DB_NOTFOUND)
324 #define DB_RETOK_DBCPUT(ret)    ((ret) == 0 || (ret) == DB_KEYEXIST || \
325                                     (ret) == DB_NOTFOUND)
326 #define DB_RETOK_DBDEL(ret)     DB_RETOK_DBCDEL(ret)
327 #define DB_RETOK_DBGET(ret)     DB_RETOK_DBCGET(ret)
328 #define DB_RETOK_DBPUT(ret)     ((ret) == 0 || (ret) == DB_KEYEXIST)
329 #define DB_RETOK_EXISTS(ret)    DB_RETOK_DBCGET(ret)
330 #define DB_RETOK_LGGET(ret)     ((ret) == 0 || (ret) == DB_NOTFOUND)
331 #define DB_RETOK_MPGET(ret)     ((ret) == 0 || (ret) == DB_PAGE_NOTFOUND)
332 #define DB_RETOK_REPPMSG(ret)   ((ret) == 0 || \
333                                     (ret) == DB_REP_IGNORE || \
334                                     (ret) == DB_REP_ISPERM || \
335                                     (ret) == DB_REP_NEWMASTER || \
336                                     (ret) == DB_REP_NEWSITE || \
337                                     (ret) == DB_REP_NOTPERM)
338 #define DB_RETOK_REPMGR_START(ret) ((ret) == 0 || (ret) == DB_REP_IGNORE)
339
340 /* Find a reasonable operation-not-supported error. */
341 #ifdef  EOPNOTSUPP
342 #define DB_OPNOTSUP     EOPNOTSUPP
343 #else
344 #ifdef  ENOTSUP
345 #define DB_OPNOTSUP     ENOTSUP
346 #else
347 #define DB_OPNOTSUP     EINVAL
348 #endif
349 #endif
350
351 /*******************************************************
352  * Files.
353  *******************************************************/
354 /*
355  * We use 1024 as the maximum path length.  It's too hard to figure out what
356  * the real path length is, as it was traditionally stored in <sys/param.h>,
357  * and that file isn't always available.
358  */
359 #define DB_MAXPATHLEN   1024
360
361 #define PATH_DOT        "."     /* Current working directory. */
362                                 /* Path separator character(s). */
363 #define PATH_SEPARATOR  "\\/:"
364
365 /*******************************************************
366  * Environment.
367  *******************************************************/
368 /* Type passed to __db_appname(). */
369 typedef enum {
370         DB_APP_NONE=0,                  /* No type (region). */
371         DB_APP_DATA,                    /* Data file. */
372         DB_APP_LOG,                     /* Log file. */
373         DB_APP_TMP,                     /* Temporary file. */
374         DB_APP_RECOVER                  /* We are in recovery. */
375 } APPNAME;
376
377 /*
378  * A set of macros to check if various functionality has been configured.
379  *
380  * ALIVE_ON     The is_alive function is configured.
381  * CDB_LOCKING  CDB product locking.
382  * CRYPTO_ON    Security has been configured.
383  * LOCKING_ON   Locking has been configured.
384  * LOGGING_ON   Logging has been configured.
385  * MUTEX_ON     Mutexes have been configured.
386  * MPOOL_ON     Memory pool has been configured.
387  * REP_ON       Replication has been configured.
388  * RPC_ON       RPC has been configured.
389  * TXN_ON       Transactions have been configured.
390  *
391  * REP_ON is more complex than most: if the BDB library was compiled without
392  * replication support, ENV->rep_handle will be NULL; if the BDB library has
393  * replication support, but it was not configured, the region reference will
394  * be NULL.
395  */
396 #define ALIVE_ON(env)           ((env)->dbenv->is_alive != NULL)
397 #define CDB_LOCKING(env)        F_ISSET(env, ENV_CDB)
398 #define CRYPTO_ON(env)          ((env)->crypto_handle != NULL)
399 #define LOCKING_ON(env)         ((env)->lk_handle != NULL)
400 #define LOGGING_ON(env)         ((env)->lg_handle != NULL)
401 #define MPOOL_ON(env)           ((env)->mp_handle != NULL)
402 #define MUTEX_ON(env)           ((env)->mutex_handle != NULL)
403 #define REP_ON(env)                                                     \
404         ((env)->rep_handle != NULL && (env)->rep_handle->region != NULL)
405 #define RPC_ON(dbenv)           ((dbenv)->cl_handle != NULL)
406 #define TXN_ON(env)             ((env)->tx_handle != NULL)
407
408 /*
409  * STD_LOCKING  Standard locking, that is, locking was configured and CDB
410  *              was not.  We do not do locking in off-page duplicate trees,
411  *              so we check for that in the cursor first.
412  */
413 #define STD_LOCKING(dbc)                                                \
414         (!F_ISSET(dbc, DBC_OPD) &&                                      \
415             !CDB_LOCKING((dbc)->env) && LOCKING_ON((dbc)->env))
416
417 /*
418  * IS_RECOVERING: The system is running recovery.
419  */
420 #define IS_RECOVERING(env)                                              \
421         (LOGGING_ON(env) && F_ISSET((env)->lg_handle, DBLOG_RECOVER))
422
423 /* Initialization methods are often illegal before/after open is called. */
424 #define ENV_ILLEGAL_AFTER_OPEN(env, name)                               \
425         if (F_ISSET((env), ENV_OPEN_CALLED))                            \
426                 return (__db_mi_open(env, name, 1));
427 #define ENV_ILLEGAL_BEFORE_OPEN(env, name)                              \
428         if (!F_ISSET((env), ENV_OPEN_CALLED))                           \
429                 return (__db_mi_open(env, name, 0));
430
431 /* We're not actually user hostile, honest. */
432 #define ENV_REQUIRES_CONFIG(env, handle, i, flags)                      \
433         if (handle == NULL)                                             \
434                 return (__env_not_config(env, i, flags));
435 #define ENV_REQUIRES_CONFIG_XX(env, handle, i, flags)                   \
436         if ((env)->handle->region == NULL)                              \
437                 return (__env_not_config(env, i, flags));
438 #define ENV_NOT_CONFIGURED(env, handle, i, flags)                       \
439         if (F_ISSET((env), ENV_OPEN_CALLED))                            \
440                 ENV_REQUIRES_CONFIG(env, handle, i, flags)
441
442 #define ENV_ENTER(env, ip) do {                                         \
443         int __ret;                                                      \
444         PANIC_CHECK(env);                                               \
445         if ((env)->thr_hashtab == NULL)                                 \
446                 ip = NULL;                                              \
447         else {                                                          \
448                 if ((__ret =                                            \
449                     __env_set_state(env, &(ip), THREAD_ACTIVE)) != 0)   \
450                         return (__ret);                                 \
451         }                                                               \
452 } while (0)
453
454 #define FAILCHK_THREAD(env, ip) do {                                    \
455         if ((ip) != NULL)                                               \
456                 (ip)->dbth_state = THREAD_FAILCHK;                      \
457 } while (0)
458
459 #define ENV_GET_THREAD_INFO(env, ip) ENV_ENTER(env, ip)
460
461 #ifdef DIAGNOSTIC
462 #define ENV_LEAVE(env, ip) do {                                         \
463         if ((ip) != NULL) {                                             \
464                 DB_ASSERT(env, ((ip)->dbth_state == THREAD_ACTIVE  ||   \
465                     (ip)->dbth_state == THREAD_FAILCHK));               \
466                 (ip)->dbth_state = THREAD_OUT;                          \
467         }                                                               \
468 } while (0)
469 #else
470 #define ENV_LEAVE(env, ip) do {                                         \
471         if ((ip) != NULL)                                               \
472                 (ip)->dbth_state = THREAD_OUT;                          \
473 } while (0)
474 #endif
475 #ifdef DIAGNOSTIC
476 #define CHECK_THREAD(env) do {                                          \
477         if ((env)->thr_hashtab != NULL)                                 \
478                 (void)__env_set_state(env, NULL, THREAD_VERIFY);        \
479 } while (0)
480 #ifdef HAVE_STATISTICS
481 #define CHECK_MTX_THREAD(env, mtx) do {                                 \
482         if (mtx->alloc_id != MTX_MUTEX_REGION &&                        \
483             mtx->alloc_id != MTX_ENV_REGION &&                          \
484             mtx->alloc_id != MTX_APPLICATION)                           \
485                 CHECK_THREAD(env);                                      \
486 } while (0)
487 #else
488 #define CHECK_MTX_THREAD(env, mtx)
489 #endif
490 #else
491 #define CHECK_THREAD(env)
492 #define CHECK_MTX_THREAD(env, mtx)
493 #endif
494
495 typedef enum {
496         THREAD_SLOT_NOT_IN_USE=0,
497         THREAD_OUT,
498         THREAD_ACTIVE,
499         THREAD_BLOCKED,
500         THREAD_BLOCKED_DEAD,
501         THREAD_FAILCHK,
502         THREAD_VERIFY
503 } DB_THREAD_STATE;
504
505 typedef struct __pin_list {
506         roff_t b_ref;           /* offset to buffer. */
507         int region;             /* region containing buffer. */
508 } PIN_LIST;
509 #define PINMAX 4
510
511 struct __db_thread_info {
512         pid_t           dbth_pid;
513         db_threadid_t   dbth_tid;
514         DB_THREAD_STATE dbth_state;
515         SH_TAILQ_ENTRY  dbth_links;
516         /*
517          * The following fields track which buffers this thread of
518          * control has pinned in the mpool buffer cache.
519          */
520         u_int16_t       dbth_pincount;  /* Number of pins for this thread. */
521         u_int16_t       dbth_pinmax;    /* Number of slots allocated. */
522         roff_t          dbth_pinlist;   /* List of pins. */
523         PIN_LIST        dbth_pinarray[PINMAX];  /* Initial array of slots. */
524 };
525
526 typedef struct __env_thread_info {
527         u_int32_t       thr_count;
528         u_int32_t       thr_max;
529         u_int32_t       thr_nbucket;
530         roff_t          thr_hashoff;
531 } THREAD_INFO;
532
533 #define DB_EVENT(env, e, einfo) do {                                    \
534         DB_ENV *__dbenv = (env)->dbenv;                                 \
535         if (__dbenv->db_event_func != NULL)                             \
536                 __dbenv->db_event_func(__dbenv, e, einfo);              \
537 } while (0)
538
539 typedef struct __flag_map {
540         u_int32_t inflag, outflag;
541 } FLAG_MAP;
542
543 /*
544  * Internal database environment structure.
545  *
546  * This is the private database environment handle.  The public environment
547  * handle is the DB_ENV structure.   The library owns this structure, the user
548  * owns the DB_ENV structure.  The reason there are two structures is because
549  * the user's configuration outlives any particular DB_ENV->open call, and
550  * separate structures allows us to easily discard internal information without
551  * discarding the user's configuration.
552  */
553 struct __env {
554         DB_ENV *dbenv;                  /* Linked DB_ENV structure */
555
556         /*
557          * The ENV structure can be used concurrently, so field access is
558          * protected.
559          */
560         db_mutex_t mtx_env;             /* ENV structure mutex */
561
562         /*
563          * Some fields are included in the ENV structure rather than in the
564          * DB_ENV structure because they are only set as arguments to the
565          * DB_ENV->open method.  In other words, because of the historic API,
566          * not for any rational reason.
567          *
568          * Arguments to DB_ENV->open.
569          */
570         char     *db_home;              /* Database home */
571         u_int32_t open_flags;           /* Flags */
572         int       db_mode;              /* Default open permissions */
573
574         pid_t   pid_cache;              /* Cached process ID */
575
576         DB_FH   *lockfhp;               /* fcntl(2) locking file handle */
577
578         DB_LOCKER *env_lref;            /* Locker in non-threaded handles */
579
580         DB_DISTAB   recover_dtab;       /* Dispatch table for recover funcs */
581
582         int dir_mode;                   /* Intermediate directory perms. */
583
584         /* Thread tracking */
585         u_int32_t        thr_nbucket;   /* Number of hash buckets */
586         DB_HASHTAB      *thr_hashtab;   /* Hash table of DB_THREAD_INFO */
587
588         /* Mutex allocation */
589         struct {
590                 int       alloc_id;     /* Allocation ID argument */
591                 u_int32_t flags;        /* Flags argument */
592         } *mutex_iq;                    /* Initial mutexes queue */
593         u_int           mutex_iq_next;  /* Count of initial mutexes */
594         u_int           mutex_iq_max;   /* Maximum initial mutexes */
595
596         /*
597          * List of open DB handles for this ENV, used for cursor
598          * adjustment.  Must be protected for multi-threaded support.
599          */
600         db_mutex_t mtx_dblist;
601         int        db_ref;              /* DB handle reference count */
602         TAILQ_HEAD(__dblist, __db) dblist;
603
604         /*
605          * List of open file handles for this ENV.  Must be protected
606          * for multi-threaded support.
607          */
608         TAILQ_HEAD(__fdlist, __fh_t) fdlist;
609
610         db_mutex_t       mtx_mt;        /* Mersenne Twister mutex */
611         int              mti;           /* Mersenne Twister index */
612         u_long          *mt;            /* Mersenne Twister state vector */
613
614         DB_CIPHER       *crypto_handle; /* Crypto handle */
615         DB_LOCKTAB      *lk_handle;     /* Lock handle */
616         DB_LOG          *lg_handle;     /* Log handle */
617         DB_MPOOL        *mp_handle;     /* Mpool handle */
618         DB_MUTEXMGR     *mutex_handle;  /* Mutex handle */
619         DB_REP          *rep_handle;    /* Replication handle */
620         DB_TXNMGR       *tx_handle;     /* Txn handle */
621
622         /* Application callback to copy data to/from a custom data source */
623 #define DB_USERCOPY_GETDATA     0x0001
624 #define DB_USERCOPY_SETDATA     0x0002
625         int (*dbt_usercopy)
626             __P((DBT *, u_int32_t, void *, u_int32_t, u_int32_t));
627
628         REGINFO *reginfo;               /* REGINFO structure reference */
629
630 #define DB_TEST_ELECTINIT        1      /* after __rep_elect_init */
631 #define DB_TEST_ELECTVOTE1       2      /* after sending VOTE1 */
632 #define DB_TEST_POSTDESTROY      3      /* after destroy op */
633 #define DB_TEST_POSTLOG          4      /* after logging all pages */
634 #define DB_TEST_POSTLOGMETA      5      /* after logging meta in btree */
635 #define DB_TEST_POSTOPEN         6      /* after __os_open */
636 #define DB_TEST_POSTSYNC         7      /* after syncing the log */
637 #define DB_TEST_PREDESTROY       8      /* before destroy op */
638 #define DB_TEST_PREOPEN          9      /* before __os_open */
639 #define DB_TEST_SUBDB_LOCKS      10     /* subdb locking tests */
640         int     test_abort;             /* Abort value for testing */
641         int     test_check;             /* Checkpoint value for testing */
642         int     test_copy;              /* Copy value for testing */
643
644 #define ENV_CDB                 0x00000001 /* DB_INIT_CDB */
645 #define ENV_DBLOCAL             0x00000002 /* Environment for a private DB */
646 #define ENV_LITTLEENDIAN        0x00000004 /* Little endian system. */
647 #define ENV_LOCKDOWN            0x00000008 /* DB_LOCKDOWN set */
648 #define ENV_NO_OUTPUT_SET       0x00000010 /* No output channel set */
649 #define ENV_OPEN_CALLED         0x00000020 /* DB_ENV->open called */
650 #define ENV_PRIVATE             0x00000040 /* DB_PRIVATE set */
651 #define ENV_RECOVER_FATAL       0x00000080 /* Doing fatal recovery in env */
652 #define ENV_REF_COUNTED         0x00000100 /* Region references this handle */
653 #define ENV_SYSTEM_MEM          0x00000200 /* DB_SYSTEM_MEM set */
654 #define ENV_THREAD              0x00000400 /* DB_THREAD set */
655         u_int32_t flags;
656 };
657
658 /*******************************************************
659  * Database Access Methods.
660  *******************************************************/
661 /*
662  * DB_IS_THREADED --
663  *      The database handle is free-threaded (was opened with DB_THREAD).
664  */
665 #define DB_IS_THREADED(dbp)                                             \
666         ((dbp)->mutex != MUTEX_INVALID)
667
668 /* Initialization methods are often illegal before/after open is called. */
669 #define DB_ILLEGAL_AFTER_OPEN(dbp, name)                                \
670         if (F_ISSET((dbp), DB_AM_OPEN_CALLED))                          \
671                 return (__db_mi_open((dbp)->env, name, 1));
672 #define DB_ILLEGAL_BEFORE_OPEN(dbp, name)                               \
673         if (!F_ISSET((dbp), DB_AM_OPEN_CALLED))                         \
674                 return (__db_mi_open((dbp)->env, name, 0));
675 /* Some initialization methods are illegal if environment isn't local. */
676 #define DB_ILLEGAL_IN_ENV(dbp, name)                                    \
677         if (!F_ISSET((dbp)->env, ENV_DBLOCAL))                          \
678                 return (__db_mi_env((dbp)->env, name));
679 #define DB_ILLEGAL_METHOD(dbp, flags) {                                 \
680         int __ret;                                                      \
681         if ((__ret = __dbh_am_chk(dbp, flags)) != 0)                    \
682                 return (__ret);                                         \
683 }
684
685 /*
686  * Common DBC->internal fields.  Each access method adds additional fields
687  * to this list, but the initial fields are common.
688  */
689 #define __DBC_INTERNAL                                                  \
690         DBC      *opd;                  /* Off-page duplicate cursor. */\
691         DBC      *pdbc;                 /* Pointer to parent cursor. */ \
692                                                                         \
693         void     *page;                 /* Referenced page. */          \
694         u_int32_t part;                 /* Partition number. */         \
695         db_pgno_t root;                 /* Tree root. */                \
696         db_pgno_t pgno;                 /* Referenced page number. */   \
697         db_indx_t indx;                 /* Referenced key item index. */\
698                                                                         \
699         /* Streaming -- cache last position. */                         \
700         db_pgno_t stream_start_pgno;    /* Last start pgno. */          \
701         u_int32_t stream_off;           /* Current offset. */           \
702         db_pgno_t stream_curr_pgno;     /* Current overflow page. */    \
703                                                                         \
704         DB_LOCK         lock;           /* Cursor lock. */              \
705         db_lockmode_t   lock_mode;      /* Lock mode. */
706
707 struct __dbc_internal {
708         __DBC_INTERNAL
709 };
710
711 /* Actions that __db_master_update can take. */
712 typedef enum { MU_REMOVE, MU_RENAME, MU_OPEN } mu_action;
713
714 /*
715  * Access-method-common macro for determining whether a cursor
716  * has been initialized.
717  */
718 #ifdef HAVE_PARTITION
719 #define IS_INITIALIZED(dbc)     (DB_IS_PARTITIONED((dbc)->dbp) ?        \
720                 ((PART_CURSOR *)(dbc)->internal)->sub_cursor != NULL && \
721                 ((PART_CURSOR *)(dbc)->internal)->sub_cursor->          \
722                     internal->pgno != PGNO_INVALID :                    \
723                 (dbc)->internal->pgno != PGNO_INVALID)
724 #else
725 #define IS_INITIALIZED(dbc)     ((dbc)->internal->pgno != PGNO_INVALID)
726 #endif
727
728 /* Free the callback-allocated buffer, if necessary, hanging off of a DBT. */
729 #define FREE_IF_NEEDED(env, dbt)                                        \
730         if (F_ISSET((dbt), DB_DBT_APPMALLOC)) {                         \
731                 __os_ufree((env), (dbt)->data);                         \
732                 F_CLR((dbt), DB_DBT_APPMALLOC);                         \
733         }
734
735 /*
736  * Use memory belonging to object "owner" to return the results of
737  * any no-DBT-flag get ops on cursor "dbc".
738  */
739 #define SET_RET_MEM(dbc, owner)                         \
740         do {                                            \
741                 (dbc)->rskey = &(owner)->my_rskey;      \
742                 (dbc)->rkey = &(owner)->my_rkey;        \
743                 (dbc)->rdata = &(owner)->my_rdata;      \
744         } while (0)
745
746 /* Use the return-data memory src is currently set to use in dest as well. */
747 #define COPY_RET_MEM(src, dest)                         \
748         do {                                            \
749                 (dest)->rskey = (src)->rskey;           \
750                 (dest)->rkey = (src)->rkey;             \
751                 (dest)->rdata = (src)->rdata;           \
752         } while (0)
753
754 /* Reset the returned-memory pointers to their defaults. */
755 #define RESET_RET_MEM(dbc)                              \
756         do {                                            \
757                 (dbc)->rskey = &(dbc)->my_rskey;        \
758                 (dbc)->rkey = &(dbc)->my_rkey;          \
759                 (dbc)->rdata = &(dbc)->my_rdata;        \
760         } while (0)
761
762 /*******************************************************
763  * Mpool.
764  *******************************************************/
765 /*
766  * File types for DB access methods.  Negative numbers are reserved to DB.
767  */
768 #define DB_FTYPE_SET            -1              /* Call pgin/pgout functions. */
769 #define DB_FTYPE_NOTSET          0              /* Don't call... */
770 #define DB_LSN_OFF_NOTSET       -1              /* Not yet set. */
771 #define DB_CLEARLEN_NOTSET      UINT32_MAX      /* Not yet set. */
772
773 /* Structure used as the DB pgin/pgout pgcookie. */
774 typedef struct __dbpginfo {
775         size_t  db_pagesize;            /* Underlying page size. */
776         u_int32_t flags;                /* Some DB_AM flags needed. */
777         DBTYPE  type;                   /* DB type */
778 } DB_PGINFO;
779
780 /*******************************************************
781  * Log.
782  *******************************************************/
783 /* Initialize an LSN to 'zero'. */
784 #define ZERO_LSN(LSN) do {                                              \
785         (LSN).file = 0;                                                 \
786         (LSN).offset = 0;                                               \
787 } while (0)
788 #define IS_ZERO_LSN(LSN)        ((LSN).file == 0 && (LSN).offset == 0)
789
790 #define IS_INIT_LSN(LSN)        ((LSN).file == 1 && (LSN).offset == 0)
791 #define INIT_LSN(LSN)           do {                                    \
792         (LSN).file = 1;                                                 \
793         (LSN).offset = 0;                                               \
794 } while (0)
795
796 #define MAX_LSN(LSN) do {                                               \
797         (LSN).file = UINT32_MAX;                                        \
798         (LSN).offset = UINT32_MAX;                                      \
799 } while (0)
800 #define IS_MAX_LSN(LSN) \
801         ((LSN).file == UINT32_MAX && (LSN).offset == UINT32_MAX)
802
803 /* If logging is turned off, smash the lsn. */
804 #define LSN_NOT_LOGGED(LSN) do {                                        \
805         (LSN).file = 0;                                                 \
806         (LSN).offset = 1;                                               \
807 } while (0)
808 #define IS_NOT_LOGGED_LSN(LSN) \
809         ((LSN).file == 0 && (LSN).offset == 1)
810
811 /*
812  * LOG_COMPARE -- compare two LSNs.
813  */
814
815 #define LOG_COMPARE(lsn0, lsn1)                                         \
816     ((lsn0)->file != (lsn1)->file ?                                     \
817     ((lsn0)->file < (lsn1)->file ? -1 : 1) :                            \
818     ((lsn0)->offset != (lsn1)->offset ?                                 \
819     ((lsn0)->offset < (lsn1)->offset ? -1 : 1) : 0))
820
821 /*******************************************************
822  * Txn.
823  *******************************************************/
824 #define DB_NONBLOCK(C)  ((C)->txn != NULL && F_ISSET((C)->txn, TXN_NOWAIT))
825 #define NOWAIT_FLAG(txn) \
826         ((txn) != NULL && F_ISSET((txn), TXN_NOWAIT) ? DB_LOCK_NOWAIT : 0)
827 #define IS_REAL_TXN(txn)                                                \
828         ((txn) != NULL && !F_ISSET(txn, TXN_CDSGROUP))
829 #define IS_SUBTRANSACTION(txn)                                          \
830         ((txn) != NULL && (txn)->parent != NULL)
831
832 /*******************************************************
833  * Crypto.
834  *******************************************************/
835 #define DB_IV_BYTES     16              /* Bytes per IV */
836 #define DB_MAC_KEY      20              /* Bytes per MAC checksum */
837
838 /*******************************************************
839  * Compression
840  *******************************************************/
841 #define CMP_INT_SPARE_VAL       0xFC    /* Smallest byte value that the integer
842                                            compression algorithm doesn't use */
843
844 /*******************************************************
845  * Secondaries over RPC.
846  *******************************************************/
847 #ifdef CONFIG_TEST
848 /*
849  * These are flags passed to DB->associate calls by the Tcl API if running
850  * over RPC.  The RPC server will mask out these flags before making the real
851  * DB->associate call.
852  *
853  * These flags must coexist with the valid flags to DB->associate (currently
854  * DB_AUTO_COMMIT and DB_CREATE).  DB_AUTO_COMMIT is in the group of
855  * high-order shared flags (0xff000000), and DB_CREATE is in the low-order
856  * group (0x00000fff), so we pick a range in between.
857  */
858 #define DB_RPC2ND_MASK          0x00f00000 /* Reserved bits. */
859
860 #define DB_RPC2ND_REVERSEDATA   0x00100000 /* callback_n(0) _s_reversedata. */
861 #define DB_RPC2ND_NOOP          0x00200000 /* callback_n(1) _s_noop */
862 #define DB_RPC2ND_CONCATKEYDATA 0x00300000 /* callback_n(2) _s_concatkeydata */
863 #define DB_RPC2ND_CONCATDATAKEY 0x00400000 /* callback_n(3) _s_concatdatakey */
864 #define DB_RPC2ND_REVERSECONCAT 0x00500000 /* callback_n(4) _s_reverseconcat */
865 #define DB_RPC2ND_TRUNCDATA     0x00600000 /* callback_n(5) _s_truncdata */
866 #define DB_RPC2ND_CONSTANT      0x00700000 /* callback_n(6) _s_constant */
867 #define DB_RPC2ND_GETZIP        0x00800000 /* sj_getzip */
868 #define DB_RPC2ND_GETNAME       0x00900000 /* sj_getname */
869 #endif
870
871 #if defined(__cplusplus)
872 }
873 #endif
874
875 /*******************************************************
876  * Remaining general DB includes.
877  *******************************************************/
878
879
880 #include "dbinc/globals.h"
881 #include "dbinc/clock.h"
882 #include "dbinc/debug.h"
883 #include "dbinc/region.h"
884 #include "dbinc_auto/env_ext.h"
885 #include "dbinc/mutex.h"
886 #ifdef HAVE_REPLICATION_THREADS
887 #include "dbinc/repmgr.h"
888 #endif
889 #include "dbinc/rep.h"
890 #include "dbinc/os.h"
891 #include "dbinc_auto/clib_ext.h"
892 #include "dbinc_auto/common_ext.h"
893
894 /*******************************************************
895  * Remaining Log.
896  * These need to be defined after the general includes
897  * because they need rep.h from above.
898  *******************************************************/
899 /*
900  * Test if the environment is currently logging changes.  If we're in recovery
901  * or we're a replication client, we don't need to log changes because they're
902  * already in the log, even though we have a fully functional log system.
903  */
904 #define DBENV_LOGGING(env)                                              \
905         (LOGGING_ON(env) && !IS_REP_CLIENT(env) && (!IS_RECOVERING(env)))
906
907 /*
908  * Test if we need to log a change.  By default, we don't log operations without
909  * associated transactions, unless DIAGNOSTIC, DEBUG_ROP or DEBUG_WOP are on.
910  * This is because we want to get log records for read/write operations, and, if
911  * we are trying to debug something, more information is always better.
912  *
913  * The DBC_RECOVER flag is set when we're in abort, as well as during recovery;
914  * thus DBC_LOGGING may be false for a particular dbc even when DBENV_LOGGING
915  * is true.
916  *
917  * We explicitly use LOGGING_ON/IS_REP_CLIENT here because we don't want to pull
918  * in the log headers, which IS_RECOVERING (and thus DBENV_LOGGING) rely on, and
919  * because DBC_RECOVER should be set anytime IS_RECOVERING would be true.
920  *
921  * If we're not in recovery (master - doing an abort or a client applying
922  * a txn), then a client's only path through here is on an internal
923  * operation, and a master's only path through here is a transactional
924  * operation.  Detect if either is not the case.
925  */
926 #if defined(DIAGNOSTIC) || defined(DEBUG_ROP)  || defined(DEBUG_WOP)
927 #define DBC_LOGGING(dbc)        __dbc_logging(dbc)
928 #else
929 #define DBC_LOGGING(dbc)                                                \
930         ((dbc)->txn != NULL && LOGGING_ON((dbc)->env) &&                \
931             !F_ISSET((dbc), DBC_RECOVER) && !IS_REP_CLIENT((dbc)->env))
932 #endif
933
934 #endif /* !_DB_INT_H_ */