diff options
Diffstat (limited to 'storage/bdb/txn/txn_util.c')
-rw-r--r-- | storage/bdb/txn/txn_util.c | 330 |
1 files changed, 0 insertions, 330 deletions
diff --git a/storage/bdb/txn/txn_util.c b/storage/bdb/txn/txn_util.c deleted file mode 100644 index ac9ea6d94c8..00000000000 --- a/storage/bdb/txn/txn_util.c +++ /dev/null @@ -1,330 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: txn_util.c,v 12.2 2005/09/28 17:45:20 margo Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" -#include "dbinc/db_am.h" - -typedef struct __txn_event TXN_EVENT; -struct __txn_event { - TXN_EVENT_T op; - TAILQ_ENTRY(__txn_event) links; - union { - struct { - /* Delayed close. */ - DB *dbp; - } c; - struct { - /* Delayed remove. */ - char *name; - u_int8_t *fileid; - int inmem; - } r; - struct { - /* Lock event. */ - DB_LOCK lock; - u_int32_t locker; - DB *dbp; - } t; - } u; -}; - -/* - * __txn_closeevent -- - * - * Creates a close event that can be added to the [so-called] commit list, so - * that we can redo a failed DB handle close once we've aborted the transaction. - * - * PUBLIC: int __txn_closeevent __P((DB_ENV *, DB_TXN *, DB *)); - */ -int -__txn_closeevent(dbenv, txn, dbp) - DB_ENV *dbenv; - DB_TXN *txn; - DB *dbp; -{ - int ret; - TXN_EVENT *e; - - e = NULL; - if ((ret = __os_calloc(dbenv, 1, sizeof(TXN_EVENT), &e)) != 0) - return (ret); - - e->u.c.dbp = dbp; - e->op = TXN_CLOSE; - TAILQ_INSERT_TAIL(&txn->events, e, links); - - return (0); -} - -/* - * __txn_remevent -- - * - * Creates a remove event that can be added to the commit list. - * - * PUBLIC: int __txn_remevent __P((DB_ENV *, - * PUBLIC: DB_TXN *, const char *, u_int8_t *, int)); - */ -int -__txn_remevent(dbenv, txn, name, fileid, inmem) - DB_ENV *dbenv; - DB_TXN *txn; - const char *name; - u_int8_t *fileid; - int inmem; -{ - int ret; - TXN_EVENT *e; - - e = NULL; - if ((ret = __os_calloc(dbenv, 1, sizeof(TXN_EVENT), &e)) != 0) - return (ret); - - if ((ret = __os_strdup(dbenv, name, &e->u.r.name)) != 0) - goto err; - - if (fileid != NULL) { - if ((ret = __os_calloc(dbenv, - 1, DB_FILE_ID_LEN, &e->u.r.fileid)) != 0) - return (ret); - memcpy(e->u.r.fileid, fileid, DB_FILE_ID_LEN); - } - - e->u.r.inmem = inmem; - e->op = TXN_REMOVE; - TAILQ_INSERT_TAIL(&txn->events, e, links); - - return (0); - -err: if (e != NULL) - __os_free(dbenv, e); - - return (ret); -} - -/* - * __txn_remrem -- - * Remove a remove event because the remove has been superceeded, - * by a create of the same name, for example. - * - * PUBLIC: void __txn_remrem __P((DB_ENV *, DB_TXN *, const char *)); - */ -void -__txn_remrem(dbenv, txn, name) - DB_ENV *dbenv; - DB_TXN *txn; - const char *name; -{ - TXN_EVENT *e, *next_e; - - for (e = TAILQ_FIRST(&txn->events); e != NULL; e = next_e) { - next_e = TAILQ_NEXT(e, links); - if (e->op != TXN_REMOVE || strcmp(name, e->u.r.name) != 0) - continue; - TAILQ_REMOVE(&txn->events, e, links); - __os_free(dbenv, e->u.r.name); - if (e->u.r.fileid != NULL) - __os_free(dbenv, e->u.r.fileid); - __os_free(dbenv, e); - } - - return; -} - -/* - * __txn_lockevent -- - * - * Add a lockevent to the commit-queue. The lock event indicates a locker - * trade. - * - * PUBLIC: int __txn_lockevent __P((DB_ENV *, - * PUBLIC: DB_TXN *, DB *, DB_LOCK *, u_int32_t)); - */ -int -__txn_lockevent(dbenv, txn, dbp, lock, locker) - DB_ENV *dbenv; - DB_TXN *txn; - DB *dbp; - DB_LOCK *lock; - u_int32_t locker; -{ - int ret; - TXN_EVENT *e; - - if (!LOCKING_ON(dbenv)) - return (0); - - e = NULL; - if ((ret = __os_calloc(dbenv, 1, sizeof(TXN_EVENT), &e)) != 0) - return (ret); - - e->u.t.locker = locker; - e->u.t.lock = *lock; - e->u.t.dbp = dbp; - e->op = TXN_TRADE; - TAILQ_INSERT_TAIL(&txn->events, e, links); - - return (0); -} - -/* - * __txn_remlock -- - * Remove a lock event because the locker is going away. We can remove - * by lock (using offset) or by locker_id (or by both). - * - * PUBLIC: void __txn_remlock __P((DB_ENV *, DB_TXN *, DB_LOCK *, u_int32_t)); - */ -void -__txn_remlock(dbenv, txn, lock, locker) - DB_ENV *dbenv; - DB_TXN *txn; - DB_LOCK *lock; - u_int32_t locker; -{ - TXN_EVENT *e, *next_e; - - for (e = TAILQ_FIRST(&txn->events); e != NULL; e = next_e) { - next_e = TAILQ_NEXT(e, links); - if ((e->op != TXN_TRADE && e->op != TXN_TRADED) || - (e->u.t.lock.off != lock->off && e->u.t.locker != locker)) - continue; - TAILQ_REMOVE(&txn->events, e, links); - __os_free(dbenv, e); - } - - return; -} - -/* - * __txn_doevents -- - * Process the list of events associated with a transaction. On commit, - * apply the events; on abort, just toss the entries. - * - * PUBLIC: int __txn_doevents __P((DB_ENV *, DB_TXN *, int, int)); - */ -#define DO_TRADE do { \ - memset(&req, 0, sizeof(req)); \ - req.lock = e->u.t.lock; \ - req.op = DB_LOCK_TRADE; \ - t_ret = __lock_vec(dbenv, e->u.t.locker, 0, &req, 1, NULL); \ - if (t_ret == 0) \ - e->u.t.dbp->cur_lid = e->u.t.locker; \ - else if (t_ret == DB_NOTFOUND) \ - t_ret = 0; \ - if (t_ret != 0 && ret == 0) \ - ret = t_ret; \ - e->op = TXN_TRADED; \ -} while (0) - -int -__txn_doevents(dbenv, txn, opcode, preprocess) - DB_ENV *dbenv; - DB_TXN *txn; - int opcode, preprocess; -{ - DB_LOCKREQ req; - TXN_EVENT *e; - int ret, t_ret; - - ret = 0; - - /* - * This phase only gets called if we have a phase where we - * release read locks. Since not all paths will call this - * phase, we have to check for it below as well. So, when - * we do the trade, we update the opcode of the entry so that - * we don't try the trade again. - */ - if (preprocess) { - for (e = TAILQ_FIRST(&txn->events); - e != NULL; e = TAILQ_NEXT(e, links)) { - if (e->op != TXN_TRADE) - continue; - DO_TRADE; - } - return (ret); - } - - /* - * Prepare should only cause a preprocess, since the transaction - * isn't over. - */ - DB_ASSERT(opcode != TXN_PREPARE); - while ((e = TAILQ_FIRST(&txn->events)) != NULL) { - TAILQ_REMOVE(&txn->events, e, links); - /* - * Most deferred events should only happen on - * commits, not aborts or prepares. The one exception - * is a close which gets done on commit and abort, but - * not prepare. If we're not doing operations, then we - * can just go free resources. - */ - if (opcode == TXN_ABORT && e->op != TXN_CLOSE) - goto dofree; - switch (e->op) { - case TXN_CLOSE: - /* If we didn't abort this txn, we screwed up badly. */ - DB_ASSERT(opcode == TXN_ABORT); - if ((t_ret = __db_close(e->u.c.dbp, - NULL, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - break; - case TXN_REMOVE: - if (e->u.r.fileid != NULL) { - if ((t_ret = __memp_nameop(dbenv, - e->u.r.fileid, NULL, e->u.r.name, - NULL, e->u.r.inmem)) != 0 && ret == 0) - ret = t_ret; - } else if ((t_ret = - __os_unlink(dbenv, e->u.r.name)) != 0 && ret == 0) - ret = t_ret; - break; - case TXN_TRADE: - DO_TRADE; - /* Fall through */ - case TXN_TRADED: - /* Downgrade the lock. */ - if ((t_ret = __lock_downgrade(dbenv, - &e->u.t.lock, DB_LOCK_READ, 0)) != 0 && ret == 0) - ret = t_ret; - break; - default: - /* This had better never happen. */ - DB_ASSERT(0); - } -dofree: - /* Free resources here. */ - switch (e->op) { - case TXN_REMOVE: - if (e->u.r.fileid != NULL) - __os_free(dbenv, e->u.r.fileid); - __os_free(dbenv, e->u.r.name); - break; - case TXN_CLOSE: - case TXN_TRADE: - case TXN_TRADED: - default: - break; - } - __os_free(dbenv, e); - } - - return (ret); -} |