diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2007-07-16 16:48:14 +0300 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2007-07-16 16:48:14 +0300 |
commit | 2cfd3012bfcb5c5c61bbaf662ef084e0ab789d79 (patch) | |
tree | e12ee52087506ac8c7a5eee83b17497d98df2d40 /db/xa | |
parent | b754fe19fd387ca5fe8e7c00ddaa25c898fa192f (diff) | |
download | librpm-tizen-2cfd3012bfcb5c5c61bbaf662ef084e0ab789d79.tar.gz librpm-tizen-2cfd3012bfcb5c5c61bbaf662ef084e0ab789d79.tar.bz2 librpm-tizen-2cfd3012bfcb5c5c61bbaf662ef084e0ab789d79.zip |
Update internal BDB to version 4.5.20
Diffstat (limited to 'db/xa')
-rw-r--r-- | db/xa/xa.c | 169 | ||||
-rw-r--r-- | db/xa/xa_db.c | 136 | ||||
-rw-r--r-- | db/xa/xa_map.c | 34 |
3 files changed, 188 insertions, 151 deletions
diff --git a/db/xa/xa.c b/db/xa/xa.c index 00f3461e3..56cc772ac 100644 --- a/db/xa/xa.c +++ b/db/xa/xa.c @@ -1,35 +1,28 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998-2004 - * Sleepycat Software. All rights reserved. + * Copyright (c) 1998-2006 + * Oracle Corporation. All rights reserved. * - * $Id: xa.c,v 11.35 2004/10/15 16:59:45 bostic Exp $ + * $Id: xa.c,v 12.12 2006/08/24 14:46:54 bostic Exp $ */ #include "db_config.h" -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - #include "db_int.h" #include "dbinc/txn.h" -static int __db_xa_close __P((char *, int, long)); -static int __db_xa_commit __P((XID *, int, long)); -static int __db_xa_complete __P((int *, int *, int, long)); -static int __db_xa_end __P((XID *, int, long)); -static int __db_xa_forget __P((XID *, int, long)); -static int __db_xa_open __P((char *, int, long)); -static int __db_xa_prepare __P((XID *, int, long)); -static int __db_xa_recover __P((XID *, long, int, long)); -static int __db_xa_rollback __P((XID *, int, long)); -static int __db_xa_start __P((XID *, int, long)); -static void __xa_put_txn __P((DB_ENV *, DB_TXN *)); +static int __db_xa_close __P((char *, int, long)); +static int __db_xa_commit __P((XID *, int, long)); +static int __db_xa_complete __P((int *, int *, int, long)); +static int __db_xa_end __P((XID *, int, long)); +static int __db_xa_forget __P((XID *, int, long)); +static int __db_xa_open __P((char *, int, long)); +static int __db_xa_prepare __P((XID *, int, long)); +static int __db_xa_recover __P((XID *, long, int, long)); +static int __db_xa_rollback __P((XID *, int, long)); +static int __db_xa_start __P((XID *, int, long)); +static int __xa_put_txn __P((DB_ENV *, DB_TXN *)); /* * Possible flag values: @@ -58,23 +51,12 @@ const struct xa_switch_t db_xa_switch = { }; /* - * If you want your XA server to be multi-threaded, then you must + * If you want your XA server to be multi-threaded, then you must (at least) * edit this file and change: * #undef XA_MULTI_THREAD * to: * #define XA_MULTI_THREAD 1 - * - * You must then modify the FILL ME IN; section below to assign a - * 32-bit unsigned, unique thread ID to the variable tid. If no - * such thread ID is available, e.g., you're using pthreads on a POSIX - * 1003.1 system where a pthread_t is declared as a structure, you - * will probably want to change the tid field of the DB_TXN structure - * to be the correct type in which to define a thread ID on the system, - * and then modify both the FILL ME IN section and then subsequent - * comparison of the thread IDs in the XA transaction list, as the - * current simple equality tests may not work. */ - #undef XA_MULTI_THREAD /* @@ -91,55 +73,62 @@ __xa_get_txn(dbenv, txnp, do_init) DB_TXN **txnp; int do_init; { - int ret; #ifdef XA_MULTI_THREAD DB_TXN *t; - u_int32_t tid; DB_TXNMGR *mgr; -#else - COMPQUIET(do_init, 0); + TXN_DETAIL *td; + db_threadid_t tid; + pid_t pid; #endif + int ret; + ret = 0; #ifdef XA_MULTI_THREAD - /* Specify Thread-ID retrieval here. */ - tid = FILL ME IN + dbenv->thread_id(dbenv, &pid, &tid); *txnp = NULL; - mgr = (DB_TXNMGR *)dbenv->tx_handle; + + DB_ASSERT(dbenv, dbenv->tx_handle != NULL); + mgr = dbenv->tx_handle; /* - * We need to protect the xa_txn linked list, but the - * environment does not have a mutex. Since we are in - * an XA transaction environment, we know that there is - * a transaction structure, so use its mutex. + * We need to protect the xa_txn linked list, but the environment does + * not have a mutex. Since we are in an XA transaction environment, + * we know there is a transaction structure, we can use its mutex. */ - DB_ASSERT(dbenv->tx_handle != NULL); - MUTEX_THREAD_LOCK(mgr->mutexp); - for (t = TAILQ_FIRST(&dbenv->xa_txn); - t != NULL; - t = TAILQ_NEXT(t, xalinks)) - /* - * FILL ME IN; if tids are not a 32-bit integral type; - * put a comparison here that will work. - */ + MUTEX_LOCK(dbenv, mgr->mutex); + TAILQ_FOREACH(t, &dbenv->xa_txn, xalinks) { + td = t->td; + if (td->pid != pid) + continue; +#ifdef HAVE_SIMPLE_THREAD_TYPE if (t->tid == tid) { *txnp = t; break; } - MUTEX_THREAD_UNLOCK(mgr->mutexp); +#else + if (memcmp(&t->tid, &tid, sizeof(tid)) == 0) { + *txnp = t; + break; + } +#endif + } + MUTEX_UNLOCK(dbenv, mgr->mutex); if (*txnp == NULL) { if (!do_init) ret = EINVAL; else if ((ret = - __os_malloc(dbenv, sizeof(DB_TXN), NULL, txnp)) == 0) { + __os_malloc(dbenv, sizeof(DB_TXN), txnp)) == 0) { (*txnp)->tid = tid; - MUTEX_THREAD_LOCK(mgr->mutexp); + MUTEX_LOCK(dbenv, mgr->mutex); TAILQ_INSERT_HEAD(&dbenv->xa_txn, *txnp, xalinks); - MUTEX_THREAD_UNLOCK(mgr->mutexp); + MUTEX_UNLOCK(dbenv, mgr->mutex); } } #else + COMPQUIET(do_init, 0); + *txnp = TAILQ_FIRST(&dbenv->xa_txn); if (*txnp == NULL && (ret = __os_calloc(dbenv, 1, sizeof(DB_TXN), txnp)) == 0) { @@ -151,23 +140,24 @@ __xa_get_txn(dbenv, txnp, do_init) return (ret); } -static void +static int __xa_put_txn(dbenv, txnp) DB_ENV *dbenv; DB_TXN *txnp; { #ifdef XA_MULTI_THREAD DB_TXNMGR *mgr; - mgr = (DB_TXNMGR *)dbenv->tx_handle; + mgr = dbenv->tx_handle; - MUTEX_THREAD_LOCK(mgr->mutexp); + MUTEX_LOCK(dbenv, mgr->mutex); TAILQ_REMOVE(&dbenv->xa_txn, txnp, xalinks); - MUTEX_THREAD_UNLOCK(mgr->mutexp); + MUTEX_UNLOCK(dbenv, mgr->mutex); __os_free(dbenv, txnp); #else COMPQUIET(dbenv, NULL); txnp->txnid = TXN_INVALID; #endif + return (0); } #ifdef XA_MULTI_THREAD @@ -213,8 +203,6 @@ __db_xa_open(xa_info, rmid, arg_flags) /* Verify if we already have this environment open. */ if (__db_rmid_to_env(rmid, &dbenv) == 0) return (XA_OK); - if (__os_calloc(dbenv, 1, sizeof(DB_ENV), &dbenv) != 0) - return (XAER_RMERR); /* Open a new environment. */ if (db_env_create(&dbenv, 0) != 0) @@ -335,7 +323,7 @@ __db_xa_start(xid, rmid, arg_flags) * Other error conditions: RMERR, RMFAIL, OUTSIDE, PROTO, RB* */ if (is_known) { - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); + td = R_ADDR(&dbenv->tx_handle->reginfo, off); if (td->xa_status == TXN_XA_SUSPENDED && !LF_ISSET(TMRESUME | TMJOIN)) return (XAER_PROTO); @@ -347,16 +335,15 @@ __db_xa_start(xid, rmid, arg_flags) /* Now, fill in the global transaction structure. */ if (__xa_get_txn(dbenv, &txnp, 1) != 0) return (XAER_RMERR); - __txn_continue(dbenv, txnp, td, off); + __txn_continue(dbenv, txnp, td); td->xa_status = TXN_XA_STARTED; } else { if (__xa_get_txn(dbenv, &txnp, 1) != 0) return (XAER_RMERR); if (__txn_xa_begin(dbenv, txnp)) return (XAER_RMERR); - (void)__db_map_xid(dbenv, xid, txnp->off); - td = R_ADDR( - &((DB_TXNMGR *)dbenv->tx_handle)->reginfo, txnp->off); + (void)__db_map_xid(dbenv, xid, txnp->td); + td = txnp->td; td->xa_status = TXN_XA_STARTED; } return (XA_OK); @@ -389,10 +376,10 @@ __db_xa_end(xid, rmid, flags) if (__xa_get_txn(dbenv, &txn, 0) != 0) return (XAER_RMERR); - if (off != txn->off) + td = R_ADDR(&dbenv->tx_handle->reginfo, off); + if (td != txn->td) return (XAER_PROTO); - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); if (td->xa_status == TXN_XA_DEADLOCKED) return (XA_RBDEADLOCK); @@ -402,9 +389,6 @@ __db_xa_end(xid, rmid, flags) if (td->xa_status != TXN_XA_STARTED) return (XAER_PROTO); - /* Update the shared memory last_lsn field */ - td->last_lsn = txn->last_lsn; - /* * If we ever support XA migration, we cannot keep SUSPEND/END * status in the shared region; it would have to be process local. @@ -414,7 +398,11 @@ __db_xa_end(xid, rmid, flags) else td->xa_status = TXN_XA_ENDED; - __xa_put_txn(dbenv, txn); + /* + * XXX + * This can fail in XA_MULTI_THREAD mode. + */ + (void)__xa_put_txn(dbenv, txn); return (XA_OK); } @@ -452,7 +440,7 @@ __db_xa_prepare(xid, rmid, arg_flags) if (__db_xid_to_txn(dbenv, xid, &off) != 0) return (XAER_NOTA); - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); + td = R_ADDR(&dbenv->tx_handle->reginfo, off); if (td->xa_status == TXN_XA_DEADLOCKED) return (XA_RBDEADLOCK); @@ -462,15 +450,18 @@ __db_xa_prepare(xid, rmid, arg_flags) /* Now, fill in the global transaction structure. */ if (__xa_get_txn(dbenv, &txnp, 0) != 0) return (XAER_PROTO); - __txn_continue(dbenv, txnp, td, off); + __txn_continue(dbenv, txnp, td); if (txnp->prepare(txnp, (u_int8_t *)xid->data) != 0) return (XAER_RMERR); td->xa_status = TXN_XA_PREPARED; - /* No fatal value that would require an XAER_RMFAIL. */ - __xa_put_txn(dbenv, txnp); + /* + * XXX + * This can fail in XA_MULTI_THREAD mode. + */ + (void)__xa_put_txn(dbenv, txnp); return (XA_OK); } @@ -509,7 +500,7 @@ __db_xa_commit(xid, rmid, arg_flags) if (__db_xid_to_txn(dbenv, xid, &off) != 0) return (XAER_NOTA); - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); + td = R_ADDR(&dbenv->tx_handle->reginfo, off); if (td->xa_status == TXN_XA_DEADLOCKED) return (XA_RBDEADLOCK); @@ -526,13 +517,16 @@ __db_xa_commit(xid, rmid, arg_flags) /* Now, fill in the global transaction structure. */ if (__xa_get_txn(dbenv, &txnp, 0) != 0) return (XAER_RMERR); - __txn_continue(dbenv, txnp, td, off); + __txn_continue(dbenv, txnp, td); if (txnp->commit(txnp, 0) != 0) return (XAER_RMERR); - /* No fatal value that would require an XAER_RMFAIL. */ - __xa_put_txn(dbenv, txnp); + /* + * XXX + * This can fail in XA_MULTI_THREAD mode. + */ + (void)__xa_put_txn(dbenv, txnp); return (XA_OK); } @@ -601,7 +595,7 @@ __db_xa_rollback(xid, rmid, arg_flags) if (__db_xid_to_txn(dbenv, xid, &off) != 0) return (XAER_NOTA); - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); + td = R_ADDR(&dbenv->tx_handle->reginfo, off); if (td->xa_status == TXN_XA_DEADLOCKED) return (XA_RBDEADLOCK); @@ -616,12 +610,15 @@ __db_xa_rollback(xid, rmid, arg_flags) /* Now, fill in the global transaction structure. */ if (__xa_get_txn(dbenv, &txnp, 0) != 0) return (XAER_RMERR); - __txn_continue(dbenv, txnp, td, off); + __txn_continue(dbenv, txnp, td); if (txnp->abort(txnp) != 0) return (XAER_RMERR); - /* No fatal value that would require an XAER_RMFAIL. */ - __xa_put_txn(dbenv, txnp); + /* + * XXX + * This can fail in XA_MULTI_THREAD mode. + */ + (void)__xa_put_txn(dbenv, txnp); return (XA_OK); } diff --git a/db/xa/xa_db.c b/db/xa/xa_db.c index 550d47dd8..2c7276345 100644 --- a/db/xa/xa_db.c +++ b/db/xa/xa_db.c @@ -1,18 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998-2004 - * Sleepycat Software. All rights reserved. + * Copyright (c) 1998-2006 + * Oracle Corporation. All rights reserved. * - * $Id: xa_db.c,v 11.26 2004/01/28 03:36:40 bostic Exp $ + * $Id: xa_db.c,v 12.8 2006/08/24 14:46:54 bostic Exp $ */ #include "db_config.h" -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - #include "db_int.h" #include "dbinc/txn.h" @@ -23,6 +19,8 @@ static int __xa_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); static int __xa_open __P((DB *, DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int)); static int __xa_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); +static int __xa_set_txn __P((DB *, DB_TXN **, int)); +static int __xa_truncate __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); typedef struct __xa_methods { int (*close) __P((DB *, u_int32_t)); @@ -32,18 +30,56 @@ typedef struct __xa_methods { int (*open) __P((DB *, DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int)); int (*put) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); + int (*truncate) __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); } XA_METHODS; -#define SET_TXN(PARAM, LOCAL) { \ - (LOCAL) = NULL; \ - if (!LF_ISSET(DB_AUTO_COMMIT)) { \ - if ((PARAM) != NULL) \ - (LOCAL) = (PARAM); \ - else if (__xa_get_txn(dbp->dbenv, &(LOCAL), 0) != 0) \ - (LOCAL) = NULL; \ - else if ((LOCAL) != NULL && (LOCAL)->txnid == TXN_INVALID) \ - (LOCAL) = NULL; \ - } \ +/* + * __xa_set_txn -- + * Find a transaction handle. + */ +static int +__xa_set_txn(dbp, txnpp, no_xa_txn) + DB *dbp; + DB_TXN **txnpp; + int no_xa_txn; +{ + DB_ENV *dbenv; + int ret; + + dbenv = dbp->dbenv; + + /* + * It doesn't make sense for a server to specify a DB_TXN handle. + * As the server can't know if other operations it has done have + * committed/aborted, it can self-deadlock. If the server wants + * other transactions, it can open other DB handles and use them. + * Disallow specified DB_TXN handles. + */ + if (*txnpp != NULL) { + __db_errx(dbenv, + "transaction handles should not be directly specified to XA interfaces"); + return (EINVAL); + } + + /* See if the TM has declared a transaction. */ + if ((ret = __xa_get_txn(dbenv, txnpp, 0)) != 0) + return (ret); + if ((*txnpp)->txnid != TXN_INVALID) + return (0); + + /* + * We may be opening databases in the server initialization routine. + * In that case, it's reasonable not to have an XA transaction. It's + * also reasonable to open a database as part of an XA transaction, + * allow both. + */ + if (no_xa_txn) { + *txnpp = NULL; + return (0); + } + + __db_errx(dbenv, "no XA transaction declared"); + return (EINVAL); } /* @@ -60,8 +96,8 @@ __db_xa_create(dbp) int ret; /* - * Interpose XA routines in front of any method that takes a TXN - * ID as an argument. + * Allocate the XA internal structure, and wrap the open and close + * calls. */ if ((ret = __os_calloc(dbp->dbenv, 1, sizeof(XA_METHODS), &xam)) != 0) return (ret); @@ -79,7 +115,6 @@ __db_xa_create(dbp) * __xa_open -- * XA open wrapper. */ - static int __xa_open(dbp, txn, name, subdb, type, flags, mode) DB *dbp; @@ -89,24 +124,28 @@ __xa_open(dbp, txn, name, subdb, type, flags, mode) u_int32_t flags; int mode; { - DB_TXN *t; XA_METHODS *xam; int ret; xam = (XA_METHODS *)dbp->xa_internal; - SET_TXN(txn, t); - if ((ret = xam->open(dbp, t, name, subdb, type, flags, mode)) != 0) + if ((ret = + __xa_set_txn(dbp, &txn, LF_ISSET(DB_AUTO_COMMIT) ? 1 : 0)) != 0) + return (ret); + if ((ret = xam->open(dbp, txn, name, subdb, type, flags, mode)) != 0) return (ret); + /* Wrap any DB handle method that takes a TXN ID as an argument. */ xam->cursor = dbp->cursor; xam->del = dbp->del; xam->get = dbp->get; xam->put = dbp->put; + xam->truncate = dbp->truncate; dbp->cursor = __xa_cursor; dbp->del = __xa_del; dbp->get = __xa_get; dbp->put = __xa_put; + dbp->truncate = __xa_truncate; return (0); } @@ -118,15 +157,12 @@ __xa_cursor(dbp, txn, dbcp, flags) DBC **dbcp; u_int32_t flags; { - DB_TXN *t; - - if (txn != NULL) - t = txn; - else if (__xa_get_txn(dbp->dbenv, &t, 0) != 0 || - t->txnid== TXN_INVALID) - t = NULL; + int ret; - return (((XA_METHODS *)dbp->xa_internal)->cursor (dbp, t, dbcp, flags)); + if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0) + return (ret); + return (((XA_METHODS *) + dbp->xa_internal)->cursor(dbp, txn, dbcp, flags)); } static int @@ -136,10 +172,11 @@ __xa_del(dbp, txn, key, flags) DBT *key; u_int32_t flags; { - DB_TXN *t; + int ret; - SET_TXN(txn, t); - return (((XA_METHODS *)dbp->xa_internal)->del(dbp, t, key, flags)); + if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0) + return (ret); + return (((XA_METHODS *)dbp->xa_internal)->del(dbp, txn, key, flags)); } static int @@ -164,11 +201,12 @@ __xa_get(dbp, txn, key, data, flags) DBT *key, *data; u_int32_t flags; { - DB_TXN *t; + int ret; - SET_TXN(txn, t); - return (((XA_METHODS *)dbp->xa_internal)->get - (dbp, t, key, data, flags)); + if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0) + return (ret); + return (((XA_METHODS *) + dbp->xa_internal)->get(dbp, txn, key, data, flags)); } static int @@ -178,10 +216,24 @@ __xa_put(dbp, txn, key, data, flags) DBT *key, *data; u_int32_t flags; { - DB_TXN *t; + int ret; - SET_TXN(txn, t); + if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0) + return (ret); + return (((XA_METHODS *) + dbp->xa_internal)->put(dbp, txn, key, data, flags)); +} + +static int +__xa_truncate(dbp, txn, countp, flags) + DB *dbp; + DB_TXN *txn; + u_int32_t *countp, flags; +{ + int ret; - return (((XA_METHODS *)dbp->xa_internal)->put - (dbp, t, key, data, flags)); + if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0) + return (ret); + return (((XA_METHODS *) + dbp->xa_internal)->truncate(dbp, txn, countp, flags)); } diff --git a/db/xa/xa_map.c b/db/xa/xa_map.c index 80fb3dac4..c0bd7cb2b 100644 --- a/db/xa/xa_map.c +++ b/db/xa/xa_map.c @@ -1,20 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996-2004 - * Sleepycat Software. All rights reserved. + * Copyright (c) 1996-2006 + * Oracle Corporation. All rights reserved. * - * $Id: xa_map.c,v 11.25 2004/10/15 16:59:46 bostic Exp $ + * $Id: xa_map.c,v 12.8 2006/08/24 14:46:54 bostic Exp $ */ #include "db_config.h" -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - #include "db_int.h" #include "dbinc/txn.h" @@ -117,29 +111,23 @@ __db_unmap_rmid(rmid) /* * __db_map_xid - * Create a mapping between this XID and the transaction at - * "off" in the shared region. + * Create a mapping between this XID and the transaction + * "td" in the shared region. * - * PUBLIC: int __db_map_xid __P((DB_ENV *, XID *, size_t)); + * PUBLIC: int __db_map_xid __P((DB_ENV *, XID *, TXN_DETAIL *)); */ int -__db_map_xid(dbenv, xid, off) +__db_map_xid(dbenv, xid, td) DB_ENV *dbenv; XID *xid; - size_t off; -{ - REGINFO *infop; TXN_DETAIL *td; - - infop = &((DB_TXNMGR *)dbenv->tx_handle)->reginfo; - td = R_ADDR(infop, off); - - R_LOCK(dbenv, infop); +{ + TXN_SYSTEM_LOCK(dbenv); memcpy(td->xid, xid->data, XIDDATASIZE); td->bqual = (u_int32_t)xid->bqual_length; td->gtrid = (u_int32_t)xid->gtrid_length; td->format = (int32_t)xid->formatID; - R_UNLOCK(dbenv, infop); + TXN_SYSTEM_UNLOCK(dbenv); return (0); } @@ -161,6 +149,6 @@ __db_unmap_xid(dbenv, xid, off) COMPQUIET(xid, NULL); - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); + td = R_ADDR(&dbenv->tx_handle->reginfo, off); memset(td->xid, 0, sizeof(td->xid)); } |