diff options
Diffstat (limited to 'db2')
65 files changed, 924 insertions, 719 deletions
diff --git a/db2/Makefile b/db2/Makefile index a75dc5aef1..e6b35aa51b 100644 --- a/db2/Makefile +++ b/db2/Makefile @@ -19,7 +19,7 @@ # # Sub-makefile for libdb. # -# The code is lifted straight from the db 2.3.6 distribution +# The code is lifted straight from the db 2.3.10 distribution # with minimal changes. # diff --git a/db2/btree/bt_close.c b/db2/btree/bt_close.c index 7044599dd2..7dd7139c66 100644 --- a/db2/btree/bt_close.c +++ b/db2/btree/bt_close.c @@ -47,7 +47,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)bt_close.c 10.23 (Sleepycat) 9/2/97"; +static const char sccsid[] = "@(#)bt_close.c 10.24 (Sleepycat) 9/17/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -150,7 +150,7 @@ __bam_upstat(dbp) /* * We use a no-op log call to log the update of the statistics onto the - * metadata page. The dbp->close() call isn't transaction protected to + * metadata page. The Db->close call isn't transaction protected to * start with, and I'm not sure what undoing a statistics update means, * anyway. */ diff --git a/db2/btree/bt_conv.c b/db2/btree/bt_conv.c index c9d5d1bc3e..c89493cbed 100644 --- a/db2/btree/bt_conv.c +++ b/db2/btree/bt_conv.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)bt_conv.c 10.4 (Sleepycat) 9/3/97"; +static const char sccsid[] = "@(#)bt_conv.c 10.5 (Sleepycat) 9/15/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -21,12 +21,11 @@ static const char sccsid[] = "@(#)bt_conv.c 10.4 (Sleepycat) 9/3/97"; #include "btree.h" /* - * __bam_pgin, __bam_pgout -- - * Convert host-specific page layout to/from the host-independent - * format stored on disk. + * __bam_pgin -- + * Convert host-specific page layout from the host-independent format + * stored on disk. * * PUBLIC: int __bam_pgin __P((db_pgno_t, void *, DBT *)); - * PUBLIC: int __bam_pgout __P((db_pgno_t, void *, DBT *)); */ int __bam_pgin(pg, pp, cookie) @@ -39,9 +38,17 @@ __bam_pgin(pg, pp, cookie) pginfo = (DB_PGINFO *)cookie->data; if (!pginfo->needswap) return (0); - return (pg == PGNO_METADATA ? __bam_mswap(pp) : __db_pgin(pg, pp)); + return (pg == PGNO_METADATA ? + __bam_mswap(pp) : __db_pgin(pg, pginfo->db_pagesize, pp)); } +/* + * __bam_pgout -- + * Convert host-specific page layout to the host-independent format + * stored on disk. + * + * PUBLIC: int __bam_pgout __P((db_pgno_t, void *, DBT *)); + */ int __bam_pgout(pg, pp, cookie) db_pgno_t pg; @@ -53,7 +60,8 @@ __bam_pgout(pg, pp, cookie) pginfo = (DB_PGINFO *)cookie->data; if (!pginfo->needswap) return (0); - return (pg == PGNO_METADATA ? __bam_mswap(pp) : __db_pgout(pg, pp)); + return (pg == PGNO_METADATA ? + __bam_mswap(pp) : __db_pgout(pg, pginfo->db_pagesize, pp)); } /* diff --git a/db2/btree/bt_cursor.c b/db2/btree/bt_cursor.c index efae556030..a1266bcd3c 100644 --- a/db2/btree/bt_cursor.c +++ b/db2/btree/bt_cursor.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)bt_cursor.c 10.27 (Sleepycat) 9/3/97"; +static const char sccsid[] = "@(#)bt_cursor.c 10.33 (Sleepycat) 9/24/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -81,7 +81,10 @@ __bam_cursor(dbp, txn, dbcp) dbc->c_get = __bam_c_get; dbc->c_put = __bam_c_put; - /* All cursor structures hang off the main DB structure. */ + /* + * All cursors are queued from the master DB structure. Add the + * cursor to that queue. + */ DB_THREAD_LOCK(dbp); TAILQ_INSERT_HEAD(&dbp->curs_queue, dbc, links); DB_THREAD_UNLOCK(dbp); @@ -99,31 +102,53 @@ __bam_c_close(dbc) DBC *dbc; { DB *dbp; - CURSOR *cp; int ret; DEBUG_LWRITE(dbc->dbp, dbc->txn, "bam_c_close", NULL, NULL, 0); GETHANDLE(dbc->dbp, dbc->txn, &dbp, ret); + + ret = __bam_c_iclose(dbp, dbc); + + PUTHANDLE(dbp); + return (ret); +} + +/* + * __bam_c_iclose -- + * Close a single cursor -- internal version. + * + * PUBLIC: int __bam_c_iclose __P((DB *, DBC *)); + */ +int +__bam_c_iclose(dbp, dbc) + DB *dbp; + DBC *dbc; +{ + CURSOR *cp; + int ret; + cp = dbc->internal; - /* If a cursor key was deleted do the actual deletion. */ - ret = F_ISSET(cp, C_DELETED) ? __bam_c_physdel(dbp, cp, NULL) : 0; + /* If a cursor key was deleted, perform the actual deletion. */ + ret = F_ISSET(cp, C_DELETED) ? __bam_c_physdel(dbp, cp, NULL) : 0; /* Discard any lock if we're not inside a transaction. */ - if (dbp->txn == NULL && cp->lock != LOCK_INVALID) + if (cp->lock != LOCK_INVALID) (void)__BT_TLPUT(dbp, cp->lock); - /* Remove the cursor from the queue. */ - DB_THREAD_LOCK(dbp); - TAILQ_REMOVE(&dbp->curs_queue, dbc, links); - DB_THREAD_UNLOCK(dbp); + /* + * All cursors are queued from the master DB structure. Remove the + * cursor from that queue. + */ + DB_THREAD_LOCK(dbc->dbp); + TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links); + DB_THREAD_UNLOCK(dbc->dbp); /* Discard the structures. */ - FREE(cp, sizeof(CURSOR)); + FREE(dbc->internal, sizeof(CURSOR)); FREE(dbc, sizeof(DBC)); - PUTHANDLE(dbp); return (ret); } @@ -235,27 +260,22 @@ __bam_get(argdbp, txn, key, data, flags) if ((ret = __db_getchk(argdbp, key, data, flags)) != 0) return (ret); - /* Build a cursor. */ + /* Build an internal cursor. */ memset(&cp, 0, sizeof(cp)); cp.dbc = &dbc; cp.pgno = cp.dpgno = PGNO_INVALID; cp.lock = LOCK_INVALID; + cp.flags = C_INTERNAL; + /* Build an external cursor. */ memset(&dbc, 0, sizeof(dbc)); dbc.dbp = argdbp; dbc.txn = txn; dbc.internal = &cp; /* Get the key. */ - if ((ret = __bam_c_get(&dbc, - key, data, LF_ISSET(DB_SET_RECNO) ? DB_SET_RECNO : DB_SET)) != 0) - return (ret); - - /* Discard any lock, the cursor didn't really exist. */ - if (cp.lock != LOCK_INVALID) - (void)__BT_TLPUT(argdbp, cp.lock); - - return (0); + return(__bam_c_get(&dbc, + key, data, LF_ISSET(DB_SET_RECNO) ? DB_SET_RECNO : DB_SET)); } /* @@ -275,8 +295,7 @@ __bam_c_get(dbc, key, data, flags) int exact, ret; DEBUG_LREAD(dbc->dbp, dbc->txn, "bam_c_get", - flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, - NULL, flags); + flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags); cp = dbc->internal; @@ -399,6 +418,10 @@ __bam_c_get(dbc, key, data, flags) /* Release the pinned page. */ ret = memp_fput(dbp->mpf, cp->page, 0); + /* Internal cursors don't hold locks. */ + if (F_ISSET(cp, C_INTERNAL) && cp->lock != LOCK_INVALID) + (void)__BT_TLPUT(dbp, cp->lock); + ++t->lstat.bt_get; if (0) { @@ -864,7 +887,7 @@ __bam_c_prev(dbp, cp) * If at the beginning of the page, move to any previous one. * * !!! - * This code handles empty pages and pages with only deleted entries. + * This code handles empty pages and pages with only deleted entries. */ for (;;) { if (indx == 0) { @@ -1472,8 +1495,7 @@ __bam_c_physdel(dbp, cp, h) * empty the current page of duplicates, we don't need to * touch the parent page. */ - if (PREV_PGNO(h) != PGNO_INVALID || - (h != NULL && pgno == h->pgno)) + if (prev_pgno != PGNO_INVALID || (h != NULL && pgno == h->pgno)) goto done; /* diff --git a/db2/btree/bt_put.c b/db2/btree/bt_put.c index 0f0b1e7126..af09f76d41 100644 --- a/db2/btree/bt_put.c +++ b/db2/btree/bt_put.c @@ -47,7 +47,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)bt_put.c 10.24 (Sleepycat) 9/3/97"; +static const char sccsid[] = "@(#)bt_put.c 10.25 (Sleepycat) 9/17/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -99,7 +99,7 @@ __bam_put(argdbp, txn, key, data, flags) t = dbp->internal; retry: /* - * Find the location at which to insert. The call to bt_lookup() + * Find the location at which to insert. The call to __bam_lookup * leaves the returned page pinned. */ if ((ret = __bam_lookup(dbp, key, &exact)) != 0) { diff --git a/db2/btree/bt_rec.c b/db2/btree/bt_rec.c index 07a3d93c74..9aeb395f27 100644 --- a/db2/btree/bt_rec.c +++ b/db2/btree/bt_rec.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)bt_rec.c 10.13 (Sleepycat) 9/3/97"; +static const char sccsid[] = "@(#)bt_rec.c 10.14 (Sleepycat) 9/6/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -298,11 +298,10 @@ __bam_split_recover(logp, dbtp, lsnp, redo, info) goto done; /* Allocate and initialize new left/right child pages. */ - if ((_lp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) - goto nomem; - if ((_rp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) { -nomem: __set_errno(ENOMEM); - __db_err(file_dbp->dbenv, "%s", strerror(errno)); + if ((_lp = (PAGE *)malloc(file_dbp->pgsize)) == NULL || + (_rp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) { + ret = ENOMEM; + __db_err(file_dbp->dbenv, "%s", strerror(ret)); goto out; } if (rootsplit) { @@ -668,7 +667,7 @@ __bam_cadjust_recover(logp, dbtp, lsnp, redo, info) REC_INTRO(__bam_cadjust_read); if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - __set_errno(__db_pgerr(file_dbp, argp->pgno)); + (void)__db_pgerr(file_dbp, argp->pgno); pagep = NULL; goto out; } diff --git a/db2/btree/bt_recno.c b/db2/btree/bt_recno.c index 42ef9cc30d..f7c5cffdc6 100644 --- a/db2/btree/bt_recno.c +++ b/db2/btree/bt_recno.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)bt_recno.c 10.15 (Sleepycat) 9/3/97"; +static const char sccsid[] = "@(#)bt_recno.c 10.19 (Sleepycat) 9/20/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -76,7 +76,7 @@ __ram_open(dbp, type, dbinfo) /* Allocate and initialize the private RECNO structure. */ if ((rp = (RECNO *)calloc(1, sizeof(*rp))) == NULL) - return (errno); + return (ENOMEM); if (dbinfo != NULL) { /* @@ -150,7 +150,7 @@ err: /* If we mmap'd a source file, discard it. */ /* If we allocated room for key/data return, discard it. */ t = dbp->internal; - if (t->bt_rkey.data != NULL) + if (t != NULL && t->bt_rkey.data != NULL) free(t->bt_rkey.data); FREE(rp, sizeof(*rp)); @@ -193,7 +193,10 @@ __ram_cursor(dbp, txn, dbcp) dbc->c_get = __ram_c_get; dbc->c_put = __ram_c_put; - /* All cursor structures hang off the main DB structure. */ + /* + * All cursors are queued from the master DB structure. Add the + * cursor to that queue. + */ DB_THREAD_LOCK(dbp); TAILQ_INSERT_HEAD(&dbp->curs_queue, dbc, links); DB_THREAD_UNLOCK(dbp); @@ -382,16 +385,29 @@ static int __ram_c_close(dbc) DBC *dbc; { - DB *dbp; - DEBUG_LWRITE(dbc->dbp, dbc->txn, "ram_c_close", NULL, NULL, 0); - dbp = dbc->dbp; + return (__ram_c_iclose(dbc->dbp, dbc)); +} - /* Remove the cursor from the queue. */ - DB_THREAD_LOCK(dbp); - TAILQ_REMOVE(&dbp->curs_queue, dbc, links); - DB_THREAD_UNLOCK(dbp); +/* + * __ram_c_iclose -- + * Close a single cursor -- internal version. + * + * PUBLIC: int __ram_c_iclose __P((DB *, DBC *)); + */ +int +__ram_c_iclose(dbp, dbc) + DB *dbp; + DBC *dbc; +{ + /* + * All cursors are queued from the master DB structure. Remove the + * cursor from that queue. + */ + DB_THREAD_LOCK(dbc->dbp); + TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links); + DB_THREAD_UNLOCK(dbc->dbp); /* Discard the structures. */ FREE(dbc->internal, sizeof(RCURSOR)); diff --git a/db2/btree/btree.src b/db2/btree/btree.src index 50cc0dd0ff..7c8c4b125f 100644 --- a/db2/btree/btree.src +++ b/db2/btree/btree.src @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)btree.src 10.3 (Sleepycat) 8/17/97"; +static const char sccsid[] = "@(#)btree.src 10.4 (Sleepycat) 8/27/97"; #endif /* not lint */ PREFIX bam @@ -88,7 +88,7 @@ END /* * BTREE-adj: used to log the adjustment of an index. - * + * * pgno: the page modified. * lsn: the page's original lsn. * indx: the index adjusted. @@ -106,7 +106,7 @@ END /* * BTREE-cadjust: used to adjust the count change in an internal page. - * + * * pgno: the page modified. * lsn: the page's original lsn. * indx: the index to be adjusted. @@ -124,7 +124,7 @@ END /* * BTREE-cdel: used to log the intent-to-delete of a cursor record. - * + * * pgno: the page modified. * lsn: the page's original lsn. * indx: the index to be deleted. diff --git a/db2/btree/btree_auto.c b/db2/btree/btree_auto.c index e6b72252e5..353ee7bc27 100644 --- a/db2/btree/btree_auto.c +++ b/db2/btree/btree_auto.c @@ -119,7 +119,7 @@ __bam_pg_alloc_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __bam_pg_alloc_read(dbtp->data, &argp)) != 0) + if ((ret = __bam_pg_alloc_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]bam_pg_alloc: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -284,7 +284,7 @@ __bam_pg_free_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __bam_pg_free_read(dbtp->data, &argp)) != 0) + if ((ret = __bam_pg_free_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]bam_pg_free: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -479,7 +479,7 @@ __bam_split_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __bam_split_read(dbtp->data, &argp)) != 0) + if ((ret = __bam_split_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]bam_split: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -672,7 +672,7 @@ __bam_rsplit_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __bam_rsplit_read(dbtp->data, &argp)) != 0) + if ((ret = __bam_rsplit_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]bam_rsplit: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -848,7 +848,7 @@ __bam_adj_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __bam_adj_read(dbtp->data, &argp)) != 0) + if ((ret = __bam_adj_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]bam_adj: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -1007,7 +1007,7 @@ __bam_cadjust_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __bam_cadjust_read(dbtp->data, &argp)) != 0) + if ((ret = __bam_cadjust_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]bam_cadjust: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -1157,7 +1157,7 @@ __bam_cdel_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __bam_cdel_read(dbtp->data, &argp)) != 0) + if ((ret = __bam_cdel_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]bam_cdel: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, diff --git a/db2/clib/getlong.c b/db2/clib/getlong.c index 0cc8567081..85f4e8c9e2 100644 --- a/db2/clib/getlong.c +++ b/db2/clib/getlong.c @@ -18,7 +18,6 @@ static const char sccsid[] = "@(#)getlong.c 10.2 (Sleepycat) 5/1/97"; #endif #include "db.h" -#include "db_int.h" #include "clib_ext.h" /* diff --git a/db2/db.h b/db2/db.h index c80d8e3633..6911002ed5 100644 --- a/db2/db.h +++ b/db2/db.h @@ -4,7 +4,7 @@ * Copyright (c) 1996, 1997 * Sleepycat Software. All rights reserved. * - * @(#)db.h.src 10.71 (Sleepycat) 9/4/97 + * @(#)db.h.src 10.77 (Sleepycat) 9/24/97 */ #ifndef _DB_H_ @@ -67,8 +67,8 @@ #define DB_VERSION_MAJOR 2 #define DB_VERSION_MINOR 3 -#define DB_VERSION_PATCH 6 -#define DB_VERSION_STRING "Sleepycat Software: DB 2.3.6: (9/4/97)" +#define DB_VERSION_PATCH 10 +#define DB_VERSION_STRING "Sleepycat Software: DB 2.3.10: (9/24/97)" typedef u_int32_t db_pgno_t; /* Page number type. */ typedef u_int16_t db_indx_t; /* Page offset type. */ @@ -339,7 +339,7 @@ struct __db_ilock { /* Internal DB access method lock. */ /* DB access method description structure. */ struct __db { - void *mutex; /* Synchronization for free threading */ + void *mutexp; /* Synchronization for free threading */ DBTYPE type; /* DB access method. */ DB_ENV *dbenv; /* DB_ENV structure. */ DB_ENV *mp_dbenv; /* DB_ENV for local mpool creation. */ @@ -641,11 +641,11 @@ extern "C" { #endif int memp_close __P((DB_MPOOL *)); int memp_fclose __P((DB_MPOOLFILE *)); -int memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, unsigned long, void *)); +int memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, int, void *)); int memp_fopen __P((DB_MPOOL *, const char *, int, int, int, size_t, int, DBT *, u_int8_t *, DB_MPOOLFILE **)); -int memp_fput __P((DB_MPOOLFILE *, void *, unsigned long)); -int memp_fset __P((DB_MPOOLFILE *, void *, unsigned long)); +int memp_fput __P((DB_MPOOLFILE *, void *, int)); +int memp_fset __P((DB_MPOOLFILE *, void *, int)); int memp_fsync __P((DB_MPOOLFILE *)); int memp_open __P((const char *, int, int, DB_ENV *, DB_MPOOL **)); int memp_register __P((DB_MPOOL *, int, @@ -698,7 +698,7 @@ extern "C" { #endif int txn_abort __P((DB_TXN *)); int txn_begin __P((DB_TXNMGR *, DB_TXN *, DB_TXN **)); -int txn_checkpoint __P((const DB_TXNMGR *, long, long)); +int txn_checkpoint __P((const DB_TXNMGR *, int, int)); int txn_commit __P((DB_TXN *)); int txn_close __P((DB_TXNMGR *)); u_int32_t txn_id __P((DB_TXN *)); diff --git a/db2/db/db.c b/db2/db/db.c index 8dad5febe8..9ebe73cf6e 100644 --- a/db2/db/db.c +++ b/db2/db/db.c @@ -44,7 +44,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)db.c 10.38 (Sleepycat) 9/2/97"; +static const char sccsid[] = "@(#)db.c 10.41 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -137,7 +137,13 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp) } dbp->dbenv = dbenv; - /* Convert the dbinfo flags. */ + /* Convert the db_open(3) flags. */ + if (LF_ISSET(DB_RDONLY)) + F_SET(dbp, DB_AM_RDONLY); + if (LF_ISSET(DB_THREAD)) + F_SET(dbp, DB_AM_THREAD); + + /* Convert the dbinfo structure flags. */ if (dbinfo != NULL) { /* * !!! @@ -160,23 +166,6 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp) F_SET(dbp, DB_RE_SNAPSHOT); } - /* Set based on the open(2) flags. */ - if (LF_ISSET(DB_RDONLY)) - F_SET(dbp, DB_AM_RDONLY); - - /* Check threading fields. */ - if (LF_ISSET(DB_THREAD)) { - if ((dbp->mutex = - (db_mutex_t *)malloc(sizeof(db_mutex_t))) == NULL) { - __db_err(dbenv, "%s", strerror(ENOMEM)); - ret = ENOMEM; - goto err; - } - __db_mutex_init(dbp->mutex, 0); - - F_SET(dbp, DB_AM_THREAD); - } - /* * Always set the master and initialize the queues, so we can * use these fields without checking the thread bit. @@ -190,7 +179,7 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp) * Set based on the dbenv fields, although no logging or transactions * are possible for temporary files. */ - if (dbp->dbenv != NULL) { + if (dbenv != NULL) { if (dbenv->lk_info != NULL) F_SET(dbp, DB_AM_LOCKING); if (fname != NULL && dbenv->lg_info != NULL) @@ -274,8 +263,8 @@ open_retry: if (LF_ISSET(DB_CREATE)) { * sizes, we limit the default pagesize to 16K. */ if (dbp->pgsize == 0) { - if ((ret = __db_stat(dbp->dbenv, - real_name, fd, NULL, &io)) != 0) + if ((ret = + __db_stat(dbenv, real_name, fd, NULL, &io)) != 0) goto err; if (io < 512) io = 512; @@ -573,6 +562,15 @@ empty: /* 0, &pgcookie, dbp->lock.fileid, &dbp->mpf)) != 0) goto err; + /* + * XXX + * Truly spectacular layering violation. We need a per-thread mutex + * that lives in shared memory (thanks, HP-UX!) and so we acquire a + * pointer to the mpool one. + */ + if (F_ISSET(dbp, DB_AM_THREAD)) + dbp->mutexp = dbp->mpf->mutexp; + /* Get a log file id. */ if (F_ISSET(dbp, DB_AM_LOGGING) && (ret = log_register(dbenv->lg_info, @@ -672,7 +670,9 @@ db_close(dbp, flags) DB *tdbp; int ret, t_ret; - ret = 0; + /* Validate arguments. */ + if ((ret = __db_fchk(dbp->dbenv, "db_close", flags, DB_NOSYNC)) != 0) + return (ret); /* Sync the underlying file. */ if (!LF_ISSET(DB_NOSYNC) && @@ -685,10 +685,26 @@ db_close(dbp, flags) */ for (tdbp = LIST_FIRST(&dbp->handleq); tdbp != NULL; tdbp = LIST_NEXT(tdbp, links)) { - while ((dbc = TAILQ_FIRST(&tdbp->curs_queue)) != NULL) - if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0) - ret = t_ret; + switch (tdbp->type) { + case DB_BTREE: + if ((t_ret = + __bam_c_iclose(tdbp, dbc)) != 0 && ret == 0) + ret = t_ret; + break; + case DB_HASH: + if ((t_ret = + __ham_c_iclose(tdbp, dbc)) != 0 && ret == 0) + ret = t_ret; + break; + case DB_RECNO: + if ((t_ret = + __ram_c_iclose(tdbp, dbc)) != 0 && ret == 0) + ret = t_ret; + break; + default: + abort(); + } switch (tdbp->type) { case DB_BTREE: @@ -706,7 +722,6 @@ db_close(dbp, flags) default: abort(); } - } /* Sync the memory pool. */ @@ -722,10 +737,6 @@ db_close(dbp, flags) (t_ret = memp_close(dbp->mp)) != 0 && ret == 0) ret = t_ret; - /* Discard the mutex. */ - if (dbp->mutex != NULL) - FREE(dbp->mutex, sizeof(db_mutex_t)); - /* Discard the log file id. */ if (F_ISSET(dbp, DB_AM_LOGGING)) (void)log_unregister(dbp->dbenv->lg_info, dbp->log_fileid); diff --git a/db2/db/db_auto.c b/db2/db/db_auto.c index 4684f1a39f..6922504383 100644 --- a/db2/db/db_auto.c +++ b/db2/db/db_auto.c @@ -141,7 +141,7 @@ __db_addrem_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __db_addrem_read(dbtp->data, &argp)) != 0) + if ((ret = __db_addrem_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]db_addrem: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -331,7 +331,7 @@ __db_split_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __db_split_read(dbtp->data, &argp)) != 0) + if ((ret = __db_split_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]db_split: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -526,7 +526,7 @@ __db_big_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __db_big_read(dbtp->data, &argp)) != 0) + if ((ret = __db_big_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]db_big: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -693,7 +693,7 @@ __db_ovref_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __db_ovref_read(dbtp->data, &argp)) != 0) + if ((ret = __db_ovref_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]db_ovref: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -854,7 +854,7 @@ __db_relink_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __db_relink_read(dbtp->data, &argp)) != 0) + if ((ret = __db_relink_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]db_relink: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -1017,7 +1017,7 @@ __db_addpage_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __db_addpage_read(dbtp->data, &argp)) != 0) + if ((ret = __db_addpage_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]db_addpage: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -1192,7 +1192,7 @@ __db_debug_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __db_debug_read(dbtp->data, &argp)) != 0) + if ((ret = __db_debug_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]db_debug: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -1347,7 +1347,7 @@ __db_noop_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __db_noop_read(dbtp->data, &argp)) != 0) + if ((ret = __db_noop_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]db_noop: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, diff --git a/db2/db/db_conv.c b/db2/db/db_conv.c index 6608005b66..8eccc2e602 100644 --- a/db2/db/db_conv.c +++ b/db2/db/db_conv.c @@ -44,7 +44,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)db_conv.c 10.5 (Sleepycat) 9/3/97"; +static const char sccsid[] = "@(#)db_conv.c 10.7 (Sleepycat) 9/21/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -58,28 +58,34 @@ static const char sccsid[] = "@(#)db_conv.c 10.5 (Sleepycat) 9/3/97"; #include "db_swap.h" #include "db_am.h" -static int __db_convert __P((db_pgno_t, void *, int)); +static int __db_convert __P((db_pgno_t, void *, size_t, int)); /* - * __db_pgin, __db_pgout -- + * __db_pgin -- * - * PUBLIC: int __db_pgin __P((db_pgno_t, void *)); - * PUBLIC: int __db_pgout __P((db_pgno_t, void *)); + * PUBLIC: int __db_pgin __P((db_pgno_t, size_t, void *)); */ int -__db_pgin(pg, pp) +__db_pgin(pg, pagesize, pp) db_pgno_t pg; + size_t pagesize; void *pp; { - return (__db_convert(pg, pp, 1)); + return (__db_convert(pg, pp, pagesize, 1)); } +/* + * __db_pgout -- + * + * PUBLIC: int __db_pgout __P((db_pgno_t, size_t, void *)); + */ int -__db_pgout(pg, pp) +__db_pgout(pg, pagesize, pp) db_pgno_t pg; + size_t pagesize; void *pp; { - return (__db_convert(pg, pp, 0)); + return (__db_convert(pg, pp, pagesize, 0)); } /* @@ -87,19 +93,19 @@ __db_pgout(pg, pp) * Actually convert a page. */ static int -__db_convert(pg, pp, pgin) +__db_convert(pg, pp, pagesize, pgin) db_pgno_t pg; /* Unused, but left for the future. */ void *pp; + size_t pagesize; int pgin; { BINTERNAL *bi; BKEYDATA *bk; BOVERFLOW *bo; - HKEYDATA *hk; PAGE *h; RINTERNAL *ri; - db_indx_t i; - u_int8_t *p; + db_indx_t i, len, tmp; + u_int8_t *p, *end; h = pp; if (pgin) { @@ -118,24 +124,42 @@ __db_convert(pg, pp, pgin) if (pgin) M_16_SWAP(h->inp[i]); - hk = GET_HKEYDATA(h, i); - switch (hk->type) { + switch (HPAGE_TYPE(h, i)) { case H_KEYDATA: break; case H_DUPLICATE: + len = LEN_HKEYDATA(h, pagesize, i); + p = HKEYDATA_DATA(P_ENTRY(h, i)); + for (end = p + len; p < end;) { + if (pgin) { + P_16_SWAP(p); + memcpy(&tmp, + p, sizeof(db_indx_t)); + p += sizeof(db_indx_t); + } else { + memcpy(&tmp, + p, sizeof(db_indx_t)); + SWAP16(p); + } + p += tmp; + SWAP16(p); + } + break; + case H_OFFDUP: + p = HOFFPAGE_PGNO(P_ENTRY(h, i)); + SWAP32(p); /* pgno */ + break; case H_OFFPAGE: - p = (u_int8_t *)hk + sizeof(u_int8_t); - ++p; - SWAP32(p); /* tlen */ + p = HOFFPAGE_PGNO(P_ENTRY(h, i)); SWAP32(p); /* pgno */ - SWAP16(p); /* offset */ - SWAP16(p); /* len */ + SWAP32(p); /* tlen */ break; } - if (!pgin) - M_16_SWAP(h->inp[i]); } + if (!pgin) + for (i = 0; i < NUM_ENT(h); i++) + M_16_SWAP(h->inp[i]); break; case P_LBTREE: case P_LRECNO: diff --git a/db2/db/db_pr.c b/db2/db/db_pr.c index f86fd6770a..09d8057da4 100644 --- a/db2/db/db_pr.c +++ b/db2/db/db_pr.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)db_pr.c 10.16 (Sleepycat) 9/3/97"; +static const char sccsid[] = "@(#)db_pr.c 10.17 (Sleepycat) 9/15/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -184,7 +184,7 @@ __db_prbtree(dbp) BTMETA *mp; BTREE *t; DB_LOCK lock; - EPG *sp; + EPG *epg; FILE *fp; RECNO *rp; db_pgno_t i; @@ -230,8 +230,8 @@ __db_prbtree(dbp) (u_long)rp->re_emap, (u_long)rp->re_msize); } (void)fprintf(fp, "stack:"); - for (sp = t->bt_stack; sp < t->bt_sp; ++sp) - (void)fprintf(fp, " %lu", (u_long)sp->page->pgno); + for (epg = t->bt_stack; epg < t->bt_sp; ++epg) + (void)fprintf(fp, " %lu", (u_long)epg->page->pgno); (void)fprintf(fp, "\n"); (void)fprintf(fp, "ovflsize: %lu\n", (u_long)t->bt_ovflsize); (void)fflush(fp); @@ -367,20 +367,15 @@ __db_prpage(h, all) { BINTERNAL *bi; BKEYDATA *bk; - HKEYDATA *hkd; HOFFPAGE a_hkd; FILE *fp; RINTERNAL *ri; db_indx_t dlen, len, i; db_pgno_t pgno; - u_int8_t *p; int deleted, ret; const char *s; - - bi = NULL; /* XXX: Shut the compiler up. */ - bk = NULL; - hkd = NULL; - ri = NULL; + u_int8_t *ep, *hk, *p; + void *sp; fp = __db_prinit(NULL); @@ -450,22 +445,18 @@ __db_prpage(h, all) deleted = 0; switch (TYPE(h)) { case P_HASH: - hkd = GET_HKEYDATA(h, i); - break; case P_IBTREE: - bi = GET_BINTERNAL(h, i); - break; case P_IRECNO: - ri = GET_RINTERNAL(h, i); + sp = P_ENTRY(h, i); break; case P_LBTREE: - bk = GET_BKEYDATA(h, i); + sp = P_ENTRY(h, i); deleted = i % 2 == 0 && B_DISSET(GET_BKEYDATA(h, i + O_INDX)->type); break; case P_LRECNO: case P_DUPLICATE: - bk = GET_BKEYDATA(h, i); + sp = P_ENTRY(h, i); deleted = B_DISSET(GET_BKEYDATA(h, i)->type); break; default: @@ -478,11 +469,11 @@ __db_prpage(h, all) deleted ? "D" : " ", (u_long)i, (u_long)h->inp[i]); switch (TYPE(h)) { case P_HASH: - switch (hkd->type) { + hk = sp; + switch (HPAGE_PTYPE(hk)) { case H_OFFDUP: memcpy(&pgno, - (u_int8_t *)hkd + SSZ(HOFFDUP, pgno), - sizeof(db_pgno_t)); + HOFFDUP_PGNO(hk), sizeof(db_pgno_t)); fprintf(fp, "%4lu [offpage dups]\n", (u_long)pgno); break; @@ -499,7 +490,8 @@ __db_prpage(h, all) len = 1; fprintf(fp, "Duplicates:\n"); - for (p = hkd->data; p < hkd->data + len;) { + for (p = HKEYDATA_DATA(hk), + ep = p + len; p < ep;) { memcpy(&dlen, p, sizeof(db_indx_t)); p += sizeof(db_indx_t); fprintf(fp, "\t\t"); @@ -509,13 +501,13 @@ __db_prpage(h, all) break; case H_KEYDATA: if (i != 0) - __db_pr(hkd->data, + __db_pr(HKEYDATA_DATA(hk), LEN_HKEYDATA(h, 0, i)); else - fprintf(fp, "%s\n", hkd->data); + fprintf(fp, "%s\n", HKEYDATA_DATA(hk)); break; case H_OFFPAGE: - memcpy(&a_hkd, hkd, HOFFPAGE_SIZE); + memcpy(&a_hkd, hk, HOFFPAGE_SIZE); fprintf(fp, "overflow: total len: %4lu page: %4lu\n", (u_long)a_hkd.tlen, (u_long)a_hkd.pgno); @@ -523,6 +515,7 @@ __db_prpage(h, all) } break; case P_IBTREE: + bi = sp; fprintf(fp, "count: %4lu pgno: %4lu ", (u_long)bi->nrecs, (u_long)bi->pgno); switch (B_TYPE(bi->type)) { @@ -541,12 +534,14 @@ __db_prpage(h, all) } break; case P_IRECNO: + ri = sp; fprintf(fp, "entries %4lu pgno %4lu\n", (u_long)ri->nrecs, (u_long)ri->pgno); break; case P_LBTREE: case P_LRECNO: case P_DUPLICATE: + bk = sp; switch (B_TYPE(bk->type)) { case B_KEYDATA: __db_pr(bk->data, bk->len); @@ -582,13 +577,9 @@ __db_isbad(h, die) { BINTERNAL *bi; BKEYDATA *bk; - HKEYDATA *hkd; FILE *fp; db_indx_t i; - - bi = NULL; /* XXX: Shut the compiler up. */ - bk = NULL; - hkd = NULL; + int type; fp = __db_prinit(NULL); @@ -618,13 +609,13 @@ __db_isbad(h, die) } switch (TYPE(h)) { case P_HASH: - hkd = GET_HKEYDATA(h, i); - if (hkd->type != H_OFFDUP && - hkd->type != H_DUPLICATE && - hkd->type != H_KEYDATA && - hkd->type != H_OFFPAGE) { + type = HPAGE_TYPE(h, i); + if (type != H_OFFDUP && + type != H_DUPLICATE && + type != H_KEYDATA && + type != H_OFFPAGE) { fprintf(fp, "ILLEGAL HASH TYPE: %lu\n", - (u_long)hkd->type); + (u_long)type); goto bad; } break; diff --git a/db2/db/db_ret.c b/db2/db/db_ret.c index baf0665446..ee2bc82f87 100644 --- a/db2/db/db_ret.c +++ b/db2/db/db_ret.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)db_ret.c 10.6 (Sleepycat) 9/3/97"; +static const char sccsid[] = "@(#)db_ret.c 10.7 (Sleepycat) 9/15/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -46,18 +46,19 @@ __db_ret(dbp, h, indx, dbt, memp, memsize) HOFFPAGE ho; BOVERFLOW *bo; u_int32_t len; - void *data, *hk; + u_int8_t *hk; + void *data; switch (TYPE(h)) { case P_HASH: hk = P_ENTRY(h, indx); - if (((HKEYDATA *)hk)->type == H_OFFPAGE) { + if (HPAGE_PTYPE(hk) == H_OFFPAGE) { memcpy(&ho, hk, sizeof(HOFFPAGE)); return (__db_goff(dbp, dbt, ho.tlen, ho.pgno, memp, memsize)); } len = LEN_HKEYDATA(h, dbp->pgsize, indx); - data = ((HKEYDATA *)hk)->data; + data = HKEYDATA_DATA(hk); break; case P_DUPLICATE: case P_LBTREE: diff --git a/db2/db/db_thread.c b/db2/db/db_thread.c index e956e809d9..170baf5345 100644 --- a/db2/db/db_thread.c +++ b/db2/db/db_thread.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)db_thread.c 8.11 (Sleepycat) 8/18/97"; +static const char sccsid[] = "@(#)db_thread.c 8.12 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -42,7 +42,7 @@ __db_gethandle(dbp, am_func, dbpp) DB *ret_dbp; int ret, t_ret; - if ((ret = __db_mutex_lock((db_mutex_t *)dbp->mutex, -1, + if ((ret = __db_mutex_lock((db_mutex_t *)dbp->mutexp, -1, dbp->dbenv == NULL ? NULL : dbp->dbenv->db_yield)) != 0) return (ret); @@ -75,7 +75,7 @@ err: if (ret_dbp != NULL) FREE(ret_dbp, sizeof(*ret_dbp)); } if ((t_ret = - __db_mutex_unlock((db_mutex_t *)dbp->mutex, -1)) != 0 && ret == 0) + __db_mutex_unlock((db_mutex_t *)dbp->mutexp, -1)) != 0 && ret == 0) ret = t_ret; return (ret); } @@ -94,13 +94,13 @@ __db_puthandle(dbp) int ret; master = dbp->master; - if ((ret = __db_mutex_lock((db_mutex_t *)master->mutex, -1, + if ((ret = __db_mutex_lock((db_mutex_t *)master->mutexp, -1, dbp->dbenv == NULL ? NULL : dbp->dbenv->db_yield)) != 0) return (ret); LIST_INSERT_HEAD(&master->handleq, dbp, links); - return (__db_mutex_unlock((db_mutex_t *)master->mutex, -1)); + return (__db_mutex_unlock((db_mutex_t *)master->mutexp, -1)); } /* diff --git a/db2/db_185.h b/db2/db_185.h index 650d365a60..b6a4d0a12a 100644 --- a/db2/db_185.h +++ b/db2/db_185.h @@ -36,7 +36,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)db_185.h.src 8.3 (Sleepycat) 7/27/97 + * @(#)db_185.h.src 8.4 (Sleepycat) 9/16/97 */ #ifndef _DB_185_H_ @@ -72,6 +72,14 @@ #endif +/* + * XXX + * SGI/IRIX already has a pgno_t. + */ +#ifdef sgi +#define pgno_t db_pgno_t +#endif + #define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */ typedef u_int32_t pgno_t; #define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */ diff --git a/db2/db_int.h b/db2/db_int.h index a088c693a8..56dfddb73f 100644 --- a/db2/db_int.h +++ b/db2/db_int.h @@ -4,7 +4,7 @@ * Copyright (c) 1996, 1997 * Sleepycat Software. All rights reserved. * - * @(#)db_int.h.src 10.28 (Sleepycat) 8/20/97 + * @(#)db_int.h.src 10.30 (Sleepycat) 9/23/97 */ #ifndef _DB_INTERNAL_H_ @@ -25,12 +25,6 @@ #define DB_MINCACHE 10 /* Minimum cached pages */ -/* Handle `errno' in the presence of multi-threading correctly. On some - systems we need a special macro to do this right. */ -#ifndef __set_errno -# define __set_errno(val) (errno) = (val) -#endif - /* * Aligning items to particular sizes or in pages or memory. ALIGNP is a * separate macro, as we've had to cast the pointer to different integral @@ -94,7 +88,7 @@ /* Structure used to print flag values. */ typedef struct __fn { - u_int32_t mask; /* Flag value. */ + u_int32_t mask; /* Flag value. */ const char *name; /* Flag name. */ } FN; @@ -183,11 +177,11 @@ typedef struct _db_mutex_t { /* Lock/unlock a DB thread. */ #define DB_THREAD_LOCK(dbp) \ (F_ISSET(dbp, DB_AM_THREAD) ? \ - __db_mutex_lock((db_mutex_t *)(dbp)->mutex, -1, \ + __db_mutex_lock((db_mutex_t *)(dbp)->mutexp, -1, \ (dbp)->dbenv == NULL ? NULL : (dbp)->dbenv->db_yield) : 0) #define DB_THREAD_UNLOCK(dbp) \ (F_ISSET(dbp, DB_AM_THREAD) ? \ - __db_mutex_unlock((db_mutex_t *)(dbp)->mutex, -1) : 0) + __db_mutex_unlock((db_mutex_t *)(dbp)->mutexp, -1) : 0) /* Btree/recno local statistics structure. */ struct __db_bt_lstat; typedef struct __db_bt_lstat DB_BTREE_LSTAT; @@ -312,14 +306,6 @@ typedef struct __dbpginfo { * Transactions and recovery. *******************************************************/ /* - * The locker id space is divided between the transaction manager and the lock - * manager. Lockid's start at 0 and go to MAX_LOCKER_ID. Txn Id's start at - * MAX_LOCKER_ID + 1 and go up to MAX_TXNID. - */ -#define MAX_LOCKER_ID 0x0fffffff -#define MAX_TXNID 0xffffffff - -/* * Out of band value for a lock. The locks are returned to callers as offsets * into the lock regions. Since the RLAYOUT structure begins all regions, an * offset of 0 is guaranteed not to be a valid lock. diff --git a/db2/hash/hash.c b/db2/hash/hash.c index 6d8c40057d..d986e08087 100644 --- a/db2/hash/hash.c +++ b/db2/hash/hash.c @@ -47,7 +47,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)hash.c 10.25 (Sleepycat) 8/24/97"; +static const char sccsid[] = "@(#)hash.c 10.27 (Sleepycat) 9/15/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -573,8 +573,6 @@ __ham_c_close(cursor) DBC *cursor; { DB *ldbp; - HTAB *hashp; - HASH_CURSOR *hcp; int ret; DEBUG_LWRITE(cursor->dbp, cursor->txn, "ham_c_close", NULL, NULL, 0); @@ -590,8 +588,32 @@ __ham_c_close(cursor) if (F_ISSET(cursor->dbp, DB_AM_THREAD) && (ret = __db_gethandle(cursor->dbp, __ham_hdup, &ldbp)) != 0) return (ret); - hashp = (HTAB *)ldbp->internal; - hcp = (HASH_CURSOR *)cursor->internal; + + ret = __ham_c_iclose(ldbp, cursor); + + if (F_ISSET(ldbp, DB_AM_THREAD)) + __db_puthandle(ldbp); + return (ret); +} +/* + * __ham_c_iclose -- + * + * Internal cursor close routine; assumes it is being passed the correct + * handle, rather than getting and putting a handle. + * + * PUBLIC: int __ham_c_iclose __P((DB *, DBC *)); + */ +int +__ham_c_iclose(dbp, dbc) + DB *dbp; + DBC *dbc; +{ + HASH_CURSOR *hcp; + HTAB *hashp; + int ret; + + hashp = (HTAB *)dbp->internal; + hcp = (HASH_CURSOR *)dbc->internal; ret = __ham_item_done(hashp, hcp, 0); if (hcp->big_key) @@ -602,19 +624,16 @@ __ham_c_close(cursor) /* * All cursors (except the default ones) are linked off the master. * Therefore, when we close the cursor, we have to remove it from - * the master, not the local one. When we are closing the file in - * its entirety, then we clear the THREAD bit and the master and - * local are identical, so we remove the correct one. + * the master, not the local one. + * XXX I am always removing from the master; what about local cursors? */ - DB_THREAD_LOCK(cursor->dbp); - TAILQ_REMOVE(&cursor->dbp->curs_queue, cursor, links); - DB_THREAD_UNLOCK(cursor->dbp); - - if (F_ISSET(cursor->dbp, DB_AM_THREAD)) - __db_puthandle(ldbp); + DB_THREAD_LOCK(dbc->dbp); + TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links); + DB_THREAD_UNLOCK(dbc->dbp); FREE(hcp, sizeof(HASH_CURSOR)); - FREE(cursor, sizeof(DBC)); + FREE(dbc, sizeof(DBC)); + return (ret); } @@ -695,10 +714,9 @@ __ham_c_del(cursor, flags) hcp->dndx = 0; /* Case 2 */ hcp->dpgno = PGNO(hcp->dpagep); if (ppgno == PGNO_INVALID) - memcpy(P_ENTRY(hcp->pagep, - H_DATAINDEX(hcp->bndx)) + - SSZ(HOFFDUP, pgno), &hcp->dpgno, - sizeof(db_pgno_t)); + memcpy(HOFFDUP_PGNO(P_ENTRY(hcp->pagep, + H_DATAINDEX(hcp->bndx))), + &hcp->dpgno, sizeof(db_pgno_t)); F_SET(hcp, H_DELETED); } else /* Case 1 */ F_SET(hcp, H_DELETED); @@ -1051,18 +1069,17 @@ __ham_dup_return(hashp, hcp, val, flags) DBT *val; int flags; { - HKEYDATA *hk; PAGE *pp; DBT *myval, tmp_val; db_indx_t ndx; db_pgno_t pgno; - u_int8_t type; + u_int8_t *hk, type; int indx, ret; db_indx_t len; /* Check for duplicate and return the first one. */ ndx = H_DATAINDEX(hcp->bndx); - type = GET_HKEYDATA(hcp->pagep, ndx)->type; + type = HPAGE_TYPE(hcp->pagep, ndx); pp = hcp->pagep; myval = val; @@ -1088,7 +1105,8 @@ __ham_dup_return(hashp, hcp, val, flags) hcp->dndx = 0; hcp->dup_off = 0; do { - memcpy(&len, hk->data + hcp->dup_off, + memcpy(&len, + HKEYDATA_DATA(hk) + hcp->dup_off, sizeof(db_indx_t)); hcp->dup_off += DUP_SIZE(len); hcp->dndx++; @@ -1096,15 +1114,15 @@ __ham_dup_return(hashp, hcp, val, flags) hcp->dup_off -= DUP_SIZE(len); hcp->dndx--; } else { - memcpy(&len, hk->data, sizeof(db_indx_t)); + memcpy(&len, + HKEYDATA_DATA(hk), sizeof(db_indx_t)); hcp->dup_off = 0; hcp->dndx = 0; } hcp->dup_len = len; } else if (type == H_OFFDUP) { F_SET(hcp, H_ISDUP); - memcpy(&pgno, - P_ENTRY(hcp->pagep, ndx) + SSZ(HOFFDUP, pgno), + memcpy(&pgno, HOFFDUP_PGNO(P_ENTRY(hcp->pagep, ndx)), sizeof(db_pgno_t)); if (flags == DB_LAST || flags == DB_PREV) { indx = (int)hcp->dndx; @@ -1166,7 +1184,7 @@ __ham_overwrite(hashp, hcp, nval) DBT *nval; { DBT *myval, tmp_val; - HKEYDATA *hk; + u_int8_t *hk; if (F_ISSET(hashp->dbp, DB_AM_DUP)) return (__ham_add_dup(hashp, hcp, nval, DB_KEYLAST)); @@ -1176,10 +1194,9 @@ __ham_overwrite(hashp, hcp, nval) F_SET(&tmp_val, DB_DBT_PARTIAL); tmp_val.doff = 0; hk = H_PAIRDATA(hcp->pagep, hcp->bndx); - if (hk->type == H_OFFPAGE) + if (HPAGE_PTYPE(hk) == H_OFFPAGE) memcpy(&tmp_val.dlen, - (u_int8_t *)hk + SSZ(HOFFPAGE, tlen), - sizeof(u_int32_t)); + HOFFPAGE_TLEN(hk), sizeof(u_int32_t)); else tmp_val.dlen = LEN_HDATA(hcp->pagep, hashp->hdr->pagesize,hcp->bndx); @@ -1207,10 +1224,10 @@ __ham_lookup(hashp, hcp, key, sought, mode) u_int32_t sought; db_lockmode_t mode; { - HKEYDATA *hk; db_pgno_t pgno; u_int32_t tlen; int match, ret, t_ret; + u_int8_t *hk; /* * Set up cursor so that we're looking for space to add an item @@ -1229,14 +1246,12 @@ __ham_lookup(hashp, hcp, key, sought, mode) break; hk = H_PAIRKEY(hcp->pagep, hcp->bndx); - switch (hk->type) { + switch (HPAGE_PTYPE(hk)) { case H_OFFPAGE: - memcpy(&tlen, (u_int8_t *)hk + SSZ(HOFFPAGE, tlen), - sizeof(u_int32_t)); + memcpy(&tlen, HOFFPAGE_TLEN(hk), sizeof(u_int32_t)); if (tlen == key->size) { memcpy(&pgno, - (u_int8_t *)hk + SSZ(HOFFPAGE, pgno), - sizeof(db_pgno_t)); + HOFFPAGE_PGNO(hk), sizeof(db_pgno_t)); match = __db_moff(hashp->dbp, key, pgno); if (match == 0) { F_SET(hcp, H_OK); @@ -1247,7 +1262,8 @@ __ham_lookup(hashp, hcp, key, sought, mode) case H_KEYDATA: if (key->size == LEN_HKEY(hcp->pagep, hashp->hdr->pagesize, hcp->bndx) && - memcmp(key->data, hk->data, key->size) == 0) { + memcmp(key->data, + HKEYDATA_DATA(hk), key->size) == 0) { F_SET(hcp, H_OK); return (0); } diff --git a/db2/hash/hash_auto.c b/db2/hash/hash_auto.c index f8ab80c8ee..2279de9668 100644 --- a/db2/hash/hash_auto.c +++ b/db2/hash/hash_auto.c @@ -138,7 +138,7 @@ __ham_insdel_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __ham_insdel_read(dbtp->data, &argp)) != 0) + if ((ret = __ham_insdel_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]ham_insdel: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -335,7 +335,7 @@ __ham_newpage_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __ham_newpage_read(dbtp->data, &argp)) != 0) + if ((ret = __ham_newpage_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]ham_newpage: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -498,7 +498,7 @@ __ham_splitmeta_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __ham_splitmeta_read(dbtp->data, &argp)) != 0) + if ((ret = __ham_splitmeta_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]ham_splitmeta: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -659,7 +659,7 @@ __ham_splitdata_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __ham_splitdata_read(dbtp->data, &argp)) != 0) + if ((ret = __ham_splitdata_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]ham_splitdata: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -851,7 +851,7 @@ __ham_replace_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __ham_replace_read(dbtp->data, &argp)) != 0) + if ((ret = __ham_replace_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]ham_replace: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -1053,7 +1053,7 @@ __ham_newpgno_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __ham_newpgno_read(dbtp->data, &argp)) != 0) + if ((ret = __ham_newpgno_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]ham_newpgno: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -1218,7 +1218,7 @@ __ham_ovfl_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __ham_ovfl_read(dbtp->data, &argp)) != 0) + if ((ret = __ham_ovfl_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]ham_ovfl: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, diff --git a/db2/hash/hash_conv.c b/db2/hash/hash_conv.c index 22901af950..9cebe72390 100644 --- a/db2/hash/hash_conv.c +++ b/db2/hash/hash_conv.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)hash_conv.c 10.3 (Sleepycat) 6/21/97"; +static const char sccsid[] = "@(#)hash_conv.c 10.4 (Sleepycat) 9/15/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -20,12 +20,11 @@ static const char sccsid[] = "@(#)hash_conv.c 10.3 (Sleepycat) 6/21/97"; #include "hash.h" /* - * __h_pgin, __ham_pgout -- - * Convert host-specific page layout to/from the host-independent - * format stored on disk. + * __ham_pgin -- + * Convert host-specific page layout from the host-independent format + * stored on disk. * * PUBLIC: int __ham_pgin __P((db_pgno_t, void *, DBT *)); - * PUBLIC: int __ham_pgout __P((db_pgno_t, void *, DBT *)); */ int __ham_pgin(pg, pp, cookie) @@ -49,9 +48,17 @@ __ham_pgin(pg, pp, cookie) if (!pginfo->needswap) return (0); - return (pg == PGNO_METADATA ? __ham_mswap(pp) : __db_pgin(pg, pp)); + return (pg == PGNO_METADATA ? + __ham_mswap(pp) : __db_pgin(pg, pginfo->db_pagesize, pp)); } +/* + * __ham_pgout -- + * Convert host-specific page layout to the host-independent format + * stored on disk. + * + * PUBLIC: int __ham_pgout __P((db_pgno_t, void *, DBT *)); + */ int __ham_pgout(pg, pp, cookie) db_pgno_t pg; @@ -63,7 +70,8 @@ __ham_pgout(pg, pp, cookie) pginfo = (DB_PGINFO *)cookie->data; if (!pginfo->needswap) return (0); - return (pg == PGNO_METADATA ? __ham_mswap(pp) : __db_pgout(pg, pp)); + return (pg == PGNO_METADATA ? + __ham_mswap(pp) : __db_pgout(pg, pginfo->db_pagesize, pp)); } /* diff --git a/db2/hash/hash_dup.c b/db2/hash/hash_dup.c index c9590fa49d..71bd1c5eb0 100644 --- a/db2/hash/hash_dup.c +++ b/db2/hash/hash_dup.c @@ -42,7 +42,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)hash_dup.c 10.6 (Sleepycat) 9/3/97"; +static const char sccsid[] = "@(#)hash_dup.c 10.7 (Sleepycat) 9/15/97"; #endif /* not lint */ /* @@ -99,9 +99,9 @@ __ham_add_dup(hashp, hcp, nval, flags) int flags; { DBT pval, tmp_val; - HKEYDATA *hk; u_int32_t del_len, new_size; int ret; + u_int8_t *hk; if (flags == DB_CURRENT && hcp->dpgno == PGNO_INVALID) del_len = hcp->dup_len; @@ -128,8 +128,8 @@ __ham_add_dup(hashp, hcp, nval, flags) * the addition of the new item will make the set large, or * if there isn't enough room on this page to add the next item. */ - if (hk->type != H_OFFDUP && - (hk->type == H_OFFPAGE || ISBIG(hashp, new_size) || + if (HPAGE_PTYPE(hk) != H_OFFDUP && + (HPAGE_PTYPE(hk) == H_OFFPAGE || ISBIG(hashp, new_size) || DUP_SIZE(nval->size) - del_len > P_FREESPACE(hcp->pagep))) { if ((ret = __ham_dup_convert(hashp, hcp)) != 0) @@ -139,16 +139,17 @@ __ham_add_dup(hashp, hcp, nval, flags) } /* There are two separate cases here: on page and off page. */ - if (hk->type != H_OFFDUP) { - if (hk->type != H_DUPLICATE) { - hk->type = H_DUPLICATE; + if (HPAGE_PTYPE(hk) != H_OFFDUP) { + if (HPAGE_PTYPE(hk) != H_DUPLICATE) { + HPAGE_PTYPE(hk) = H_DUPLICATE; pval.flags = 0; - pval.data = hk->data; + pval.data = HKEYDATA_DATA(hk); pval.size = LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx); - if ((ret = __ham_make_dup(&pval, &tmp_val, &hcp->big_data, - &hcp->big_datalen)) != 0 || - (ret = __ham_replpair(hashp, hcp, &tmp_val, 1)) != 0) + if ((ret = + __ham_make_dup(&pval, &tmp_val, &hcp->big_data, + &hcp->big_datalen)) != 0 || (ret = + __ham_replpair(hashp, hcp, &tmp_val, 1)) != 0) return (ret); } @@ -187,8 +188,7 @@ __ham_add_dup(hashp, hcp, nval, flags) /* If we get here, then we're on duplicate pages. */ if (hcp->dpgno == PGNO_INVALID) { - memcpy(&hcp->dpgno, - (u_int8_t *)hk + SSZ(HOFFDUP, pgno), sizeof(db_pgno_t)); + memcpy(&hcp->dpgno, HOFFDUP_PGNO(hk), sizeof(db_pgno_t)); hcp->dndx = 0; } @@ -259,14 +259,13 @@ __ham_dup_convert(hashp, hcp) * Now put the duplicates onto the new page. */ dbt.flags = 0; - switch (((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->type) { + switch (HPAGE_PTYPE(H_PAIRDATA(hcp->pagep, hcp->bndx))) { case H_KEYDATA: /* Simple case, one key on page; move it to dup page. */ dndx = 0; dbt.size = LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx); - dbt.data = - ((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->data; + dbt.data = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx)); ret = __db_pitem(hashp->dbp, hcp->dpagep, (u_int32_t)dndx, BKEYDATA_SIZE(dbt.size), NULL, &dbt); if (ret == 0) @@ -289,7 +288,7 @@ __ham_dup_convert(hashp, hcp) __ham_dirty_page(hashp, hcp->dpagep); break; case H_DUPLICATE: - p = ((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->data; + p = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx)); pend = p + LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx); @@ -366,24 +365,23 @@ __ham_check_move(hashp, hcp, add_len) { DBT k, d; DB_LSN new_lsn; - HKEYDATA *hk; PAGE *next_pagep; db_pgno_t next_pgno; int rectype, ret; u_int32_t new_datalen, old_len; + u_int8_t *hk; /* * Check if we can do whatever we need to on this page. If not, * then we'll have to move the current element to a new page. */ - hk = H_PAIRDATA(hcp->pagep, hcp->bndx); /* * If the item is already off page duplicates or an offpage item, * then we know we can do whatever we need to do in-place */ - if (hk->type == H_OFFDUP || hk->type == H_OFFPAGE) + if (HPAGE_PTYPE(hk) == H_OFFDUP || HPAGE_PTYPE(hk) == H_OFFPAGE) return (0); old_len = @@ -443,22 +441,25 @@ __ham_check_move(hashp, hcp, add_len) rectype = PUTPAIR; k.flags = 0; d.flags = 0; - if (H_PAIRKEY(hcp->pagep, hcp->bndx)->type == H_OFFPAGE) { + if (HPAGE_PTYPE( + H_PAIRKEY(hcp->pagep, hcp->bndx)) == H_OFFPAGE) { rectype |= PAIR_KEYMASK; k.data = H_PAIRKEY(hcp->pagep, hcp->bndx); k.size = HOFFPAGE_SIZE; } else { - k.data = H_PAIRKEY(hcp->pagep, hcp->bndx)->data; + k.data = + HKEYDATA_DATA(H_PAIRKEY(hcp->pagep, hcp->bndx)); k.size = LEN_HKEY(hcp->pagep, hashp->hdr->pagesize, hcp->bndx); } - if (hk->type == H_OFFPAGE) { + if (HPAGE_PTYPE(hk) == H_OFFPAGE) { rectype |= PAIR_DATAMASK; d.data = H_PAIRDATA(hcp->pagep, hcp->bndx); d.size = HOFFPAGE_SIZE; } else { - d.data = H_PAIRDATA(hcp->pagep, hcp->bndx)->data; + d.data = + HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx)); d.size = LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx); } diff --git a/db2/hash/hash_func.c b/db2/hash/hash_func.c index 2ef47afb57..1bf12c4948 100644 --- a/db2/hash/hash_func.c +++ b/db2/hash/hash_func.c @@ -47,7 +47,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)hash_func.c 10.6 (Sleepycat) 7/26/97"; +static const char sccsid[] = "@(#)hash_func.c 10.7 (Sleepycat) 9/16/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -64,7 +64,7 @@ static const char sccsid[] = "@(#)hash_func.c 10.6 (Sleepycat) 7/26/97"; * * PUBLIC: u_int32_t __ham_func2 __P((const void *, u_int32_t)); */ -#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c)) +#define DCHARHASH(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c)) u_int32_t __ham_func2(key, len) @@ -81,7 +81,7 @@ __ham_func2(key, len) c = *k++; if (!c && k > e) break; - dcharhash(h, c); + DCHARHASH(h, c); } return (h); } diff --git a/db2/hash/hash_page.c b/db2/hash/hash_page.c index 68c31b14f9..8ba42da1a4 100644 --- a/db2/hash/hash_page.c +++ b/db2/hash/hash_page.c @@ -47,10 +47,9 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)hash_page.c 10.18 (Sleepycat) 8/21/97"; +static const char sccsid[] = "@(#)hash_page.c 10.24 (Sleepycat) 9/17/97"; #endif /* not lint */ - /* * PACKAGE: hashing * @@ -85,7 +84,7 @@ static const char sccsid[] = "@(#)hash_page.c 10.18 (Sleepycat) 8/21/97"; static int __ham_lock_bucket __P((DB *, HASH_CURSOR *, db_lockmode_t)); #ifdef DEBUG_SLOW -static void account_page(HTAB *, db_pgno_t, int); +static void __account_page(HTAB *, db_pgno_t, int); #endif /* @@ -121,7 +120,7 @@ __ham_item(hashp, cursorp, mode) * pointer to be the beginning of the datum. */ memcpy(&cursorp->dup_len, - H_PAIRDATA(cursorp->pagep, cursorp->bndx)->data + + HKEYDATA_DATA(H_PAIRDATA(cursorp->pagep, cursorp->bndx)) + cursorp->dup_off, sizeof(db_indx_t)); else if (F_ISSET(cursorp, H_ISDUP)) { /* Make sure we're not about to run off the page. */ @@ -326,8 +325,8 @@ __ham_item_prev(hashp, cursorp, mode) else { HASH_CURSOR *h; h = cursorp; - memcpy(&h->dup_len, - H_PAIRDATA(h->pagep, h->bndx)->data + memcpy(&h->dup_len, HKEYDATA_DATA( + H_PAIRDATA(h->pagep, h->bndx)) + h->dup_off - sizeof(db_indx_t), sizeof(db_indx_t)); cursorp->dup_off -= @@ -481,7 +480,7 @@ __ham_putitem(p, dbt, type) } else { off = HOFFSET(p) - HKEYDATA_SIZE(dbt->size); HOFFSET(p) = p->inp[n] = off; - PUT_HKEYDATA(GET_HKEYDATA(p, n), dbt->data, dbt->size, type); + PUT_HKEYDATA(P_ENTRY(p, n), dbt->data, dbt->size, type); } /* Adjust page info. */ @@ -524,24 +523,24 @@ __ham_del_pair(hashp, cursorp) * entry referring to the big item. */ ret = 0; - if (H_PAIRKEY(p, ndx)->type == H_OFFPAGE) { - memcpy(&pgno, (u_int8_t *)GET_HOFFPAGE(p, H_KEYINDEX(ndx)) + - SSZ(HOFFPAGE, pgno), sizeof(db_pgno_t)); + if (HPAGE_PTYPE(H_PAIRKEY(p, ndx)) == H_OFFPAGE) { + memcpy(&pgno, HOFFPAGE_PGNO(P_ENTRY(p, H_KEYINDEX(ndx))), + sizeof(db_pgno_t)); ret = __db_doff(hashp->dbp, pgno, __ham_del_page); } if (ret == 0) - switch (H_PAIRDATA(p, ndx)->type) { + switch (HPAGE_PTYPE(H_PAIRDATA(p, ndx))) { case H_OFFPAGE: memcpy(&pgno, - (u_int8_t *)GET_HOFFPAGE(p, H_DATAINDEX(ndx)) + - SSZ(HOFFPAGE, pgno), sizeof(db_pgno_t)); + HOFFPAGE_PGNO(P_ENTRY(p, H_DATAINDEX(ndx))), + sizeof(db_pgno_t)); ret = __db_doff(hashp->dbp, pgno, __ham_del_page); break; case H_OFFDUP: memcpy(&pgno, - (u_int8_t *)GET_HOFFDUP(p, H_DATAINDEX(ndx)) + - SSZ(HOFFDUP, pgno), sizeof(db_pgno_t)); + HOFFDUP_PGNO(P_ENTRY(p, H_DATAINDEX(ndx))), + sizeof(db_pgno_t)); ret = __db_ddup(hashp->dbp, pgno, __ham_del_page); break; } @@ -706,13 +705,12 @@ __ham_replpair(hashp, hcp, dbt, make_dup) DBT *dbt; u_int32_t make_dup; { - DBT old_dbt, tmp; + DBT old_dbt, tdata, tmp; DB_LSN new_lsn; - HKEYDATA *hk; u_int32_t len; int32_t change; int is_big, ret, type; - u_int8_t *beg, *dest, *end, *src; + u_int8_t *beg, *dest, *end, *hk, *src; /* * Big item replacements are handled in generic code. @@ -738,11 +736,10 @@ __ham_replpair(hashp, hcp, dbt, make_dup) change = dbt->size - dbt->dlen; hk = H_PAIRDATA(hcp->pagep, hcp->bndx); - is_big = hk->type == H_OFFPAGE; + is_big = HPAGE_PTYPE(hk) == H_OFFPAGE; if (is_big) - memcpy(&len, (u_int8_t *)hk + SSZ(HOFFPAGE, tlen), - sizeof(u_int32_t)); + memcpy(&len, HOFFPAGE_TLEN(hk), sizeof(u_int32_t)); else len = LEN_HKEYDATA(hcp->pagep, hashp->dbp->pgsize, H_DATAINDEX(hcp->bndx)); @@ -770,13 +767,14 @@ __ham_replpair(hashp, hcp, dbt, make_dup) &tmp, &hcp->big_key, &hcp->big_keylen)) != 0) return (ret); - type = hk->type; if (dbt->doff == 0 && dbt->dlen == len) { ret = __ham_del_pair(hashp, hcp); if (ret == 0) - ret = __ham_add_el(hashp, hcp, &tmp, dbt, type); + ret = __ham_add_el(hashp, + hcp, &tmp, dbt, H_KEYDATA); } else { /* Case B */ - DBT tdata; + type = HPAGE_PTYPE(hk) != H_OFFPAGE ? + HPAGE_PTYPE(hk) : H_KEYDATA; tdata.flags = 0; F_SET(&tdata, DB_DBT_MALLOC | DB_DBT_INTERNAL); @@ -824,7 +822,7 @@ err: free(tmp.data); * Set up pointer into existing data. Do it before the log * message so we can use it inside of the log setup. */ - beg = H_PAIRDATA(hcp->pagep, hcp->bndx)->data; + beg = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx)); beg += dbt->doff; /* @@ -885,11 +883,11 @@ __ham_onpage_replace(pagep, pgsize, ndx, off, change, dbt) if (off < 0) len = pagep->inp[ndx] - HOFFSET(pagep); else if ((u_int32_t)off >= LEN_HKEYDATA(pagep, pgsize, ndx)) { - len = GET_HKEYDATA(pagep, ndx)->data + + len = HKEYDATA_DATA(P_ENTRY(pagep, ndx)) + LEN_HKEYDATA(pagep, pgsize, ndx) - src; zero_me = 1; } else - len = (GET_HKEYDATA(pagep, ndx)->data + off) - src; + len = (HKEYDATA_DATA(P_ENTRY(pagep, ndx)) + off) - src; dest = src - change; memmove(dest, src, len); if (zero_me) @@ -901,7 +899,7 @@ __ham_onpage_replace(pagep, pgsize, ndx, off, change, dbt) HOFFSET(pagep) -= change; } if (off >= 0) - memcpy(GET_HKEYDATA(pagep, ndx)->data + off, + memcpy(HKEYDATA_DATA(P_ENTRY(pagep, ndx)) + off, dbt->data, dbt->size); else memcpy(P_ENTRY(pagep, ndx), dbt->data, dbt->size); @@ -1319,7 +1317,7 @@ __ham_new_page(hashp, addr, type, pp) return (ret); #ifdef DEBUG_SLOW - account_page(hashp, addr, 1); + __account_page(hashp, addr, 1); #endif /* This should not be necessary because page-in should do it. */ P_INIT(pagep, @@ -1398,7 +1396,7 @@ __ham_put_page(dbp, pagep, is_dirty) int32_t is_dirty; { #ifdef DEBUG_SLOW - account_page((HTAB *)dbp->cookie, + __account_page((HTAB *)dbp->cookie, ((BKT *)((char *)pagep - sizeof(BKT)))->pgno, -1); #endif return (memp_fput(dbp->mpf, pagep, (is_dirty ? DB_MPOOL_DIRTY : 0))); @@ -1432,7 +1430,7 @@ __ham_get_page(dbp, addr, pagep) ret = memp_fget(dbp->mpf, &addr, DB_MPOOL_CREATE, pagep); #ifdef DEBUG_SLOW if (*pagep != NULL) - account_page((HTAB *)dbp->internal, addr, 1); + __account_page((HTAB *)dbp->internal, addr, 1); #endif return (ret); } @@ -1523,11 +1521,11 @@ __ham_overflow_page(dbp, type, pp) #ifdef DEBUG /* * PUBLIC: #ifdef DEBUG - * PUBLIC: int bucket_to_page __P((HTAB *, int)); + * PUBLIC: int __bucket_to_page __P((HTAB *, int)); * PUBLIC: #endif */ int -bucket_to_page(hashp, n) +__bucket_to_page(hashp, n) HTAB *hashp; int n; { @@ -1735,7 +1733,7 @@ __ham_dpair(dbp, p, pndx) #ifdef DEBUG_SLOW static void -account_page(hashp, pgno, inout) +__account_page(hashp, pgno, inout) HTAB *hashp; db_pgno_t pgno; int inout; @@ -1767,7 +1765,8 @@ account_page(hashp, pgno, inout) last--; } for (i = 0; i < last; i++, list[i].times++) - if (list[i].times > 20 && !is_bitmap_pgno(hashp, list[i].pgno)) + if (list[i].times > 20 && + !__is_bitmap_pgno(hashp, list[i].pgno)) (void)fprintf(stderr, "Warning: pg %lu has been out for %d times\n", (u_long)list[i].pgno, list[i].times); diff --git a/db2/hash/hash_rec.c b/db2/hash/hash_rec.c index 81d9bb5ea8..1b30be337d 100644 --- a/db2/hash/hash_rec.c +++ b/db2/hash/hash_rec.c @@ -47,7 +47,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)hash_rec.c 10.12 (Sleepycat) 8/22/97"; +static const char sccsid[] = "@(#)hash_rec.c 10.13 (Sleepycat) 9/15/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -364,11 +364,11 @@ __ham_replace_recover(logp, dbtp, lsnp, redo, info) DB *mdbp, *file_dbp; DB_MPOOLFILE *mpf; DBT dbt; - HKEYDATA *hk; HTAB *hashp; PAGE *pagep; int32_t grow; int change, cmp_n, cmp_p, getmeta, ret; + u_int8_t *hk; getmeta = 0; hashp = NULL; /* XXX: shut the compiler up. */ @@ -421,11 +421,11 @@ __ham_replace_recover(logp, dbtp, lsnp, redo, info) __ham_onpage_replace(pagep, file_dbp->pgsize, argp->ndx, argp->off, grow, &dbt); if (argp->makedup) { - hk = GET_HKEYDATA(pagep, argp->ndx); + hk = P_ENTRY(pagep, argp->ndx); if (redo) - hk->type = H_DUPLICATE; + HPAGE_PTYPE(hk) = H_DUPLICATE; else - hk->type = H_KEYDATA; + HPAGE_PTYPE(hk) = H_KEYDATA; } } @@ -738,7 +738,7 @@ __ham_ovfl_recover(logp, dbtp, lsnp, redo, info) DBT *dbtp; DB_LSN *lsnp; int redo; - void *info; + void *info; { __ham_ovfl_args *argp; DB *mdbp, *file_dbp; diff --git a/db2/include/btree.h b/db2/include/btree.h index 5cf4224ae6..878096b7b2 100644 --- a/db2/include/btree.h +++ b/db2/include/btree.h @@ -43,7 +43,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)btree.h 10.16 (Sleepycat) 8/24/97 + * @(#)btree.h 10.17 (Sleepycat) 9/23/97 */ /* Forward structure declarations. */ @@ -181,6 +181,12 @@ struct __cursor { #define C_DELETED 0x0001 #define C_REPLACE 0x0002 #define C_REPLACE_SETUP 0x0004 + + /* + * Internal cursor held for DB->get; don't hold locks unless involved + * in a TXN. + */ +#define C_INTERNAL 0x0008 u_int32_t flags; }; diff --git a/db2/include/btree_ext.h b/db2/include/btree_ext.h index dab0f5be4e..9133c58c6b 100644 --- a/db2/include/btree_ext.h +++ b/db2/include/btree_ext.h @@ -8,6 +8,7 @@ int __bam_pgin __P((db_pgno_t, void *, DBT *)); int __bam_pgout __P((db_pgno_t, void *, DBT *)); int __bam_mswap __P((PAGE *)); int __bam_cursor __P((DB *, DB_TXN *, DBC **)); +int __bam_c_iclose __P((DB *, DBC *)); int __bam_get __P((DB *, DB_TXN *, DBT *, DBT *, int)); int __bam_ovfl_chk __P((DB *, CURSOR *, u_int32_t, int)); int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, CURSOR *)); @@ -51,6 +52,7 @@ int __bam_cdel_recover int __ram_open __P((DB *, DBTYPE, DB_INFO *)); int __ram_cursor __P((DB *, DB_TXN *, DBC **)); int __ram_close __P((DB *)); +int __ram_c_iclose __P((DB *, DBC *)); void __ram_ca __P((DB *, db_recno_t, ca_recno_arg)); int __ram_getno __P((DB *, const DBT *, db_recno_t *, int)); int __ram_snapshot __P((DB *)); diff --git a/db2/include/db.h.src b/db2/include/db.h.src index f9b29fa2af..63d9603dba 100644 --- a/db2/include/db.h.src +++ b/db2/include/db.h.src @@ -4,7 +4,7 @@ * Copyright (c) 1996, 1997 * Sleepycat Software. All rights reserved. * - * @(#)db.h.src 10.67 (Sleepycat) 8/25/97 + * @(#)db.h.src 10.77 (Sleepycat) 9/24/97 */ #ifndef _DB_H_ @@ -67,8 +67,8 @@ #define DB_VERSION_MAJOR 2 #define DB_VERSION_MINOR 3 -#define DB_VERSION_PATCH 4 -#define DB_VERSION_STRING "Sleepycat Software: DB 2.3.4: (8/20/97)" +#define DB_VERSION_PATCH 10 +#define DB_VERSION_STRING "Sleepycat Software: DB 2.3.10: (9/24/97)" typedef u_int32_t db_pgno_t; /* Page number type. */ typedef u_int16_t db_indx_t; /* Page offset type. */ @@ -329,6 +329,7 @@ struct __db_info { #define DB_NEEDSPLIT ( -9) /* Page needs to be split. */ #define DB_REGISTERED (-10) /* Entry was previously registered. */ #define DB_SWAPBYTES (-11) /* Database needs byte swapping. */ +#define DB_TXN_CKP (-12) /* Encountered ckp record in log. */ struct __db_ilock { /* Internal DB access method lock. */ db_pgno_t pgno; /* Page being locked. */ @@ -338,7 +339,7 @@ struct __db_ilock { /* Internal DB access method lock. */ /* DB access method description structure. */ struct __db { - void *mutex; /* Synchronization for free threading */ + void *mutexp; /* Synchronization for free threading */ DBTYPE type; /* DB access method. */ DB_ENV *dbenv; /* DB_ENV structure. */ DB_ENV *mp_dbenv; /* DB_ENV for local mpool creation. */ @@ -640,11 +641,11 @@ extern "C" { #endif int memp_close __P((DB_MPOOL *)); int memp_fclose __P((DB_MPOOLFILE *)); -int memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, unsigned long, void *)); +int memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, int, void *)); int memp_fopen __P((DB_MPOOL *, const char *, int, int, int, size_t, int, DBT *, u_int8_t *, DB_MPOOLFILE **)); -int memp_fput __P((DB_MPOOLFILE *, void *, unsigned long)); -int memp_fset __P((DB_MPOOLFILE *, void *, unsigned long)); +int memp_fput __P((DB_MPOOLFILE *, void *, int)); +int memp_fset __P((DB_MPOOLFILE *, void *, int)); int memp_fsync __P((DB_MPOOLFILE *)); int memp_open __P((const char *, int, int, DB_ENV *, DB_MPOOL **)); int memp_register __P((DB_MPOOL *, int, @@ -697,7 +698,7 @@ extern "C" { #endif int txn_abort __P((DB_TXN *)); int txn_begin __P((DB_TXNMGR *, DB_TXN *, DB_TXN **)); -int txn_checkpoint __P((const DB_TXNMGR *, long, long)); +int txn_checkpoint __P((const DB_TXNMGR *, int, int)); int txn_commit __P((DB_TXN *)); int txn_close __P((DB_TXNMGR *)); u_int32_t txn_id __P((DB_TXN *)); diff --git a/db2/include/db_185.h.src b/db2/include/db_185.h.src index 52fb3a0da1..3fbca8bfda 100644 --- a/db2/include/db_185.h.src +++ b/db2/include/db_185.h.src @@ -36,7 +36,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)db_185.h.src 8.3 (Sleepycat) 7/27/97 + * @(#)db_185.h.src 8.4 (Sleepycat) 9/16/97 */ #ifndef _DB_185_H_ @@ -72,6 +72,14 @@ @u_int32_decl@ #endif +/* + * XXX + * SGI/IRIX already has a pgno_t. + */ +#ifdef sgi +#define pgno_t db_pgno_t +#endif + #define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */ typedef u_int32_t pgno_t; #define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */ diff --git a/db2/include/db_cxx.h b/db2/include/db_cxx.h index 506aed845c..611d967ef9 100644 --- a/db2/include/db_cxx.h +++ b/db2/include/db_cxx.h @@ -4,7 +4,7 @@ * Copyright (c) 1997 * Sleepycat Software. All rights reserved. * - * @(#)db_cxx.h 10.7 (Sleepycat) 8/22/97 + * @(#)db_cxx.h 10.8 (Sleepycat) 9/20/97 */ #ifndef _DB_CXX_H_ @@ -303,9 +303,9 @@ class _exported DbMpoolFile { public: int close(); - int get(db_pgno_t *pgnoaddr, unsigned long flags, void *pagep); - int put(void *pgaddr, unsigned long flags); - int set(void *pgaddr, unsigned long flags); + int get(db_pgno_t *pgnoaddr, int flags, void *pagep); + int put(void *pgaddr, int flags); + int set(void *pgaddr, int flags); int sync(); static int open(DbMpool *mp, const char *file, @@ -391,7 +391,7 @@ class _exported DbTxnMgr friend DbEnv; public: int begin(DbTxn *pid, DbTxn **tid); - int checkpoint(long kbyte, long min) const; + int checkpoint(int kbyte, int min) const; int close(); int stat(DB_TXN_STAT **statp, void *(*db_malloc)(size_t)); diff --git a/db2/include/db_ext.h b/db2/include/db_ext.h index 1cccb47617..b18b10ff7f 100644 --- a/db2/include/db_ext.h +++ b/db2/include/db_ext.h @@ -57,8 +57,8 @@ int __db_noop_print int __db_noop_read __P((void *, __db_noop_args **)); int __db_init_print __P((DB_ENV *)); int __db_init_recover __P((DB_ENV *)); -int __db_pgin __P((db_pgno_t, void *)); -int __db_pgout __P((db_pgno_t, void *)); +int __db_pgin __P((db_pgno_t, size_t, void *)); +int __db_pgout __P((db_pgno_t, size_t, void *)); int __db_dispatch __P((DB_LOG *, DBT *, DB_LSN *, int, void *)); int __db_add_recovery __P((DB_ENV *, int (*)(DB_LOG *, DBT *, DB_LSN *, int, void *), u_int32_t)); diff --git a/db2/include/db_int.h.src b/db2/include/db_int.h.src index b60e5002e5..ebadb35d36 100644 --- a/db2/include/db_int.h.src +++ b/db2/include/db_int.h.src @@ -4,7 +4,7 @@ * Copyright (c) 1996, 1997 * Sleepycat Software. All rights reserved. * - * @(#)db_int.h.src 10.28 (Sleepycat) 8/20/97 + * @(#)db_int.h.src 10.30 (Sleepycat) 9/23/97 */ #ifndef _DB_INTERNAL_H_ @@ -177,11 +177,11 @@ typedef struct _db_mutex_t { /* Lock/unlock a DB thread. */ #define DB_THREAD_LOCK(dbp) \ (F_ISSET(dbp, DB_AM_THREAD) ? \ - __db_mutex_lock((db_mutex_t *)(dbp)->mutex, -1, \ + __db_mutex_lock((db_mutex_t *)(dbp)->mutexp, -1, \ (dbp)->dbenv == NULL ? NULL : (dbp)->dbenv->db_yield) : 0) #define DB_THREAD_UNLOCK(dbp) \ (F_ISSET(dbp, DB_AM_THREAD) ? \ - __db_mutex_unlock((db_mutex_t *)(dbp)->mutex, -1) : 0) + __db_mutex_unlock((db_mutex_t *)(dbp)->mutexp, -1) : 0) /* Btree/recno local statistics structure. */ struct __db_bt_lstat; typedef struct __db_bt_lstat DB_BTREE_LSTAT; @@ -306,14 +306,6 @@ typedef struct __dbpginfo { * Transactions and recovery. *******************************************************/ /* - * The locker id space is divided between the transaction manager and the lock - * manager. Lockid's start at 0 and go to MAX_LOCKER_ID. Txn Id's start at - * MAX_LOCKER_ID + 1 and go up to MAX_TXNID. - */ -#define MAX_LOCKER_ID 0x0fffffff -#define MAX_TXNID 0xffffffff - -/* * Out of band value for a lock. The locks are returned to callers as offsets * into the lock regions. Since the RLAYOUT structure begins all regions, an * offset of 0 is guaranteed not to be a valid lock. diff --git a/db2/include/db_page.h b/db2/include/db_page.h index cde7ff9f2e..30f6072fc3 100644 --- a/db2/include/db_page.h +++ b/db2/include/db_page.h @@ -4,7 +4,7 @@ * Copyright (c) 1996, 1997 * Sleepycat Software. All rights reserved. * - * @(#)db_page.h 10.11 (Sleepycat) 9/3/97 + * @(#)db_page.h 10.13 (Sleepycat) 9/24/97 */ #ifndef _DB_PAGE_H_ @@ -273,6 +273,17 @@ typedef struct _db_page { #define H_OFFDUP 4 /* Overflow page of duplicates. */ /* + * !!! + * Items on hash pages are (potentially) unaligned, so we can never cast the + * (page + offset) pointer to an HKEYDATA, HOFFPAGE or HOFFDUP structure, as + * we do with B+tree on-page structures. Because we frequently want the type + * field, it requires no alignment, and it's in the same location in all three + * structures, there's a pair of macros. + */ +#define HPAGE_PTYPE(p) (*(u_int8_t *)p) +#define HPAGE_TYPE(pg, indx) (*P_ENTRY(pg, indx)) + +/* * The first and second types are H_KEYDATA and H_DUPLICATE, represented * by the HKEYDATA structure: * @@ -294,10 +305,7 @@ typedef struct _hkeydata { u_int8_t type; /* 00: Page type. */ u_int8_t data[1]; /* Variable length key/data item. */ } HKEYDATA; - -/* Get a HKEYDATA item for a specific index. */ -#define GET_HKEYDATA(pg, indx) \ - ((HKEYDATA *)P_ENTRY(pg, indx)) +#define HKEYDATA_DATA(p) (((u_int8_t *)p) + SSZA(HKEYDATA, data)) /* * The length of any HKEYDATA item. Note that indx is an element index, @@ -333,8 +341,8 @@ typedef struct _hkeydata { #define H_NUMPAIRS(pg) (NUM_ENT(pg) / 2) #define H_KEYINDEX(pindx) (2 * (pindx)) #define H_DATAINDEX(pindx) ((2 * (pindx)) + 1) -#define H_PAIRKEY(pg, pindx) GET_HKEYDATA(pg, H_KEYINDEX(pindx)) -#define H_PAIRDATA(pg, pindx) GET_HKEYDATA(pg, H_DATAINDEX(pindx)) +#define H_PAIRKEY(pg, pindx) P_ENTRY(pg, H_KEYINDEX(pindx)) +#define H_PAIRDATA(pg, pindx) P_ENTRY(pg, H_DATAINDEX(pindx)) #define H_PAIRSIZE(pg, psize, pindx) \ (LEN_HITEM(pg, psize, H_KEYINDEX(pindx)) + \ LEN_HITEM(pg, psize, H_DATAINDEX(pindx))) @@ -355,9 +363,8 @@ typedef struct _hoffpage { u_int32_t tlen; /* 08-11: Total length of item. */ } HOFFPAGE; -/* Get a HOFFPAGE item for a specific index. */ -#define GET_HOFFPAGE(pg, indx) \ - ((HOFFPAGE *)P_ENTRY(pg, indx)) +#define HOFFPAGE_PGNO(p) (((u_int8_t *)p) + SSZ(HOFFPAGE, pgno)) +#define HOFFPAGE_TLEN(p) (((u_int8_t *)p) + SSZ(HOFFPAGE, tlen)) /* * Page space required to add a new HOFFPAGE item to the page, with and @@ -378,10 +385,7 @@ typedef struct _hoffdup { u_int8_t unused[3]; /* 01-03: Padding, unused. */ db_pgno_t pgno; /* 04-07: Offpage page number. */ } HOFFDUP; - -/* Get a HOFFDUP item for a specific index. */ -#define GET_HOFFDUP(pg, indx) \ - ((HOFFDUP *)P_ENTRY(pg, indx)) +#define HOFFDUP_PGNO(p) (((u_int8_t *)p) + SSZ(HOFFDUP, pgno)) /* * Page space required to add a new HOFFDUP item to the page, with and diff --git a/db2/include/db_shash.h b/db2/include/db_shash.h index f695a2bafa..b94e0f1d41 100644 --- a/db2/include/db_shash.h +++ b/db2/include/db_shash.h @@ -4,14 +4,14 @@ * Copyright (c) 1996, 1997 * Sleepycat Software. All rights reserved. * - * @(#)db_shash.h 10.1 (Sleepycat) 4/12/97 + * @(#)db_shash.h 10.2 (Sleepycat) 9/16/97 */ /* Hash Headers */ typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB; /* - * __db_hashlookup -- + * HASHLOOKUP -- * * Look up something in a shared memory hash table. The "elt" argument * should be a key, and cmp_func must know how to compare a key to whatever @@ -30,7 +30,7 @@ typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB; * If the element is not in the hash table, this macro exits with result * set to NULL. */ -#define __db_hashlookup(begin, type, field, elt, r, n, hash, cmp) do { \ +#define HASHLOOKUP(begin, type, field, elt, r, n, hash, cmp) do { \ DB_HASHTAB *__bucket; \ u_int32_t __ndx; \ \ @@ -43,10 +43,10 @@ typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB; } while(0) /* - * __db_hashinsert -- + * HASHINSERT -- * * Insert a new entry into the hash table. This assumes that lookup has - * failed; don't call it if you haven't already called __db_hashlookup. + * failed; don't call it if you haven't already called HASHLOOKUP. * begin: the beginning address of the hash table. * type: the structure type of the elements that are linked in each bucket. * field: the name of the field by which the "type" structures are linked. @@ -54,7 +54,7 @@ typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB; * nelems: the number of buckets in the hash table. * hash_func: the hash function that operates on elements of the type of elt */ -#define __db_hashinsert(begin, type, field, elt, n, hash) do { \ +#define HASHINSERT(begin, type, field, elt, n, hash) do { \ u_int32_t __ndx; \ DB_HASHTAB *__bucket; \ \ @@ -64,7 +64,7 @@ typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB; } while(0) /* - * __db_hashremove -- + * HASHREMOVE -- * Remove the entry with a key == elt. * begin: address of the beginning of the hash table. * type: the structure type of the elements that are linked in each bucket. @@ -75,19 +75,19 @@ typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB; * cmp_func: compare elements of the type of elt with those in the table (of * type "type"). */ -#define __db_hashremove(begin, type, field, elt, n, hash, cmp) { \ +#define HASHREMOVE(begin, type, field, elt, n, hash, cmp) { \ u_int32_t __ndx; \ DB_HASHTAB *__bucket; \ SH_TAILQ_ENTRY *__entp; \ \ __ndx = hash(elt) % (n); \ __bucket = &begin[__ndx]; \ - __db_hashlookup(begin, type, field, elt, __entp, n, hash, cmp); \ + HASHLOOKUP(begin, type, field, elt, __entp, n, hash, cmp); \ SH_TAILQ_REMOVE(__bucket, __entp, field, type); \ } /* - * __db_hashremove_el -- + * HASHREMOVE_EL -- * Given the object "obj" in the table, remove it. * begin: address of the beginning of the hash table. * type: the structure type of the elements that are linked in each bucket. @@ -96,7 +96,7 @@ typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB; * nelems: the number of buckets in the hash table. * hash_func: the hash function that operates on elements of the type of elt */ -#define __db_hashremove_el(begin, type, field, obj, n, hash) { \ +#define HASHREMOVE_EL(begin, type, field, obj, n, hash) { \ u_int32_t __ndx; \ DB_HASHTAB *__bucket; \ \ diff --git a/db2/include/hash_ext.h b/db2/include/hash_ext.h index 5ae63dc6ad..32788c7b8a 100644 --- a/db2/include/hash_ext.h +++ b/db2/include/hash_ext.h @@ -1,6 +1,7 @@ /* Do not edit: automatically built by dist/distrib. */ int __ham_open __P((DB *, DB_INFO *)); int __ham_close __P((DB *)); +int __ham_c_iclose __P((DB *, DBC *)); int __ham_expand_table __P((HTAB *)); u_int32_t __ham_call_hash __P((HTAB *, u_int8_t *, int32_t)); int __ham_init_dbt __P((DBT *, u_int32_t, void **, u_int32_t *)); @@ -96,7 +97,7 @@ int __ham_dirty_page __P((HTAB *, PAGE *)); int __ham_get_page __P((DB *, db_pgno_t, PAGE **)); int __ham_overflow_page __P((DB *, u_int32_t, PAGE **)); #ifdef DEBUG -int bucket_to_page __P((HTAB *, int)); +int __bucket_to_page __P((HTAB *, int)); #endif void __ham_init_ovflpages __P((HTAB *)); int __ham_get_cpage __P((HTAB *, HASH_CURSOR *, db_lockmode_t)); diff --git a/db2/include/lock.h b/db2/include/lock.h index 18d29e8740..8f9e81c0fa 100644 --- a/db2/include/lock.h +++ b/db2/include/lock.h @@ -4,13 +4,19 @@ * Copyright (c) 1996, 1997 * Sleepycat Software. All rights reserved. * - * @(#)lock.h 10.7 (Sleepycat) 7/29/97 + * @(#)lock.h 10.8 (Sleepycat) 9/23/97 */ typedef struct __db_lockobj DB_LOCKOBJ; #define DB_DEFAULT_LOCK_FILE "__db_lock.share" #define DB_LOCK_DEFAULT_N 5000 + +/* + * The locker id space is divided between the transaction manager and the lock + * manager. Lockid's start at 0 and go to DB_LOCK_MAXID. Txn Id's start at + * DB_LOCK_MAXID + 1 and go up to TXN_INVALID. + */ #define DB_LOCK_MAXID 0x7fffffff /* diff --git a/db2/include/log.h b/db2/include/log.h index 970dfd153a..a9c82fa04d 100644 --- a/db2/include/log.h +++ b/db2/include/log.h @@ -4,7 +4,7 @@ * Copyright (c) 1996, 1997 * Sleepycat Software. All rights reserved. * - * @(#)log.h 10.8 (Sleepycat) 8/18/97 + * @(#)log.h 10.9 (Sleepycat) 9/23/97 */ #ifndef _LOG_H_ @@ -30,11 +30,11 @@ struct __log_persist; typedef struct __log_persist LOGP; /* Macros to lock/unlock the region and threads. */ #define LOCK_LOGTHREAD(dblp) \ if (F_ISSET(dblp, DB_AM_THREAD)) \ - (void)__db_mutex_lock(&(dblp)->mutex, -1, \ + (void)__db_mutex_lock((dblp)->mutexp, -1, \ (dblp)->dbenv == NULL ? NULL : (dblp)->dbenv->db_yield) #define UNLOCK_LOGTHREAD(dblp) \ if (F_ISSET(dblp, DB_AM_THREAD)) \ - (void)__db_mutex_unlock(&(dblp)->mutex, -1); + (void)__db_mutex_unlock((dblp)->mutexp, -1); #define LOCK_LOGREGION(dblp) \ (void)__db_mutex_lock(&((RLAYOUT *)(dblp)->lp)->lock, \ (dblp)->fd, (dblp)->dbenv == NULL ? NULL : (dblp)->dbenv->db_yield) @@ -56,7 +56,7 @@ typedef struct __db_entry { */ struct __db_log { /* These fields need to be protected for multi-threaded support. */ - db_mutex_t mutex; /* Mutex for thread protection. */ + db_mutex_t *mutexp; /* Mutex for thread protection. */ DB_ENTRY *dbentry; /* Recovery file-id mapping. */ #define DB_GROW_SIZE 64 @@ -86,6 +86,8 @@ struct __db_log { void *addr; /* Address of shalloc() region. */ int fd; /* Region file descriptor. */ + char *dir; /* Directory argument. */ + u_int32_t flags; /* Support the DB_AM_XXX flags. */ }; diff --git a/db2/include/log_ext.h b/db2/include/log_ext.h index d5c9dd6e72..bc63d9dac8 100644 --- a/db2/include/log_ext.h +++ b/db2/include/log_ext.h @@ -1,6 +1,6 @@ /* Do not edit: automatically built by dist/distrib. */ -int __log_find __P((DB_ENV *, LOG *, int *)); -int __log_valid __P((DB_ENV *, LOG *, int)); +int __log_find __P((DB_LOG *, int *)); +int __log_valid __P((DB_LOG *, LOG *, int)); int __log_register_log __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t, DBT *, DBT *, u_int32_t, DBTYPE)); @@ -18,7 +18,7 @@ int __log_init_recover __P((DB_ENV *)); int __log_findckp __P((DB_LOG *, DB_LSN *)); int __log_get __P((DB_LOG *, DB_LSN *, DBT *, int, int)); int __log_put __P((DB_LOG *, DB_LSN *, const DBT *, int)); -int __log_name __P((DB_ENV *, int, char **)); +int __log_name __P((DB_LOG *, int, char **)); int __log_register_recover __P((DB_LOG *, DBT *, DB_LSN *, int, void *)); int __log_unregister_recover diff --git a/db2/include/mp.h b/db2/include/mp.h index 1fe0c752a9..3b71774484 100644 --- a/db2/include/mp.h +++ b/db2/include/mp.h @@ -4,7 +4,7 @@ * Copyright (c) 1996, 1997 * Sleepycat Software. All rights reserved. * - * @(#)mp.h 10.15 (Sleepycat) 8/29/97 + * @(#)mp.h 10.16 (Sleepycat) 9/23/97 */ struct __bh; typedef struct __bh BH; @@ -99,7 +99,7 @@ struct __mpoolfile; typedef struct __mpoolfile MPOOLFILE; */ struct __db_mpool { /* These fields need to be protected for multi-threaded support. */ - db_mutex_t mutex; /* Structure lock. */ + db_mutex_t *mutexp; /* Structure lock. */ /* List of pgin/pgout routines. */ LIST_HEAD(__db_mpregh, __db_mpreg) dbregq; @@ -145,7 +145,7 @@ struct __db_mpreg { */ struct __db_mpoolfile { /* These fields need to be protected for multi-threaded support. */ - db_mutex_t mutex; /* Structure lock. */ + db_mutex_t *mutexp; /* Structure lock. */ int fd; /* Underlying file descriptor. */ diff --git a/db2/include/shqueue.h b/db2/include/shqueue.h index c3e2f4aecc..c596d33e92 100644 --- a/db2/include/shqueue.h +++ b/db2/include/shqueue.h @@ -1,38 +1,11 @@ -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. +/*- + * See the file LICENSE for redistribution information. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * Copyright (c) 1996, 1997 + * Sleepycat Software. All rights reserved. * - * @(#)shqueue.h 8.11 (Sleepycat) 7/27/97 + * @(#)shqueue.h 8.12 (Sleepycat) 9/10/97 */ - #ifndef _SYS_SHQUEUE_H_ #define _SYS_SHQUEUE_H_ diff --git a/db2/include/txn.h b/db2/include/txn.h index f4e0999b36..8bb3976c1c 100644 --- a/db2/include/txn.h +++ b/db2/include/txn.h @@ -4,7 +4,7 @@ * Copyright (c) 1996, 1997 * Sleepycat Software. All rights reserved. * - * @(#)txn.h 10.6 (Sleepycat) 7/29/97 + * @(#)txn.h 10.10 (Sleepycat) 9/23/97 */ #ifndef _TXN_H_ #define _TXN_H_ @@ -14,8 +14,9 @@ * the region is always created group RW of the group owning the directory. */ #define DEFAULT_TXN_FILE "__db_txn.share" +/* TXN_MINIMUM = (DB_LOCK_MAXID + 1) but this makes compilers complain. */ +#define TXN_MINIMUM 0x80000000 #define TXN_INVALID 0xffffffff /* Maximum number of txn ids. */ -#define TXN_MINIMUM 0x80000000 /* First transaction id */ /* * Transaction type declarations. @@ -36,6 +37,7 @@ typedef struct __txn_detail { #define TXN_ABORTED 2 #define TXN_PREPARED 3 u_int32_t status; /* status of the transaction */ + SH_TAILQ_ENTRY links; /* free/active list */ } TXN_DETAIL; /* @@ -45,7 +47,7 @@ typedef struct __txn_detail { */ struct __db_txnmgr { /* These fields need to be protected for multi-threaded support. */ - db_mutex_t mutex; /* Synchronization. */ + db_mutex_t *mutexp; /* Synchronization. */ /* list of active transactions */ TAILQ_HEAD(_chain, __db_txn) txn_chain; @@ -57,11 +59,14 @@ struct __db_txnmgr { u_int flags; /* DB_TXN_NOSYNC, DB_THREAD */ size_t reg_size; /* how large we think the region is */ DB_TXNREGION *region; /* address of shared memory region */ + void *mem; /* address of the shalloc space */ }; /* * Layout of the shared memory region. - * + * The region consists of a DB_TXNREGION structure followed by a large + * pool of shalloc'd memory which is used to hold TXN_DETAIL structures + * and thread mutexes (which are dynamically allocated). */ struct __db_txnregion { RLAYOUT hdr; /* Shared memory region header. */ @@ -69,7 +74,6 @@ struct __db_txnregion { u_int32_t version; /* version number */ u_int32_t maxtxns; /* maximum number of active txns */ u_int32_t last_txnid; /* last transaction id given out */ - u_int32_t free_txn; /* head of transaction free list */ DB_LSN pending_ckp; /* last checkpoint did not finish */ DB_LSN last_ckp; /* lsn of the last checkpoint */ time_t time_ckp; /* time of last checkpoint */ @@ -78,20 +82,25 @@ struct __db_txnregion { u_int32_t naborts; /* number of aborted transactions */ u_int32_t ncommits; /* number of committed transactions */ u_int32_t nbegins; /* number of begun transactions */ - TXN_DETAIL table[1]; /* array of TXN structures */ + SH_TAILQ_HEAD(_active) active_txn; /* active transaction list */ }; +/* + * Make the region large enough to hold N transaction detail structures + * plus some space to hold thread handles and the beginning of the shalloc + * region. + */ #define TXN_REGION_SIZE(N) \ - (sizeof(DB_TXNREGION) + N * sizeof(DB_TXN)) + (sizeof(DB_TXNREGION) + N * sizeof(TXN_DETAIL) + 1000) /* Macros to lock/unlock the region and threads. */ #define LOCK_TXNTHREAD(tmgrp) \ if (F_ISSET(tmgrp, DB_THREAD)) \ - (void)__db_mutex_lock(&(tmgrp)->mutex, -1, \ + (void)__db_mutex_lock((tmgrp)->mutexp, -1, \ (tmgrp)->dbenv == NULL ? NULL : (tmgrp)->dbenv->db_yield) #define UNLOCK_TXNTHREAD(tmgrp) \ if (F_ISSET(tmgrp, DB_THREAD)) \ - (void)__db_mutex_unlock(&(tmgrp)->mutex, -1) + (void)__db_mutex_unlock((tmgrp)->mutexp, -1) #define LOCK_TXNREGION(tmgrp) \ (void)__db_mutex_lock(&(tmgrp)->region->hdr.lock,(tmgrp)->fd, \ diff --git a/db2/lock/lock.c b/db2/lock/lock.c index 8fc91334a7..a2a3b208f2 100644 --- a/db2/lock/lock.c +++ b/db2/lock/lock.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)lock.c 10.31 (Sleepycat) 8/17/97"; +static const char sccsid[] = "@(#)lock.c 10.36 (Sleepycat) 9/24/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -201,7 +201,7 @@ lock_open(path, flags, mode, dbenv, ltp) * Create the lock table structure. */ if ((lt = (DB_LOCKTAB *)calloc(1, sizeof(DB_LOCKTAB))) == NULL) { - __db_err(dbenv, "%s", strerror(errno)); + __db_err(dbenv, "%s", strerror(ENOMEM)); return (ENOMEM); } lt->dbenv = dbenv; @@ -319,8 +319,10 @@ lock_vec(lt, locker, flags, list, nlist, elistp) case DB_LOCK_GET: ret = __lock_get_internal(lt, locker, flags, list[i].obj, list[i].mode, &lp); - if (ret == 0) + if (ret == 0) { list[i].lock = LOCK_TO_OFFSET(lt, lp); + lt->region->nrequests++; + } break; case DB_LOCK_PUT: lp = OFFSET_TO_LOCK(lt, list[i].lock); @@ -351,7 +353,7 @@ lock_vec(lt, locker, flags, list, nlist, elistp) case DB_LOCK_PUT_OBJ: /* Look up the object in the hash table. */ - __db_hashlookup(lt->hashtab, __db_lockobj, links, + HASHLOOKUP(lt->hashtab, __db_lockobj, links, list[i].obj, sh_obj, lt->region->table_size, __lock_ohash, __lock_cmp); if (sh_obj == NULL) { @@ -596,8 +598,8 @@ __lock_put_internal(lt, lockp, do_all) /* Check if object should be reclaimed. */ if (SH_TAILQ_FIRST(&sh_obj->holders, __db_lock) == NULL) { - __db_hashremove_el(lt->hashtab, __db_lockobj, links, sh_obj, - lt->region->table_size, __lock_lhash); + HASHREMOVE_EL(lt->hashtab, __db_lockobj, + links, sh_obj, lt->region->table_size, __lock_lhash); __db_shalloc_free(lt->mem, SH_DBT_PTR(&sh_obj->lockobj)); SH_TAILQ_INSERT_HEAD(<->region->free_objs, sh_obj, links, __db_lockobj); @@ -676,8 +678,12 @@ __lock_get_internal(lt, locker, flags, obj, lock_mode, lockp) * Now we have a lock and an object and we need to see if we should * grant the lock. We use a FIFO ordering so we can only grant a * new lock if it does not conflict with anyone on the holders list - * OR anyone on the waiters list. In case of conflict, we put the - * new lock on the end of the waiters list. + * OR anyone on the waiters list. The reason that we don't grant if + * there's a conflict is that this can lead to starvation (a writer + * waiting on a popularly read item will never ben granted). The + * downside of this is that a waiting reader can prevent an upgrade + * from reader to writer, which is not uncommon. In case of conflict, + * we put the new lock on the end of the waiters list. */ for (lp = SH_TAILQ_FIRST(&sh_obj->holders, __db_lock); lp != NULL; @@ -1042,7 +1048,7 @@ __lock_dump_locker(lt, op) ptr = SH_DBT_PTR(&op->lockobj); memcpy(&locker, ptr, sizeof(u_int32_t)); - printf("L %lu", (u_long)locker); + printf("L %lx", (u_long)locker); lp = SH_LIST_FIRST(&op->heldby, __db_lock); if (lp == NULL) { @@ -1095,7 +1101,7 @@ __lock_is_locked(lt, locker, dbt, mode) lrp = lt->region; /* Look up the object in the hash table. */ - __db_hashlookup(lt->hashtab, __db_lockobj, links, + HASHLOOKUP(lt->hashtab, __db_lockobj, links, dbt, sh_obj, lrp->table_size, __lock_ohash, __lock_cmp); if (sh_obj == NULL) return (0); @@ -1171,7 +1177,7 @@ __lock_printlock(lt, lp, ispgno) stat = "UNKNOWN"; break; } - printf("\t%lu\t%s\t%lu\t%s\t", + printf("\t%lx\t%s\t%lu\t%s\t", (u_long)lp->holder, mode, (u_long)lp->refcount, stat); lockobj = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj); @@ -1243,11 +1249,11 @@ __lock_getobj(lt, locker, dbt, type, objp) /* Look up the object in the hash table. */ if (type == DB_LOCK_OBJTYPE) { - __db_hashlookup(lt->hashtab, __db_lockobj, links, dbt, sh_obj, + HASHLOOKUP(lt->hashtab, __db_lockobj, links, dbt, sh_obj, lrp->table_size, __lock_ohash, __lock_cmp); obj_size = dbt->size; } else { - __db_hashlookup(lt->hashtab, __db_lockobj, links, locker, + HASHLOOKUP(lt->hashtab, __db_lockobj, links, locker, sh_obj, lrp->table_size, __lock_locker_hash, __lock_locker_cmp); obj_size = sizeof(locker); @@ -1288,8 +1294,8 @@ __lock_getobj(lt, locker, dbt, type, objp) sh_obj->lockobj.size = obj_size; sh_obj->lockobj.off = SH_PTR_TO_OFF(&sh_obj->lockobj, p); - __db_hashinsert(lt->hashtab, __db_lockobj, links, sh_obj, - lrp->table_size, __lock_lhash); + HASHINSERT(lt->hashtab, + __db_lockobj, links, sh_obj, lrp->table_size, __lock_lhash); if (type == DB_LOCK_LOCKER) lrp->nlockers++; @@ -1325,8 +1331,8 @@ __lock_freeobj(lt, obj) DB_LOCKTAB *lt; DB_LOCKOBJ *obj; { - __db_hashremove_el(lt->hashtab, __db_lockobj, links, - obj, lt->region->table_size, __lock_lhash); + HASHREMOVE_EL(lt->hashtab, + __db_lockobj, links, obj, lt->region->table_size, __lock_lhash); __db_shalloc_free(lt->mem, SH_DBT_PTR(&obj->lockobj)); SH_TAILQ_INSERT_HEAD(<->region->free_objs, obj, links, __db_lockobj); } diff --git a/db2/lock/lock_deadlock.c b/db2/lock/lock_deadlock.c index f753958b21..f947f901c3 100644 --- a/db2/lock/lock_deadlock.c +++ b/db2/lock/lock_deadlock.c @@ -11,7 +11,7 @@ static const char copyright[] = "@(#) Copyright (c) 1997\n\ Sleepycat Software Inc. All rights reserved.\n"; -static const char sccsid[] = "@(#)lock_deadlock.c 10.20 (Sleepycat) 8/21/97"; +static const char sccsid[] = "@(#)lock_deadlock.c 10.21 (Sleepycat) 9/6/97"; #endif #ifndef NO_SYSTEM_INCLUDES @@ -300,8 +300,8 @@ retry: count = lt->region->nlockers; for (lp = SH_TAILQ_FIRST(&op->holders, __db_lock); lp != NULL; lp = SH_TAILQ_NEXT(lp, links, __db_lock)) { - if ((__set_errno(__lock_getobj(lt, lp->holder, - NULL, DB_LOCK_LOCKER, &lockerp))) != 0) { + if (__lock_getobj(lt, lp->holder, + NULL, DB_LOCK_LOCKER, &lockerp) != 0) { __db_err(dbenv, "warning unable to find object"); continue; @@ -472,8 +472,7 @@ __dd_debug(dbenv, idmap, bitmap, nlockers) * Alloc space to print 10 bytes per item waited on. */ if ((msgbuf = (char *)malloc((nlockers + 1) * 10 + 64)) == NULL) { - __set_errno(ENOMEM); - __db_err(dbenv, "%s", strerror(errno)); + __db_err(dbenv, "%s", strerror(ENOMEM)); return; } diff --git a/db2/log/log.c b/db2/log/log.c index d3e5183588..893c1ee402 100644 --- a/db2/log/log.c +++ b/db2/log/log.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)log.c 10.25 (Sleepycat) 8/27/97"; +static const char sccsid[] = "@(#)log.c 10.27 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -29,7 +29,7 @@ static const char sccsid[] = "@(#)log.c 10.25 (Sleepycat) 8/27/97"; #include "txn_auto.h" #include "common_ext.h" -static int __log_recover __P((DB_ENV *, DB_LOG *)); +static int __log_recover __P((DB_LOG *)); /* * log_open -- @@ -70,14 +70,15 @@ log_open(path, flags, mode, dbenv, lpp) if ((dblp = (DB_LOG *)calloc(1, sizeof(DB_LOG))) == NULL) return (ENOMEM); + if (path != NULL && (dblp->dir = strdup(path)) == NULL) { + free(dblp); + return (ENOMEM); + } + dblp->dbenv = dbenv; dblp->lfd = -1; ZERO_LSN(dblp->c_lsn); dblp->c_fd = -1; - if (LF_ISSET(DB_THREAD)) { - F_SET(dblp, DB_AM_THREAD); - (void)__db_mutex_init(&dblp->mutex, -1); - } /* * The log region isn't fixed size because we store the registered @@ -114,7 +115,7 @@ retry: if (LF_ISSET(DB_CREATE)) { newregion = 1; } else if (ret != EEXIST) - return (ret); + goto err; } /* If we didn't or couldn't create the region, try and join it. */ @@ -129,7 +130,7 @@ retry: if (LF_ISSET(DB_CREATE)) { (void)__db_sleep(1, 0); goto retry; } - return (ret); + goto err; } /* Set up the common information. */ @@ -137,19 +138,49 @@ retry: if (LF_ISSET(DB_CREATE)) { dblp->addr = (u_int8_t *)dblp->maddr + sizeof(LOG); dblp->fd = fd; + /* Initialize thread information. */ + if (LF_ISSET(DB_THREAD)) { + F_SET(dblp, DB_AM_THREAD); + + if (!newregion) + LOCK_LOGREGION(dblp); + if ((ret = __db_shalloc(dblp->addr, + sizeof(db_mutex_t), MUTEX_ALIGNMENT, &dblp->mutexp)) == 0) + (void)__db_mutex_init(dblp->mutexp, -1); + if (!newregion) + UNLOCK_LOGREGION(dblp); + if (ret != 0) { + (void)log_close(dblp); + if (newregion) + (void)log_unlink(path, 1, dbenv); + return (ret); + } + } + /* * If doing recovery, try and recover any previous log files * before releasing the lock. */ if (newregion) { - if ((ret = __log_recover(dbenv, dblp)) != 0) { - log_unlink(path, 1, dbenv); + ret = __log_recover(dblp); + UNLOCK_LOGREGION(dblp); + + if (ret != 0) { + (void)log_close(dblp); + (void)log_unlink(path, 1, dbenv); return (ret); } - UNLOCK_LOGREGION(dblp); } *lpp = dblp; return (0); + +err: /* + * We never get here with an allocated thread-mutex, so we do + * not have to worry about freeing it. + */ + FREE(dblp, sizeof(DB_LOG)); + return (ret); + } /* @@ -157,8 +188,7 @@ retry: if (LF_ISSET(DB_CREATE)) { * Recover a log. */ static int -__log_recover(dbenv, dblp) - DB_ENV *dbenv; +__log_recover(dblp) DB_LOG *dblp; { DBT dbt; @@ -173,14 +203,14 @@ __log_recover(dbenv, dblp) * Find a log file. If none exist, we simply return, leaving * everything initialized to a new log. */ - if ((ret = __log_find(dbenv, lp, &cnt)) != 0) + if ((ret = __log_find(dblp, &cnt)) != 0) return (ret); if (cnt == 0) return (0); /* We have a log file name, find the last one. */ while (cnt < MAXLFNAME) - if (__log_valid(dbenv, lp, ++cnt) != 0) { + if (__log_valid(dblp, lp, ++cnt) != 0) { --cnt; break; } @@ -263,7 +293,7 @@ __log_recover(dbenv, dblp) lp->c_lsn.offset = 0; } - __db_err(dbenv, + __db_err(dblp->dbenv, "Recovering the log: last valid LSN: file: %lu offset %lu", (u_long)lp->lsn.file, (u_long)lp->lsn.offset); @@ -277,12 +307,11 @@ __log_recover(dbenv, dblp) * __log_find -- * Try to find a log file. * - * PUBLIC: int __log_find __P((DB_ENV *, LOG *, int *)); + * PUBLIC: int __log_find __P((DB_LOG *, int *)); */ int -__log_find(dbenv, lp, valp) - DB_ENV *dbenv; - LOG *lp; +__log_find(dblp, valp) + DB_LOG *dblp; int *valp; { int cnt, fcnt, logval, ret; @@ -290,7 +319,7 @@ __log_find(dbenv, lp, valp) char **names, *p, *q; /* Find the directory name. */ - if ((ret = __log_name(dbenv, 1, &p)) != 0) + if ((ret = __log_name(dblp, 1, &p)) != 0) return (ret); if ((q = __db_rpath(p)) == NULL) dir = PATH_DOT; @@ -300,7 +329,7 @@ __log_find(dbenv, lp, valp) } /* Get the list of file names. */ - ret = __db_dir(dbenv, dir, &names, &fcnt); + ret = __db_dir(dblp->dbenv, dir, &names, &fcnt); FREES(p); if (ret != 0) return (ret); @@ -314,14 +343,14 @@ __log_find(dbenv, lp, valp) if (strncmp(names[cnt], "log.", sizeof("log.") - 1) == 0) { logval = atoi(names[cnt] + 4); if (logval != 0 && - __log_valid(dbenv, lp, logval) == 0) { + __log_valid(dblp, dblp->lp, logval) == 0) { *valp = logval; break; } } /* Discard the list. */ - __db_dirf(dbenv, names, fcnt); + __db_dirf(dblp->dbenv, names, fcnt); return (ret); } @@ -330,11 +359,11 @@ __log_find(dbenv, lp, valp) * log_valid -- * Validate a log file. * - * PUBLIC: int __log_valid __P((DB_ENV *, LOG *, int)); + * PUBLIC: int __log_valid __P((DB_LOG *, LOG *, int)); */ int -__log_valid(dbenv, lp, cnt) - DB_ENV *dbenv; +__log_valid(dblp, lp, cnt) + DB_LOG *dblp; LOG *lp; int cnt; { @@ -343,7 +372,7 @@ __log_valid(dbenv, lp, cnt) int fd, ret; char *p; - if ((ret = __log_name(dbenv, cnt, &p)) != 0) + if ((ret = __log_name(dblp, cnt, &p)) != 0) return (ret); fd = -1; @@ -357,7 +386,7 @@ __log_valid(dbenv, lp, cnt) ret = EIO; if (fd != -1) { (void)__db_close(fd); - __db_err(dbenv, + __db_err(dblp->dbenv, "Ignoring log file: %s: %s", p, strerror(ret)); } goto err; @@ -365,14 +394,14 @@ __log_valid(dbenv, lp, cnt) (void)__db_close(fd); if (persist.magic != DB_LOGMAGIC) { - __db_err(dbenv, + __db_err(dblp->dbenv, "Ignoring log file: %s: magic number %lx, not %lx", p, (u_long)persist.magic, (u_long)DB_LOGMAGIC); ret = EINVAL; goto err; } if (persist.version < DB_LOGOLDVER || persist.version > DB_LOGVERSION) { - __db_err(dbenv, + __db_err(dblp->dbenv, "Ignoring log file: %s: unsupported log version %lu", p, (u_long)persist.version); ret = EINVAL; @@ -401,6 +430,13 @@ log_close(dblp) ret = 0; + /* Discard the per-thread pointer. */ + if (dblp->mutexp != NULL) { + LOCK_LOGREGION(dblp); + __db_shalloc_free(dblp->addr, dblp->mutexp); + UNLOCK_LOGREGION(dblp); + } + /* Close the region. */ if ((t_ret = __db_rclose(dblp->dbenv, dblp->fd, dblp->maddr)) != 0 && ret == 0) @@ -414,10 +450,12 @@ log_close(dblp) if (dblp->c_fd != -1 && (t_ret = __db_close(dblp->c_fd)) != 0 && ret == 0) ret = t_ret; - - /* Free the structure. */ if (dblp->dbentry != NULL) FREE(dblp->dbentry, (dblp->dbentry_cnt * sizeof(DB_ENTRY))); + if (dblp->dir != NULL) + FREES(dblp->dir); + + /* Free the structure. */ FREE(dblp, sizeof(DB_LOG)); return (ret); diff --git a/db2/log/log_archive.c b/db2/log/log_archive.c index 0d6c3f2bea..6904a2c726 100644 --- a/db2/log/log_archive.c +++ b/db2/log/log_archive.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)log_archive.c 10.23 (Sleepycat) 8/23/97"; +static const char sccsid[] = "@(#)log_archive.c 10.26 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -27,18 +27,18 @@ static const char sccsid[] = "@(#)log_archive.c 10.23 (Sleepycat) 8/23/97"; #include "clib_ext.h" #include "common_ext.h" -static int absname __P((char *, char *, char **)); -static int build_data __P((DB_LOG *, char *, char ***, void *(*)(size_t))); -static int cmpfunc __P((const void *, const void *)); -static int usermem __P((char ***, void *(*)(size_t))); +static int __absname __P((char *, char *, char **)); +static int __build_data __P((DB_LOG *, char *, char ***, void *(*)(size_t))); +static int __cmpfunc __P((const void *, const void *)); +static int __usermem __P((char ***, void *(*)(size_t))); /* * log_archive -- * Supporting function for db_archive(1). */ int -log_archive(logp, listp, flags, db_malloc) - DB_LOG *logp; +log_archive(dblp, listp, flags, db_malloc) + DB_LOG *dblp; char ***listp; int flags; void *(*db_malloc) __P((size_t)); @@ -54,10 +54,10 @@ log_archive(logp, listp, flags, db_malloc) #define OKFLAGS (DB_ARCH_ABS | DB_ARCH_DATA | DB_ARCH_LOG) if (flags != 0) { if ((ret = - __db_fchk(logp->dbenv, "log_archive", flags, OKFLAGS)) != 0) + __db_fchk(dblp->dbenv, "log_archive", flags, OKFLAGS)) != 0) return (ret); if ((ret = - __db_fcchk(logp->dbenv, + __db_fcchk(dblp->dbenv, "log_archive", flags, DB_ARCH_DATA, DB_ARCH_LOG)) != 0) return (ret); } @@ -68,7 +68,7 @@ log_archive(logp, listp, flags, db_malloc) * but that's just not possible. */ if (LF_ISSET(DB_ARCH_ABS)) { - __set_errno(0); + __set_errno (0); if ((pref = getcwd(buf, sizeof(buf))) == NULL) return (errno == 0 ? ENOMEM : errno); } else @@ -76,19 +76,19 @@ log_archive(logp, listp, flags, db_malloc) switch (LF_ISSET(~DB_ARCH_ABS)) { case DB_ARCH_DATA: - return (build_data(logp, pref, listp, db_malloc)); + return (__build_data(dblp, pref, listp, db_malloc)); case DB_ARCH_LOG: memset(&rec, 0, sizeof(rec)); - if (F_ISSET(logp, DB_AM_THREAD)) + if (F_ISSET(dblp, DB_AM_THREAD)) F_SET(&rec, DB_DBT_MALLOC); - if ((ret = log_get(logp, &stable_lsn, &rec, DB_LAST)) != 0) + if ((ret = log_get(dblp, &stable_lsn, &rec, DB_LAST)) != 0) return (ret); - if (F_ISSET(logp, DB_AM_THREAD)) + if (F_ISSET(dblp, DB_AM_THREAD)) free(rec.data); fnum = stable_lsn.file; break; case 0: - if ((ret = __log_findckp(logp, &stable_lsn)) != 0) { + if ((ret = __log_findckp(dblp, &stable_lsn)) != 0) { if (ret != DB_NOTFOUND) return (ret); *listp = NULL; @@ -108,7 +108,7 @@ log_archive(logp, listp, flags, db_malloc) /* Build an array of the file names. */ for (n = 0; fnum > 0; --fnum) { - if ((ret = __log_name(logp->dbenv, fnum, &name)) != 0) + if ((ret = __log_name(dblp, fnum, &name)) != 0) goto err; if (__db_exists(name, NULL) != 0) break; @@ -123,7 +123,7 @@ log_archive(logp, listp, flags, db_malloc) } if (LF_ISSET(DB_ARCH_ABS)) { - if ((ret = absname(pref, name, &array[n])) != 0) + if ((ret = __absname(pref, name, &array[n])) != 0) goto err; FREES(name); } else if ((p = __db_rpath(name)) != NULL) { @@ -146,10 +146,10 @@ log_archive(logp, listp, flags, db_malloc) } /* Sort the list. */ - qsort(array, (size_t)n, sizeof(char *), cmpfunc); + qsort(array, (size_t)n, sizeof(char *), __cmpfunc); /* Rework the memory. */ - if ((ret = usermem(&array, db_malloc)) != 0) + if ((ret = __usermem(&array, db_malloc)) != 0) goto err; *listp = array; @@ -164,12 +164,12 @@ err: if (array != NULL) { } /* - * build_data -- + * __build_data -- * Build a list of datafiles for return. */ static int -build_data(logp, pref, listp, db_malloc) - DB_LOG *logp; +__build_data(dblp, pref, listp, db_malloc) + DB_LOG *dblp; char *pref, ***listp; void *(*db_malloc) __P((size_t)); { @@ -187,19 +187,19 @@ build_data(logp, pref, listp, db_malloc) array[0] = NULL; memset(&rec, 0, sizeof(rec)); - if (F_ISSET(logp, DB_AM_THREAD)) + if (F_ISSET(dblp, DB_AM_THREAD)) F_SET(&rec, DB_DBT_MALLOC); - for (n = 0, ret = log_get(logp, &lsn, &rec, DB_FIRST); - ret == 0; ret = log_get(logp, &lsn, &rec, DB_NEXT)) { + for (n = 0, ret = log_get(dblp, &lsn, &rec, DB_FIRST); + ret == 0; ret = log_get(dblp, &lsn, &rec, DB_NEXT)) { if (rec.size < sizeof(rectype)) { ret = EINVAL; - __db_err(logp->dbenv, "log_archive: bad log record"); + __db_err(dblp->dbenv, "log_archive: bad log record"); goto lg_free; } memcpy(&rectype, rec.data, sizeof(rectype)); if (rectype != DB_log_register) { - if (F_ISSET(logp, DB_AM_THREAD)) { + if (F_ISSET(dblp, DB_AM_THREAD)) { free(rec.data); rec.data = NULL; } @@ -207,7 +207,7 @@ build_data(logp, pref, listp, db_malloc) } if ((ret = __log_register_read(rec.data, &argp)) != 0) { ret = EINVAL; - __db_err(logp->dbenv, + __db_err(dblp->dbenv, "log_archive: unable to read log record"); goto lg_free; } @@ -231,7 +231,7 @@ lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL) array[++n] = NULL; free(argp); - if (F_ISSET(logp, DB_AM_THREAD)) { + if (F_ISSET(dblp, DB_AM_THREAD)) { free(rec.data); rec.data = NULL; } @@ -245,7 +245,7 @@ lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL) } /* Sort the list. */ - qsort(array, (size_t)n, sizeof(char *), cmpfunc); + qsort(array, (size_t)n, sizeof(char *), __cmpfunc); /* * Build the real pathnames, discarding nonexistent files and @@ -268,7 +268,7 @@ lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL) } /* Get the real name. */ - if ((ret = __db_appname(logp->dbenv, + if ((ret = __db_appname(dblp->dbenv, DB_APP_DATA, NULL, array[last], NULL, &real_name)) != 0) goto err2; @@ -284,7 +284,7 @@ lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL) FREES(array[last]); array[last] = NULL; if (pref != NULL) { - ret = absname(pref, real_name, &array[last]); + ret = __absname(pref, real_name, &array[last]); FREES(real_name); if (ret != 0) goto err2; @@ -302,7 +302,7 @@ lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL) array[last] = NULL; /* Rework the memory. */ - if ((ret = usermem(&array, db_malloc)) != 0) + if ((ret = __usermem(&array, db_malloc)) != 0) goto err1; *listp = array; @@ -327,11 +327,11 @@ err1: if (array != NULL) { } /* - * absname -- + * __absname -- * Return an absolute path name for the file. */ static int -absname(pref, name, newnamep) +__absname(pref, name, newnamep) char *pref, *name, **newnamep; { size_t l_pref, l_name; @@ -355,12 +355,12 @@ absname(pref, name, newnamep) } /* - * usermem -- + * __usermem -- * Create a single chunk of memory that holds the returned information. * If the user has their own malloc routine, use it. */ static int -usermem(listp, func) +__usermem(listp, func) char ***listp; void *(*func) __P((size_t)); { @@ -406,7 +406,7 @@ usermem(listp, func) } static int -cmpfunc(p1, p2) +__cmpfunc(p1, p2) const void *p1, *p2; { return (strcmp(*((char **)p1), *((char **)p2))); diff --git a/db2/log/log_auto.c b/db2/log/log_auto.c index 59400087ca..ea88a7bff9 100644 --- a/db2/log/log_auto.c +++ b/db2/log/log_auto.c @@ -121,7 +121,7 @@ __log_register_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __log_register_read(dbtp->data, &argp)) != 0) + if ((ret = __log_register_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]log_register: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -269,7 +269,7 @@ __log_unregister_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __log_unregister_read(dbtp->data, &argp)) != 0) + if ((ret = __log_unregister_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]log_unregister: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, diff --git a/db2/log/log_get.c b/db2/log/log_get.c index 54a58c75fc..3f6df6c33c 100644 --- a/db2/log/log_get.c +++ b/db2/log/log_get.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)log_get.c 10.17 (Sleepycat) 8/27/97"; +static const char sccsid[] = "@(#)log_get.c 10.19 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -145,7 +145,7 @@ __log_get(dblp, alsn, dbt, flags, silent) * Find any log file. Note, we may have only entered records * in the buffer, and not yet written a log file. */ - if ((ret = __log_find(dblp->dbenv, lp, &cnt)) != 0) { + if ((ret = __log_find(dblp, &cnt)) != 0) { __db_err(dblp->dbenv, "log_get: unable to find the first record: no log files found."); goto err2; @@ -157,7 +157,7 @@ __log_get(dblp, alsn, dbt, flags, silent) /* Now go backwards to find the smallest one. */ for (; cnt > 1; --cnt) - if (__log_valid(dblp->dbenv, NULL, cnt) != 0) { + if (__log_valid(dblp, NULL, cnt) != 0) { ++cnt; break; } @@ -223,7 +223,7 @@ retry: * Acquire a file descriptor. */ if (dblp->c_fd == -1) { - if ((ret = __log_name(dblp->dbenv, nlsn.file, &np)) != 0) + if ((ret = __log_name(dblp, nlsn.file, &np)) != 0) goto err1; if ((ret = __db_fdopen(np, DB_RDONLY | DB_SEQUENTIAL, DB_RDONLY | DB_SEQUENTIAL, 0, &dblp->c_fd)) != 0) { @@ -319,6 +319,7 @@ retry: &dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0) goto err1; free(tbuf); + tbuf = NULL; cksum: if (hdr.cksum != __ham_func4(dbt->data, dbt->size)) { if (!silent) diff --git a/db2/log/log_put.c b/db2/log/log_put.c index db31f9b0e1..225595f33e 100644 --- a/db2/log/log_put.c +++ b/db2/log/log_put.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)log_put.c 10.12 (Sleepycat) 8/20/97"; +static const char sccsid[] = "@(#)log_put.c 10.14 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -416,7 +416,7 @@ log_file(dblp, lsn, namep, len) LOCK_LOGREGION(dblp); - ret = __log_name(dblp->dbenv, lsn->file, &p); + ret = __log_name(dblp, lsn->file, &p); UNLOCK_LOGREGION(dblp); @@ -453,14 +453,14 @@ __log_newfd(dblp) /* Get the path of the new file and open it. */ dblp->lfname = dblp->lp->lsn.file; - if ((ret = __log_name(dblp->dbenv, dblp->lfname, &p)) != 0) + if ((ret = __log_name(dblp, dblp->lfname, &p)) != 0) return (ret); if ((ret = __db_fdopen(p, DB_CREATE | DB_SEQUENTIAL, DB_CREATE | DB_SEQUENTIAL, dblp->lp->persist.mode, &dblp->lfd)) != 0) __db_err(dblp->dbenv, - "log_put: %s: %s", p, strerror(errno)); + "log_put: %s: %s", p, strerror(ret)); FREES(p); return (ret); } @@ -469,16 +469,17 @@ __log_newfd(dblp) * __log_name -- * Return the log name for a particular file. * - * PUBLIC: int __log_name __P((DB_ENV *, int, char **)); + * PUBLIC: int __log_name __P((DB_LOG *, int, char **)); */ int -__log_name(dbenv, fn, np) - DB_ENV *dbenv; - int fn; - char **np; +__log_name(dblp, fileno, namep) + DB_LOG *dblp; + char **namep; + int fileno; { char name[sizeof(LFNAME) + 10]; - (void)snprintf(name, sizeof(name), LFNAME, fn); - return (__db_appname(dbenv, DB_APP_LOG, NULL, name, NULL, np)); + (void)snprintf(name, sizeof(name), LFNAME, fileno); + return (__db_appname(dblp->dbenv, + DB_APP_LOG, dblp->dir, name, NULL, namep)); } diff --git a/db2/log/log_register.c b/db2/log/log_register.c index 582eab9408..859b1e5bcb 100644 --- a/db2/log/log_register.c +++ b/db2/log/log_register.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)log_register.c 10.10 (Sleepycat) 8/20/97"; +static const char sccsid[] = "@(#)log_register.c 10.11 (Sleepycat) 9/15/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -190,8 +190,13 @@ log_unregister(dblp, fid) SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname); __db_shalloc_free(dblp->addr, fnp); - /* Remove from the process local table. */ - __log_rem_logid(dblp, fid); + /* + * Remove from the process local table. If this operation is taking + * place during recovery, then the logid was never added to the table, + * so do not remove it. + */ + if (!F_ISSET(dblp, DB_AM_RECOVER)) + __log_rem_logid(dblp, fid); ret1: UNLOCK_LOGREGION(dblp); diff --git a/db2/mp/mp_bh.c b/db2/mp/mp_bh.c index 3d0d053b5f..fb6bc96ae7 100644 --- a/db2/mp/mp_bh.c +++ b/db2/mp/mp_bh.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)mp_bh.c 10.15 (Sleepycat) 8/29/97"; +static const char sccsid[] = "@(#)mp_bh.c 10.16 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -55,7 +55,7 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep) * If we find a descriptor on the file that's not open for writing, we * try and upgrade it to make it writeable. */ - LOCKHANDLE(dbmp, &dbmp->mutex); + LOCKHANDLE(dbmp, dbmp->mutexp); for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq); dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q)) if (dbmfp->mfp == mfp) { @@ -64,7 +64,7 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep) return (0); break; } - UNLOCKHANDLE(dbmp, &dbmp->mutex); + UNLOCKHANDLE(dbmp, dbmp->mutexp); if (dbmfp != NULL) goto found; @@ -75,12 +75,12 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep) * nothing we can do. */ if (mfp->ftype != 0) { - LOCKHANDLE(dbmp, &dbmp->mutex); + LOCKHANDLE(dbmp, dbmp->mutexp); for (mpreg = LIST_FIRST(&dbmp->dbregq); mpreg != NULL; mpreg = LIST_NEXT(mpreg, q)) if (mpreg->ftype == mfp->ftype) break; - UNLOCKHANDLE(dbmp, &dbmp->mutex); + UNLOCKHANDLE(dbmp, dbmp->mutexp); if (mpreg == NULL) return (0); } @@ -135,19 +135,19 @@ __memp_pgread(dbmfp, bhp, can_create) * Seek to the page location. */ ret = 0; - LOCKHANDLE(dbmp, &dbmfp->mutex); + LOCKHANDLE(dbmp, dbmfp->mutexp); if (dbmfp->fd == -1 || (ret = __db_lseek(dbmfp->fd, pagesize, bhp->pgno, 0, SEEK_SET)) != 0) { if (!can_create) { if (dbmfp->fd == -1) ret = EINVAL; - UNLOCKHANDLE(dbmp, &dbmfp->mutex); + UNLOCKHANDLE(dbmp, dbmfp->mutexp); __db_err(dbmp->dbenv, "%s: page %lu doesn't exist, create flag not set", dbmfp->path, (u_long)bhp->pgno); goto err; } - UNLOCKHANDLE(dbmp, &dbmfp->mutex); + UNLOCKHANDLE(dbmp, dbmfp->mutexp); /* Clear any uninitialized data. */ memset(bhp->buf, 0, pagesize); @@ -159,7 +159,7 @@ __memp_pgread(dbmfp, bhp, can_create) * any valid data is preserved. */ ret = __db_read(dbmfp->fd, bhp->buf, pagesize, &nr); - UNLOCKHANDLE(dbmp, &dbmfp->mutex); + UNLOCKHANDLE(dbmp, dbmfp->mutexp); if (ret != 0) goto err; @@ -268,10 +268,10 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep) } /* Temporary files may not yet have been created. */ - LOCKHANDLE(dbmp, &dbmfp->mutex); + LOCKHANDLE(dbmp, dbmfp->mutexp); if (dbmfp->fd == -1 && ((ret = __db_appname(dbenv, DB_APP_TMP, NULL, NULL, &dbmfp->fd, NULL)) != 0 || dbmfp->fd == -1)) { - UNLOCKHANDLE(dbmp, &dbmfp->mutex); + UNLOCKHANDLE(dbmp, dbmfp->mutexp); __db_err(dbenv, "unable to create temporary backing file"); goto err; } @@ -282,7 +282,7 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep) fail = "seek"; else if ((ret = __db_write(dbmfp->fd, bhp->buf, pagesize, &nw)) != 0) fail = "write"; - UNLOCKHANDLE(dbmp, &dbmfp->mutex); + UNLOCKHANDLE(dbmp, dbmfp->mutexp); if (ret != 0) { /* * XXX @@ -380,7 +380,7 @@ __memp_pg(dbmfp, bhp, is_pgin) dbmp = dbmfp->dbmp; mfp = dbmfp->mfp; - LOCKHANDLE(dbmp, &dbmp->mutex); + LOCKHANDLE(dbmp, dbmp->mutexp); ftype = mfp->ftype; for (mpreg = LIST_FIRST(&dbmp->dbregq); @@ -394,7 +394,7 @@ __memp_pg(dbmfp, bhp, is_pgin) dbt.data = ADDR(dbmp, mfp->pgcookie_off); dbtp = &dbt; } - UNLOCKHANDLE(dbmp, &dbmp->mutex); + UNLOCKHANDLE(dbmp, dbmp->mutexp); if (is_pgin) { if (mpreg->pgin != NULL && (ret = @@ -408,11 +408,11 @@ __memp_pg(dbmfp, bhp, is_pgin) } if (mpreg == NULL) - UNLOCKHANDLE(dbmp, &dbmp->mutex); + UNLOCKHANDLE(dbmp, dbmp->mutexp); return (0); -err: UNLOCKHANDLE(dbmp, &dbmp->mutex); +err: UNLOCKHANDLE(dbmp, dbmp->mutexp); __db_err(dbmp->dbenv, "%s: %s failed for page %lu", dbmfp->path, is_pgin ? "pgin" : "pgout", (u_long)bhp->pgno); return (ret); diff --git a/db2/mp/mp_fget.c b/db2/mp/mp_fget.c index 418802a3b9..a0364e92c3 100644 --- a/db2/mp/mp_fget.c +++ b/db2/mp/mp_fget.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)mp_fget.c 10.22 (Sleepycat) 8/19/97"; +static const char sccsid[] = "@(#)mp_fget.c 10.25 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -35,7 +35,7 @@ int memp_fget(dbmfp, pgnoaddr, flags, addrp) DB_MPOOLFILE *dbmfp; db_pgno_t *pgnoaddr; - u_long flags; + int flags; void *addrp; { BH *bhp, *tbhp; @@ -293,7 +293,7 @@ found: /* Increment the reference count. */ __db_err(dbmp->dbenv, "%s: too many references to page %lu", dbmfp->path, bhp->pgno); - ret = EAGAIN; + ret = EINVAL; goto err; } ++bhp->ref; @@ -337,9 +337,9 @@ found: /* Increment the reference count. */ ++mfp->stat.st_cache_hit; } -mapret: LOCKHANDLE(dbmp, &dbmfp->mutex); +mapret: LOCKHANDLE(dbmp, dbmfp->mutexp); ++dbmfp->pinref; - UNLOCKHANDLE(dbmp, &dbmfp->mutex); + UNLOCKHANDLE(dbmp, dbmfp->mutexp); if (0) { err: /* diff --git a/db2/mp/mp_fopen.c b/db2/mp/mp_fopen.c index 1a770bfdf0..5ab807701c 100644 --- a/db2/mp/mp_fopen.c +++ b/db2/mp/mp_fopen.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)mp_fopen.c 10.25 (Sleepycat) 8/27/97"; +static const char sccsid[] = "@(#)mp_fopen.c 10.27 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -28,8 +28,8 @@ static const char sccsid[] = "@(#)mp_fopen.c 10.25 (Sleepycat) 8/27/97"; #include "common_ext.h" static int __memp_mf_close __P((DB_MPOOL *, DB_MPOOLFILE *)); -static int __memp_mf_open __P((DB_MPOOL *, DB_MPOOLFILE *, - int, int, size_t, int, DBT *, u_int8_t *, int, MPOOLFILE **)); +static int __memp_mf_open __P((DB_MPOOL *, + DB_MPOOLFILE *, int, size_t, int, DBT *, u_int8_t *, int, MPOOLFILE **)); /* * memp_fopen -- @@ -97,7 +97,6 @@ __memp_fopen(dbmp, path, path == NULL ? TEMPORARY : path, strerror(ENOMEM)); return (ENOMEM); } - LOCKINIT(dbmp, &dbmfp->mutex); dbmfp->dbmp = dbmp; dbmfp->fd = -1; if (LF_ISSET(DB_RDONLY)) @@ -141,14 +140,21 @@ __memp_fopen(dbmp, path, } } - /* Find/allocate the shared file object. */ + /* + * Find/allocate the shared file objects. This includes allocating + * space for the per-process thread lock. + */ if (needlock) LOCKREGION(dbmp); - ret = __memp_mf_open(dbmp, dbmfp, ftype, - F_ISSET(dbmfp, MP_READONLY), pagesize, + ret = __memp_mf_open(dbmp, dbmfp, ftype, pagesize, lsn_offset, pgcookie, fileid, F_ISSET(dbmfp, MP_PATH_TEMP), &mfp); + if (ret == 0 && + F_ISSET(dbmp, MP_LOCKHANDLE) && (ret = + __memp_ralloc(dbmp, sizeof(db_mutex_t), NULL, &dbmfp->mutexp)) == 0) + LOCKINIT(dbmp, dbmfp->mutexp); if (needlock) UNLOCKREGION(dbmp); + if (ret != 0) goto err; @@ -156,11 +162,11 @@ __memp_fopen(dbmp, path, /* * If a file: - * * + is read-only + * + isn't temporary * + doesn't require any pgin/pgout support - * + is less than mp_mmapsize bytes in size. - * + and the DB_NOMMAP flag wasn't set + * + the DB_NOMMAP flag wasn't set + * + and is less than mp_mmapsize bytes in size * * we can mmap it instead of reading/writing buffers. Don't do error * checking based on the mmap call failure. We want to do normal I/O @@ -176,11 +182,20 @@ __memp_fopen(dbmp, path, * flatly impossible. Hope that mmap fails if the file is too large. */ #define DB_MAXMMAPSIZE (10 * 1024 * 1024) /* 10 Mb. */ + if (mfp->can_mmap) { + if (!F_ISSET(dbmfp, MP_READONLY)) + mfp->can_mmap = 0; + if (path == NULL) + mfp->can_mmap = 0; + if (ftype != 0) + mfp->can_mmap = 0; + if (LF_ISSET(DB_NOMMAP)) + mfp->can_mmap = 0; + if (size > (dbenv == NULL || dbenv->mp_mmapsize == 0 ? + DB_MAXMMAPSIZE : (off_t)dbenv->mp_mmapsize)) + mfp->can_mmap = 0; + } dbmfp->addr = NULL; - mfp->can_mmap = F_ISSET(dbmfp, MP_READONLY) && - ftype == 0 && !LF_ISSET(DB_NOMMAP) && path != NULL && - size <= (dbenv == NULL || dbenv->mp_mmapsize == 0 ? - DB_MAXMMAPSIZE : (off_t)dbenv->mp_mmapsize); if (mfp->can_mmap) { dbmfp->len = size; if (__db_mmap(dbmfp->fd, dbmfp->len, 1, 1, &dbmfp->addr) != 0) { @@ -189,14 +204,18 @@ __memp_fopen(dbmp, path, } } - LOCKHANDLE(dbmp, &dbmp->mutex); + LOCKHANDLE(dbmp, dbmp->mutexp); TAILQ_INSERT_TAIL(&dbmp->dbmfq, dbmfp, q); - UNLOCKHANDLE(dbmp, &dbmp->mutex); + UNLOCKHANDLE(dbmp, dbmp->mutexp); *retp = dbmfp; return (0); -err: if (F_ISSET(dbmfp, MP_PATH_ALLOC)) +err: /* + * Note that we do not have to free the thread mutex, because we + * never get to here after we have successfully allocated it. + */ + if (F_ISSET(dbmfp, MP_PATH_ALLOC)) FREES(dbmfp->path); if (dbmfp->fd != -1) (void)__db_close(dbmfp->fd); @@ -211,10 +230,10 @@ err: if (F_ISSET(dbmfp, MP_PATH_ALLOC)) */ static int __memp_mf_open(dbmp, dbmfp, - ftype, readonly, pagesize, lsn_offset, pgcookie, fileid, istemp, retp) + ftype, pagesize, lsn_offset, pgcookie, fileid, istemp, retp) DB_MPOOL *dbmp; DB_MPOOLFILE *dbmfp; - int ftype, readonly, lsn_offset, istemp; + int ftype, lsn_offset, istemp; size_t pagesize; DBT *pgcookie; u_int8_t *fileid; @@ -255,13 +274,8 @@ __memp_mf_open(dbmp, dbmfp, mfp = NULL; goto ret1; } - /* - * Found it: increment the reference count and update - * the mmap-able status. - */ + /* Found it: increment the reference count. */ ++mfp->ref; - if (!readonly) - mfp->can_mmap = 0; goto ret1; } @@ -273,6 +287,7 @@ alloc: if ((ret = __memp_ralloc(dbmp, sizeof(MPOOLFILE), NULL, &mfp)) != 0) memset(mfp, 0, sizeof(MPOOLFILE)); mfp->ref = 1; mfp->ftype = ftype; + mfp->can_mmap = 1; mfp->lsn_off = lsn_offset; mfp->stat.st_pagesize = pagesize; @@ -343,9 +358,9 @@ memp_fclose(dbmfp) dbmfp->path, (u_long)dbmfp->pinref); /* Remove the DB_MPOOLFILE structure from the list. */ - LOCKHANDLE(dbmp, &dbmp->mutex); + LOCKHANDLE(dbmp, dbmp->mutexp); TAILQ_REMOVE(&dbmp->dbmfq, dbmfp, q); - UNLOCKHANDLE(dbmp, &dbmp->mutex); + UNLOCKHANDLE(dbmp, dbmp->mutexp); /* Close the underlying MPOOLFILE. */ (void)__memp_mf_close(dbmp, dbmfp); @@ -362,11 +377,16 @@ memp_fclose(dbmfp) t_ret = ret; } - /* Potentially allocated path. */ + /* Free memory. */ if (F_ISSET(dbmfp, MP_PATH_ALLOC)) FREES(dbmfp->path); + if (dbmfp->mutexp != NULL) { + LOCKREGION(dbmp); + __db_shalloc_free(dbmp->addr, dbmfp->mutexp); + UNLOCKREGION(dbmp); + } - /* Free the DB_MPOOLFILE structure. */ + /* Discard the DB_MPOOLFILE structure. */ FREE(dbmfp, sizeof(DB_MPOOLFILE)); return (ret); diff --git a/db2/mp/mp_fput.c b/db2/mp/mp_fput.c index 5fac8ae76b..9ea7cd9d0d 100644 --- a/db2/mp/mp_fput.c +++ b/db2/mp/mp_fput.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)mp_fput.c 10.10 (Sleepycat) 7/20/97"; +static const char sccsid[] = "@(#)mp_fput.c 10.12 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -31,7 +31,7 @@ int memp_fput(dbmfp, pgaddr, flags) DB_MPOOLFILE *dbmfp; void *pgaddr; - u_long flags; + int flags; { BH *bhp; DB_MPOOL *dbmp; @@ -58,14 +58,14 @@ memp_fput(dbmfp, pgaddr, flags) } /* Decrement the pinned reference count. */ - LOCKHANDLE(dbmp, &dbmfp->mutex); + LOCKHANDLE(dbmp, dbmfp->mutexp); if (dbmfp->pinref == 0) __db_err(dbmp->dbenv, "%s: put: more blocks returned than retrieved", dbmfp->path); else --dbmfp->pinref; - UNLOCKHANDLE(dbmp, &dbmfp->mutex); + UNLOCKHANDLE(dbmp, dbmfp->mutexp); /* * If we're mapping the file, there's nothing to do. Because we can diff --git a/db2/mp/mp_fset.c b/db2/mp/mp_fset.c index 588085a358..a3a3dcef9c 100644 --- a/db2/mp/mp_fset.c +++ b/db2/mp/mp_fset.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)mp_fset.c 10.8 (Sleepycat) 8/19/97"; +static const char sccsid[] = "@(#)mp_fset.c 10.9 (Sleepycat) 9/20/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -30,7 +30,7 @@ int memp_fset(dbmfp, pgaddr, flags) DB_MPOOLFILE *dbmfp; void *pgaddr; - u_long flags; + int flags; { BH *bhp; DB_MPOOL *dbmp; diff --git a/db2/mp/mp_open.c b/db2/mp/mp_open.c index 257ce1b9e9..f622b1ed26 100644 --- a/db2/mp/mp_open.c +++ b/db2/mp/mp_open.c @@ -7,7 +7,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)mp_open.c 10.12 (Sleepycat) 7/6/97"; +static const char sccsid[] = "@(#)mp_open.c 10.13 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -56,7 +56,6 @@ memp_open(path, flags, mode, dbenv, retp) /* Create and initialize the DB_MPOOL structure. */ if ((dbmp = (DB_MPOOL *)calloc(1, sizeof(DB_MPOOL))) == NULL) return (ENOMEM); - LOCKINIT(dbmp, &dbmp->mutex); LIST_INIT(&dbmp->dbregq); TAILQ_INIT(&dbmp->dbmfq); @@ -68,6 +67,17 @@ memp_open(path, flags, mode, dbenv, retp) F_SET(dbmp, MP_ISPRIVATE); /* + * XXX + * HP-UX won't permit mutexes to live in anything but shared memory. + * So, we have to instantiate the shared mpool region file on that + * architecture, regardless. If this turns out to be a performance + * problem, we could probably use anonymous memory instead. + */ +#if defined(__hppa) + F_CLR(dbmp, MP_ISPRIVATE); +#endif + + /* * Map in the region. We do locking regardless, as portions of it are * implemented in common code (if we put the region in a file, that is). */ @@ -79,12 +89,22 @@ memp_open(path, flags, mode, dbenv, retp) /* * If there's concurrent access, then we have to lock the region. * If it's threaded, then we have to lock both the handles and the - * region. + * region, and we need to allocate a mutex for that purpose. */ if (!F_ISSET(dbmp, MP_ISPRIVATE)) F_SET(dbmp, MP_LOCKREGION); - if (LF_ISSET(DB_THREAD)) + if (LF_ISSET(DB_THREAD)) { F_SET(dbmp, MP_LOCKHANDLE | MP_LOCKREGION); + LOCKREGION(dbmp); + ret = __memp_ralloc(dbmp, + sizeof(db_mutex_t), NULL, &dbmp->mutexp); + UNLOCKREGION(dbmp); + if (ret != 0) { + (void)memp_close(dbmp); + goto err; + } + LOCKINIT(dbmp, dbmp->mutexp); + } *retp = dbmp; return (0); @@ -119,11 +139,18 @@ memp_close(dbmp) if ((t_ret = memp_fclose(dbmfp)) != 0 && ret == 0) ret = t_ret; + /* Discard thread mutex. */ + if (F_ISSET(dbmp, MP_LOCKHANDLE)) { + LOCKREGION(dbmp); + __db_shalloc_free(dbmp->addr, dbmp->mutexp); + UNLOCKREGION(dbmp); + } + /* Close the region. */ if ((t_ret = __memp_rclose(dbmp)) && ret == 0) ret = t_ret; - /* Free the structure. */ + /* Discard the structure. */ FREE(dbmp, sizeof(DB_MPOOL)); return (ret); @@ -168,9 +195,9 @@ memp_register(dbmp, ftype, pgin, pgout) * the most recent registry in the case of multiple entries, so * we don't have to check for multiple registries. */ - LOCKHANDLE(dbmp, &dbmp->mutex); + LOCKHANDLE(dbmp, dbmp->mutexp); LIST_INSERT_HEAD(&dbmp->dbregq, mpr, q); - UNLOCKHANDLE(dbmp, &dbmp->mutex); + UNLOCKHANDLE(dbmp, dbmp->mutexp); return (0); } diff --git a/db2/mutex/mutex.c b/db2/mutex/mutex.c index b23f738ad7..5315b2d3fe 100644 --- a/db2/mutex/mutex.c +++ b/db2/mutex/mutex.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)mutex.c 10.22 (Sleepycat) 8/21/97"; +static const char sccsid[] = "@(#)mutex.c 10.25 (Sleepycat) 9/23/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES diff --git a/db2/os/db_os_dir.c b/db2/os/db_os_dir.c index 6dabd62049..1206e3faa7 100644 --- a/db2/os/db_os_dir.c +++ b/db2/os/db_os_dir.c @@ -8,7 +8,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)db_os_dir.c 10.8 (Sleepycat) 8/27/97"; +static const char sccsid[] = "@(#)db_os_dir.c 10.10 (Sleepycat) 9/17/97"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -60,9 +60,11 @@ __db_dir(dbenv, dir, namesp, cntp) struct _finddata_t fdata; long dirhandle; int finished; + char filespec[MAX_PATH]; - if ((dirhandle = _findfirst(dir, &fdata)) == -1) { - __db_err(dbenv, "%s: %s", dir, strerror(errno)); + (void)snprintf(filespec, sizeof(filespec), "%s/*", dir); + if ((dirhandle = _findfirst(filespec, &fdata)) == -1) { + __db_err(dbenv, "%s: %s", filespec, strerror(errno)); return (errno); } diff --git a/db2/progs/db_checkpoint/db_checkpoint.c b/db2/progs/db_checkpoint/db_checkpoint.c index 4f9b79a7ba..b2a692bba9 100644 --- a/db2/progs/db_checkpoint/db_checkpoint.c +++ b/db2/progs/db_checkpoint/db_checkpoint.c @@ -11,7 +11,7 @@ static const char copyright[] = "@(#) Copyright (c) 1997\n\ Sleepycat Software Inc. All rights reserved.\n"; -static const char sccsid[] = "@(#)db_checkpoint.c 10.11 (Sleepycat) 8/27/97"; +static const char sccsid[] = "@(#)db_checkpoint.c 10.12 (Sleepycat) 9/4/97"; #endif #ifndef NO_SYSTEM_INCLUDES @@ -22,6 +22,7 @@ static const char sccsid[] = "@(#)db_checkpoint.c 10.11 (Sleepycat) 8/27/97"; #include <signal.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <time.h> #include <unistd.h> #endif @@ -59,7 +60,7 @@ main(argc, argv) DB_ENV *dbenv; time_t now; long kbytes, minutes, seconds; - int ch, rval, verbose; + int ch, eval, verbose; char *home, *logfile; home = logfile = NULL; @@ -110,7 +111,7 @@ main(argc, argv) * to wake up when a checkpoint is necessary. If we have a "kbytes" * field set, then we'll check every 30 seconds. */ - rval = 0; + eval = 0; seconds = kbytes != 0 ? 30 : minutes * 60; while (!interrupted) { (void)__db_sleep(seconds, 0); @@ -119,23 +120,25 @@ main(argc, argv) (void)time(&now); printf("checkpoint: %s", ctime(&now)); } - rval = txn_checkpoint(dbenv->tx_info, kbytes, minutes); - if (rval < 0) - break; + errno = txn_checkpoint(dbenv->tx_info, kbytes, minutes); - while (rval > 0) { + while (errno == DB_INCOMPLETE) { if (verbose) __db_err(dbenv, "checkpoint did not finish, retrying"); (void)__db_sleep(2, 0); - rval = txn_checkpoint(dbenv->tx_info, 0, 0); + errno = txn_checkpoint(dbenv->tx_info, 0, 0); } - if (rval < 0) + + if (errno != 0) { + eval = 1; + __db_err(dbenv, "checkpoint: %s", strerror(errno)); break; + } } if (logfile != NULL && logpid(logfile, 0)) - rval = 1; + eval = 1; if (interrupted) { (void)signal(interrupted, SIG_DFL); @@ -143,7 +146,7 @@ main(argc, argv) /* NOTREACHED */ } - return (db_appexit(dbenv) || rval ? 1 : 0); + return (db_appexit(dbenv) || eval ? 1 : 0); } /* diff --git a/db2/progs/db_deadlock/db_deadlock.c b/db2/progs/db_deadlock/db_deadlock.c index 09004f58b3..ec2b53dee7 100644 --- a/db2/progs/db_deadlock/db_deadlock.c +++ b/db2/progs/db_deadlock/db_deadlock.c @@ -11,7 +11,7 @@ static const char copyright[] = "@(#) Copyright (c) 1997\n\ Sleepycat Software Inc. All rights reserved.\n"; -static const char sccsid[] = "@(#)db_deadlock.c 10.14 (Sleepycat) 8/27/97"; +static const char sccsid[] = "@(#)db_deadlock.c 10.15 (Sleepycat) 9/4/97"; #endif #ifndef NO_SYSTEM_INCLUDES diff --git a/db2/progs/db_dump185/db_dump185.c b/db2/progs/db_dump185/db_dump185.c index 6e2d95bee0..5ec7673f1b 100644 --- a/db2/progs/db_dump185/db_dump185.c +++ b/db2/progs/db_dump185/db_dump185.c @@ -11,7 +11,7 @@ static const char copyright[] = "@(#) Copyright (c) 1997\n\ Sleepycat Software Inc. All rights reserved.\n"; -static const char sccsid[] = "@(#)db_dump185.c 10.7 (Sleepycat) 8/27/97"; +static const char sccsid[] = "@(#)db_dump185.c 10.8 (Sleepycat) 9/21/97"; #endif #ifndef NO_SYSTEM_INCLUDES @@ -192,7 +192,7 @@ main(argc, argv) if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_BTREE, NULL)) == NULL) { if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_HASH, NULL)) == NULL) - return (1); + err(1, "%s", argv[0]); db_185_hash(dbp, pflag); } else db_185_btree(dbp, pflag); diff --git a/db2/progs/db_load/db_load.c b/db2/progs/db_load/db_load.c index 6f69216777..a1ebfa8a11 100644 --- a/db2/progs/db_load/db_load.c +++ b/db2/progs/db_load/db_load.c @@ -11,7 +11,7 @@ static const char copyright[] = "@(#) Copyright (c) 1997\n\ Sleepycat Software Inc. All rights reserved.\n"; -static const char sccsid[] = "@(#)db_load.c 10.12 (Sleepycat) 8/28/97"; +static const char sccsid[] = "@(#)db_load.c 10.13 (Sleepycat) 9/15/97"; #endif #ifndef NO_SYSTEM_INCLUDES @@ -59,7 +59,7 @@ main(argc, argv) char **clist, **clp, *home; /* Allocate enough room for configuration arguments. */ - if ((clp = clist = calloc(argc + 1, sizeof(char *))) == NULL) + if ((clp = clist = (char **)calloc(argc + 1, sizeof(char *))) == NULL) err(1, NULL); home = NULL; diff --git a/db2/progs/db_recover/db_recover.c b/db2/progs/db_recover/db_recover.c index d17c4b0c76..55b9b49a79 100644 --- a/db2/progs/db_recover/db_recover.c +++ b/db2/progs/db_recover/db_recover.c @@ -11,7 +11,7 @@ static const char copyright[] = "@(#) Copyright (c) 1997\n\ Sleepycat Software Inc. All rights reserved.\n"; -static const char sccsid[] = "@(#)db_recover.c 10.14 (Sleepycat) 8/27/97"; +static const char sccsid[] = "@(#)db_recover.c 10.15 (Sleepycat) 9/21/97"; #endif #ifndef NO_SYSTEM_INCLUDES @@ -24,6 +24,7 @@ static const char sccsid[] = "@(#)db_recover.c 10.14 (Sleepycat) 8/27/97"; #endif #include "db_int.h" +#include "shqueue.h" #include "txn.h" #include "common_ext.h" #include "clib_ext.h" diff --git a/db2/txn/txn.c b/db2/txn/txn.c index cb700dc037..9a0d626c3e 100644 --- a/db2/txn/txn.c +++ b/db2/txn/txn.c @@ -43,16 +43,10 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)txn.c 10.24 (Sleepycat) 9/3/97"; +static const char sccsid[] = "@(#)txn.c 10.30 (Sleepycat) 9/23/97"; #endif /* not lint */ -/* - * This file contains the top level routines of the transaction library. - * It assumes that a lock manager and log manager that conform to the db_log(3) - * and db_lock(3) interfaces exist. - */ - #ifndef NO_SYSTEM_INCLUDES #include <sys/types.h> #include <sys/mman.h> @@ -87,10 +81,12 @@ static int __txn_undo __P((DB_TXN *)); static int __txn_validate_region __P((DB_TXNMGR *)); /* + * This file contains the top level routines of the transaction library. + * It assumes that a lock manager and log manager that conform to the db_log(3) + * and db_lock(3) interfaces exist. + * * Create and initialize a transaction region in shared memory. - * 0 means, success. - * +1 means that the db_create failed, so we did not create the region. - * -1 means that we got some sort of system error. + * Return 0 on success, errno on failure. */ static int __txn_create(dbenv, path, mode) @@ -99,9 +95,8 @@ __txn_create(dbenv, path, mode) u_int mode; { DB_TXNREGION *txn_region; - TXN_DETAIL *txnp; time_t now; - int fd, i, maxtxns, ret; + int fd, maxtxns, ret; maxtxns = dbenv->tx_max != 0 ? dbenv->tx_max : 1000; (void)time(&now); @@ -120,17 +115,12 @@ __txn_create(dbenv, path, mode) /* XXX If we ever do more types of locking and logging, this changes. */ txn_region->logtype = 0; txn_region->locktype = 0; - txn_region->free_txn = 0; txn_region->time_ckp = now; ZERO_LSN(txn_region->last_ckp); ZERO_LSN(txn_region->pending_ckp); - - for (txnp = &txn_region->table[0], i = 0; i < maxtxns; i++, txnp++) { - ZERO_LSN(txnp->begin_lsn); - txnp->status = TXN_UNALLOC; - txnp->txnid = i + 1; - } - txn_region->table[maxtxns - 1].txnid = TXN_INVALID; + SH_TAILQ_INIT(&txn_region->active_txn); + __db_shalloc_init((void *)&txn_region[1], + TXN_REGION_SIZE(maxtxns) - sizeof(DB_TXNREGION)); /* Unlock the region. */ (void)__db_mutex_unlock(&txn_region->hdr.lock, fd); @@ -140,7 +130,6 @@ __txn_create(dbenv, path, mode) (void)txn_unlink(path, 1 /* force */, dbenv); return (ret); } - return (0); } @@ -199,7 +188,7 @@ retry1: if ((ret = __db_ropen(dbenv, DB_APP_NONE, path, DEFAULT_TXN_FILE, /* Now, create the transaction manager structure and set its fields. */ if ((tmgrp = (DB_TXNMGR *)malloc(sizeof(DB_TXNMGR))) == NULL) { - __db_err(dbenv, "txn_open: %s", strerror(errno)); + __db_err(dbenv, "txn_open: %s", strerror(ENOMEM)); ret = ENOMEM; goto out; } @@ -211,9 +200,18 @@ retry1: if ((ret = __db_ropen(dbenv, DB_APP_NONE, path, DEFAULT_TXN_FILE, tmgrp->reg_size = txn_regionp->hdr.size; tmgrp->fd = fd; tmgrp->flags = LF_ISSET(DB_TXN_NOSYNC | DB_THREAD); + tmgrp->mem = &txn_regionp[1]; + tmgrp->mutexp = NULL; TAILQ_INIT(&tmgrp->txn_chain); - if (LF_ISSET(DB_THREAD)) - __db_mutex_init(&tmgrp->mutex, -1); + if (LF_ISSET(DB_THREAD)) { + LOCK_TXNREGION(tmgrp); + if ((ret = __db_shalloc(tmgrp->mem, sizeof(db_mutex_t), + MUTEX_ALIGNMENT, &tmgrp->mutexp)) == 0) + __db_mutex_init(tmgrp->mutexp, -1); + UNLOCK_TXNREGION(tmgrp); + if (ret != 0) + goto out; + } *mgrpp = tmgrp; return (0); @@ -221,8 +219,14 @@ out: if (txn_regionp != NULL) (void)__db_rclose(dbenv, fd, txn_regionp); if (flags & DB_CREATE) (void)txn_unlink(path, 1, dbenv); - if (tmgrp != NULL) + if (tmgrp != NULL) { + if (tmgrp->mutexp != NULL) { + LOCK_TXNREGION(tmgrp); + __db_shalloc_free(tmgrp->mem, tmgrp->mutexp); + UNLOCK_TXNREGION(tmgrp); + } free(tmgrp); + } return (ret); } @@ -239,30 +243,20 @@ txn_begin(tmgrp, parent, txnpp) { TXN_DETAIL *txnp; DB_TXN *retp; - int id, index, ret; + int id, ret; LOCK_TXNREGION(tmgrp); - if ((ret = __txn_validate_region(tmgrp)) != 0) { - UNLOCK_TXNREGION(tmgrp); - return (ret); - } - - /* Remove element from free list. */ - if (tmgrp->region->free_txn == TXN_INVALID && - (ret = __txn_grow_region(tmgrp)) != 0) { - UNLOCK_TXNREGION(tmgrp); - return (ret); - } - - index = tmgrp->region->free_txn; - txnp = &tmgrp->region->table[index]; - tmgrp->region->free_txn = txnp->txnid; + if ((ret = __txn_validate_region(tmgrp)) != 0) + goto err; - if (txnp->status != TXN_UNALLOC) { - UNLOCK_TXNREGION(tmgrp); - return (EINVAL); - } + /* Allocate a new transaction detail structure. */ + if ((ret = __db_shalloc(tmgrp->mem, sizeof(TXN_DETAIL), 0, &txnp)) != 0 + && ret == ENOMEM && (ret = __txn_grow_region(tmgrp)) == 0) + ret = __db_shalloc(tmgrp->mem, sizeof(TXN_DETAIL), 0, &txnp); + + if (ret != 0) + goto err; /* Make sure that last_txnid is not going to wrap around. */ if (tmgrp->region->last_txnid == TXN_INVALID) @@ -270,18 +264,20 @@ txn_begin(tmgrp, parent, txnpp) if ((retp = (DB_TXN *)malloc(sizeof(DB_TXN))) == NULL) { __db_err(tmgrp->dbenv, "txn_begin : %s", strerror(ENOMEM)); - UNLOCK_TXNREGION(tmgrp); - return (ENOMEM); + ret = ENOMEM; + goto err1; } id = ++tmgrp->region->last_txnid; tmgrp->region->nbegins++; txnp->txnid = id; - txnp->last_lock = 0; - txnp->status = TXN_RUNNING; ZERO_LSN(txnp->last_lsn); ZERO_LSN(txnp->begin_lsn); + txnp->last_lock = 0; + txnp->status = TXN_RUNNING; + SH_TAILQ_INSERT_HEAD(&tmgrp->region->active_txn, + txnp, links, __txn_detail); UNLOCK_TXNREGION(tmgrp); @@ -297,8 +293,9 @@ txn_begin(tmgrp, parent, txnpp) /* Deallocate transaction. */ LOCK_TXNREGION(tmgrp); - txnp->txnid = tmgrp->region->free_txn; - tmgrp->region->free_txn = txnp - &tmgrp->region->table[0]; + SH_TAILQ_REMOVE(&tmgrp->region->active_txn, + txnp, links, __txn_detail); + __db_shalloc_free(tmgrp->mem, txnp); UNLOCK_TXNREGION(tmgrp); free (retp); return (ret); @@ -310,6 +307,12 @@ txn_begin(tmgrp, parent, txnpp) *txnpp = retp; return (0); + +err1: + __db_shalloc_free(tmgrp->mem, txnp); +err: + UNLOCK_TXNREGION(tmgrp); + return (ret); } /* The db_txn(3) man page describes txn_commit. */ @@ -362,16 +365,15 @@ txn_prepare(txnp) int ret; TXN_DETAIL *tp; - ret = 0; if ((ret = __txn_check_running(txnp)) != 0) return (ret); - if (txnp->mgrp->dbenv->lg_info) { - ret = log_flush(txnp->mgrp->dbenv->lg_info, &txnp->last_lsn); - if (ret) + if (txnp->mgrp->dbenv->lg_info != NULL) { + if ((ret = log_flush(txnp->mgrp->dbenv->lg_info, + &txnp->last_lsn)) != 0) __db_err(txnp->mgrp->dbenv, "txn_prepare: log_flush failed %s\n", - strerror(errno)); + strerror(ret)); return (ret); } @@ -420,12 +422,19 @@ txn_close(tmgrp) ret == 0) ret = t_ret; + if (tmgrp->mutexp != NULL) { + LOCK_TXNREGION(tmgrp); + __db_shalloc_free(tmgrp->mem, tmgrp->mutexp); + UNLOCK_TXNREGION(tmgrp); + } + if ((t_ret = __db_rclose(tmgrp->dbenv, tmgrp->fd, tmgrp->region)) != 0 && ret == 0) ret = t_ret; if (ret == 0) free (tmgrp); + return (ret); } @@ -499,9 +508,8 @@ __txn_end(txnp, is_commit) /* End the transaction. */ LOCK_TXNREGION(mgr); tp = (TXN_DETAIL *)((u_int8_t *)mgr->region + txnp->off); - tp->status = TXN_UNALLOC; - tp->txnid = mgr->region->free_txn; - mgr->region->free_txn = tp - &mgr->region->table[0]; + SH_TAILQ_REMOVE(&mgr->region->active_txn, tp, links, __txn_detail); + __db_shalloc_free(mgr->mem, tp); if (is_commit) mgr->region->ncommits++; else @@ -515,8 +523,9 @@ __txn_end(txnp, is_commit) /* - * Undo the transaction with id txnid. Returns 0 on success and sets - * errno and returns -1 on failure. + * __txn_undo -- + * Undo the transaction with id txnid. Returns 0 on success and + * errno on failure. */ static int __txn_undo(txnp) @@ -576,12 +585,12 @@ __txn_undo(txnp) int txn_checkpoint(mgr, kbytes, minutes) const DB_TXNMGR *mgr; - long kbytes, minutes; + int kbytes, minutes; { TXN_DETAIL *txnp; DB_LSN ckp_lsn, last_ckp; DB_LOG *dblp; - u_int32_t bytes_written, i; + u_int32_t bytes_written; time_t last_ckp_time, now; int ret; @@ -638,16 +647,16 @@ do_ckp: if (!IS_ZERO_LSN(mgr->region->pending_ckp)) ckp_lsn = mgr->region->pending_ckp; else - for (txnp = &mgr->region->table[0], i = 0; - i < mgr->region->maxtxns; i++, txnp++) { + for (txnp = + SH_TAILQ_FIRST(&mgr->region->active_txn, __txn_detail); + txnp != NULL; + txnp = SH_TAILQ_NEXT(txnp, links, __txn_detail)) { /* - * Look through the transaction table for the LSN of - * the transaction that is in-use (e.g., not - * TXN_UNALLOC) and whose begin lsn is the lowest. + * Look through the active transactions for the + * lowest begin lsn. */ - if (txnp->status != TXN_UNALLOC && - !IS_ZERO_LSN(txnp->begin_lsn) && + if (!IS_ZERO_LSN(txnp->begin_lsn) && log_compare(&txnp->begin_lsn, &ckp_lsn) < 0) ckp_lsn = txnp->begin_lsn; } @@ -707,6 +716,7 @@ __txn_validate_region(tp) return (ret); tp->reg_size = tp->region->hdr.size; + tp->mem = &tp->region[1]; return (0); } @@ -715,9 +725,9 @@ static int __txn_grow_region(tp) DB_TXNMGR *tp; { - TXN_DETAIL *tx; size_t incr; - u_int32_t i, oldmax; + u_int32_t oldmax; + u_int8_t *curaddr; int ret; oldmax = tp->region->maxtxns; @@ -729,19 +739,17 @@ __txn_grow_region(tp) if ((ret = __db_rremap(tp->dbenv, tp->region, tp->reg_size, tp->reg_size + incr, tp->fd, &tp->region)) != 0) return (ret); + + /* Throw the new space on the free list. */ + curaddr = (u_int8_t *)tp->region + tp->reg_size; + tp->mem = &tp->region[1]; tp->reg_size += incr; - /* - * Initialize all the new transactions and up the transaction count. - */ - for (i = 0, tx = &tp->region->table[oldmax]; i < oldmax; i++, tx++) { - ZERO_LSN(tx->begin_lsn); - tx->status = TXN_UNALLOC; - tx->txnid = oldmax + i + 1; - } - tp->region->free_txn = oldmax; + *((size_t *)curaddr) = incr - sizeof(size_t); + curaddr += sizeof(size_t); + __db_shalloc_free(tp->mem, curaddr); + tp->region->maxtxns = 2 * oldmax; - tp->region->table[tp->region->maxtxns - 1].txnid = TXN_INVALID; return (0); } @@ -753,8 +761,9 @@ txn_stat(mgr, statp, db_malloc) void *(*db_malloc) __P((size_t)); { DB_TXN_STAT *stats; + TXN_DETAIL *txnp; size_t nbytes; - u_int32_t i, nactive, ndx; + u_int32_t nactive, ndx; LOCK_TXNREGION(mgr); nactive = mgr->region->nbegins - @@ -789,17 +798,17 @@ txn_stat(mgr, statp, db_malloc) stats->st_nactive = nactive + 200; stats->st_txnarray = (DB_TXN_ACTIVE *)&stats[1]; - for (ndx = 0, i = 0; i < mgr->region->maxtxns; i++) - if (mgr->region->table[i].status != TXN_UNALLOC) { - stats->st_txnarray[ndx].txnid = - mgr->region->table[i].txnid; - stats->st_txnarray[ndx].lsn = - mgr->region->table[i].begin_lsn; - ndx++; + ndx = 0; + for (txnp = SH_TAILQ_FIRST(&mgr->region->active_txn, __txn_detail); + txnp != NULL; + txnp = SH_TAILQ_NEXT(txnp, links, __txn_detail)) { + stats->st_txnarray[ndx].txnid = txnp->txnid; + stats->st_txnarray[ndx].lsn = txnp->begin_lsn; + ndx++; - if (ndx >= stats->st_nactive) - break; - } + if (ndx >= stats->st_nactive) + break; + } UNLOCK_TXNREGION(mgr); *statp = stats; diff --git a/db2/txn/txn_auto.c b/db2/txn/txn_auto.c index c7f277ed0f..baef7333c7 100644 --- a/db2/txn/txn_auto.c +++ b/db2/txn/txn_auto.c @@ -92,7 +92,7 @@ __txn_regop_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __txn_regop_read(dbtp->data, &argp)) != 0) + if ((ret = __txn_regop_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]txn_regop: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, @@ -221,7 +221,7 @@ __txn_ckp_print(notused1, dbtp, lsnp, notused3, notused4) notused3 = 0; notused4 = NULL; - if((ret = __txn_ckp_read(dbtp->data, &argp)) != 0) + if ((ret = __txn_ckp_read(dbtp->data, &argp)) != 0) return (ret); printf("[%lu][%lu]txn_ckp: rec: %lu txnid %lx prevlsn [%lu][%lu]\n", (u_long)lsnp->file, |