diff options
Diffstat (limited to 'src/db/db_cds.c')
-rw-r--r-- | src/db/db_cds.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/src/db/db_cds.c b/src/db/db_cds.c new file mode 100644 index 00000000..185d5487 --- /dev/null +++ b/src/db/db_cds.c @@ -0,0 +1,201 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/lock.h" +#include "dbinc/txn.h" + +static int __cdsgroup_abort __P((DB_TXN *txn)); +static int __cdsgroup_commit __P((DB_TXN *txn, u_int32_t flags)); +static int __cdsgroup_discard __P((DB_TXN *txn, u_int32_t flags)); +static u_int32_t __cdsgroup_id __P((DB_TXN *txn)); +static int __cdsgroup_notsup __P((ENV *env, const char *meth)); +static int __cdsgroup_prepare __P((DB_TXN *txn, u_int8_t *gid)); +static int __cdsgroup_get_name __P((DB_TXN *txn, const char **namep)); +static int __cdsgroup_set_name __P((DB_TXN *txn, const char *name)); +static int __cdsgroup_set_timeout + __P((DB_TXN *txn, db_timeout_t timeout, u_int32_t flags)); + +/* + * __cdsgroup_notsup -- + * Error when CDS groups don't support a method. + */ +static int +__cdsgroup_notsup(env, meth) + ENV *env; + const char *meth; +{ + __db_errx(env, DB_STR_A("0687", "CDS groups do not support %s", "%s"), + meth); + return (DB_OPNOTSUP); +} + +static int +__cdsgroup_abort(txn) + DB_TXN *txn; +{ + return (__cdsgroup_notsup(txn->mgrp->env, "abort")); +} + +static int +__cdsgroup_commit(txn, flags) + DB_TXN *txn; + u_int32_t flags; +{ + DB_LOCKER *locker; + DB_LOCKREQ lreq; + ENV *env; + int ret, t_ret; + + COMPQUIET(flags, 0); + env = txn->mgrp->env; + + /* Check for live cursors. */ + if (txn->cursors != 0) { + __db_errx(env, DB_STR("0688", "CDS group has active cursors")); + return (EINVAL); + } + + /* We may be holding handle locks; release them. */ + lreq.op = DB_LOCK_PUT_ALL; + lreq.obj = NULL; + ret = __lock_vec(env, txn->locker, 0, &lreq, 1, NULL); + + env = txn->mgrp->env; + locker = txn->locker; + __os_free(env, txn->mgrp); + __os_free(env, txn); + if ((t_ret = __lock_id_free(env, locker)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +static int __cdsgroup_discard(txn, flags) + DB_TXN *txn; + u_int32_t flags; +{ + COMPQUIET(flags, 0); + return (__cdsgroup_notsup(txn->mgrp->env, "discard")); +} + +static u_int32_t __cdsgroup_id(txn) + DB_TXN *txn; +{ + return (txn->txnid); +} + +static int __cdsgroup_prepare(txn, gid) + DB_TXN *txn; + u_int8_t *gid; +{ + COMPQUIET(gid, NULL); + return (__cdsgroup_notsup(txn->mgrp->env, "prepare")); +} + +static int __cdsgroup_get_name(txn, namep) + DB_TXN *txn; + const char **namep; +{ + COMPQUIET(namep, NULL); + return (__cdsgroup_notsup(txn->mgrp->env, "get_name")); +} + +static int __cdsgroup_set_name(txn, name) + DB_TXN *txn; + const char *name; +{ + COMPQUIET(name, NULL); + return (__cdsgroup_notsup(txn->mgrp->env, "set_name")); +} + +static int __cdsgroup_set_timeout(txn, timeout, flags) + DB_TXN *txn; + db_timeout_t timeout; + u_int32_t flags; +{ + COMPQUIET(timeout, 0); + COMPQUIET(flags, 0); + return (__cdsgroup_notsup(txn->mgrp->env, "set_timeout")); +} + +/* + * PUBLIC: int __cdsgroup_begin __P((ENV *, DB_TXN **)); + */ +int +__cdsgroup_begin(env, txnpp) + ENV *env; + DB_TXN **txnpp; +{ + DB_TXN *txn; + int ret; + + *txnpp = txn = NULL; + if ((ret = __os_calloc(env, 1, sizeof(DB_TXN), &txn)) != 0) + goto err; + /* + * We need a dummy DB_TXNMGR -- it's the only way to get from a + * transaction handle to the environment handle. + */ + if ((ret = __os_calloc(env, 1, sizeof(DB_TXNMGR), &txn->mgrp)) != 0) + goto err; + txn->mgrp->env = env; + + if ((ret = __lock_id(env, &txn->txnid, &txn->locker)) != 0) + goto err; + + txn->flags = TXN_FAMILY; + txn->abort = __cdsgroup_abort; + txn->commit = __cdsgroup_commit; + txn->discard = __cdsgroup_discard; + txn->id = __cdsgroup_id; + txn->prepare = __cdsgroup_prepare; + txn->get_name = __cdsgroup_get_name; + txn->set_name = __cdsgroup_set_name; + txn->set_timeout = __cdsgroup_set_timeout; + + *txnpp = txn; + + if (0) { +err: if (txn != NULL) { + if (txn->mgrp != NULL) + __os_free(env, txn->mgrp); + __os_free(env, txn); + } + } + return (ret); +} + +/* + * __cds_txn_begin_pp -- + * DB_ENV->cdsgroup_begin + * + * PUBLIC: int __cdsgroup_begin_pp __P((DB_ENV *, DB_TXN **)); + */ +int __cdsgroup_begin_pp(dbenv, txnpp) + DB_ENV *dbenv; + DB_TXN **txnpp; +{ + DB_THREAD_INFO *ip; + ENV *env; + int ret; + + env = dbenv->env; + + ENV_ILLEGAL_BEFORE_OPEN(env, "cdsgroup_begin"); + if (!CDB_LOCKING(env)) + return (__env_not_config(env, "cdsgroup_begin", DB_INIT_CDB)); + + ENV_ENTER(env, ip); + ret = __cdsgroup_begin(env, txnpp); + ENV_LEAVE(env, ip); + return (ret); + } |