📄 tcl_txn.c
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1999-2001 * Sleepycat Software. All rights reserved. */#include "db_config.h"#ifndef lintstatic const char revid[] = "$Id: tcl_txn.c,v 11.57 2002/08/06 06:21:36 bostic Exp $";#endif /* not lint */#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <stdlib.h>#include <string.h>#include <tcl.h>#endif#include "db_int.h"#include "dbinc/tcl_db.h"static int tcl_TxnCommit __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_TXN *, DBTCL_INFO *));static int txn_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST *));/* * _TxnInfoDelete -- * Removes nested txn info structures that are children * of this txn. * RECURSIVE: Transactions can be arbitrarily nested, so we * must recurse down until we get them all. * * PUBLIC: void _TxnInfoDelete __P((Tcl_Interp *, DBTCL_INFO *)); */void_TxnInfoDelete(interp, txnip) Tcl_Interp *interp; /* Interpreter */ DBTCL_INFO *txnip; /* Info for txn */{ DBTCL_INFO *nextp, *p; for (p = LIST_FIRST(&__db_infohead); p != NULL; p = nextp) { /* * Check if this info structure "belongs" to this * txn. Remove its commands and info structure. */ nextp = LIST_NEXT(p, entries); if (p->i_parent == txnip && p->i_type == I_TXN) { _TxnInfoDelete(interp, p); (void)Tcl_DeleteCommand(interp, p->i_name); _DeleteInfo(p); } }}/* * tcl_TxnCheckpoint -- * * PUBLIC: int tcl_TxnCheckpoint __P((Tcl_Interp *, int, * PUBLIC: Tcl_Obj * CONST*, DB_ENV *)); */inttcl_TxnCheckpoint(interp, objc, objv, envp) Tcl_Interp *interp; /* Interpreter */ int objc; /* How many arguments? */ Tcl_Obj *CONST objv[]; /* The argument objects */ DB_ENV *envp; /* Environment pointer */{ static char *txnckpopts[] = { "-kbyte", "-min", NULL }; enum txnckpopts { TXNCKP_KB, TXNCKP_MIN }; int i, kb, min, optindex, result, ret; result = TCL_OK; kb = min = 0; /* * Get the flag index from the object based on the options * defined above. */ i = 2; while (i < objc) { if (Tcl_GetIndexFromObj(interp, objv[i], txnckpopts, "option", TCL_EXACT, &optindex) != TCL_OK) { return (IS_HELP(objv[i])); } i++; switch ((enum txnckpopts)optindex) { case TXNCKP_KB: if (i == objc) { Tcl_WrongNumArgs(interp, 2, objv, "?-kbyte kb?"); result = TCL_ERROR; break; } result = Tcl_GetIntFromObj(interp, objv[i++], &kb); break; case TXNCKP_MIN: if (i == objc) { Tcl_WrongNumArgs(interp, 2, objv, "?-min min?"); result = TCL_ERROR; break; } result = Tcl_GetIntFromObj(interp, objv[i++], &min); break; } } _debug_check(); ret = envp->txn_checkpoint(envp, (u_int32_t)kb, (u_int32_t)min, 0); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "txn checkpoint"); return (result);}/* * tcl_Txn -- * * PUBLIC: int tcl_Txn __P((Tcl_Interp *, int, * PUBLIC: Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *)); */inttcl_Txn(interp, objc, objv, envp, envip) Tcl_Interp *interp; /* Interpreter */ int objc; /* How many arguments? */ Tcl_Obj *CONST objv[]; /* The argument objects */ DB_ENV *envp; /* Environment pointer */ DBTCL_INFO *envip; /* Info pointer */{ static char *txnopts[] = {#if CONFIG_TEST "-dirty", "-lock_timeout", "-txn_timeout",#endif "-nosync", "-nowait", "-parent", "-sync", NULL }; enum txnopts {#if CONFIG_TEST TXNDIRTY, TXN_LOCK_TIMEOUT, TXN_TIMEOUT,#endif TXNNOSYNC, TXNNOWAIT, TXNPARENT, TXNSYNC }; DBTCL_INFO *ip; DB_TXN *parent; DB_TXN *txn; Tcl_Obj *res; db_timeout_t lk_time, tx_time; u_int32_t flag, lk_timeflag, tx_timeflag; int i, optindex, result, ret; char *arg, msg[MSG_SIZE], newname[MSG_SIZE]; result = TCL_OK; memset(newname, 0, MSG_SIZE); parent = NULL; flag = 0; lk_timeflag = tx_timeflag = 0; i = 2; while (i < objc) { if (Tcl_GetIndexFromObj(interp, objv[i], txnopts, "option", TCL_EXACT, &optindex) != TCL_OK) { return (IS_HELP(objv[i])); } i++; switch ((enum txnopts)optindex) {#ifdef CONFIG_TEST case TXNDIRTY: flag |= DB_DIRTY_READ; break; case TXN_LOCK_TIMEOUT: lk_timeflag = DB_SET_LOCK_TIMEOUT; goto getit; case TXN_TIMEOUT: tx_timeflag = DB_SET_TXN_TIMEOUT;getit: if (i >= objc) { Tcl_WrongNumArgs(interp, 2, objv, "?-txn_timestamp time?"); return (TCL_ERROR); } result = Tcl_GetLongFromObj(interp, objv[i++], (long *)(optindex == TXN_LOCK_TIMEOUT ? &lk_time : &tx_time)); if (result != TCL_OK) return (TCL_ERROR); break;#endif case TXNNOSYNC: FLAG_CHECK2(flag, DB_DIRTY_READ); flag |= DB_TXN_NOSYNC; break; case TXNNOWAIT: FLAG_CHECK2(flag, DB_DIRTY_READ); flag |= DB_TXN_NOWAIT; break; case TXNPARENT: if (i == objc) { Tcl_WrongNumArgs(interp, 2, objv, "?-parent txn?"); result = TCL_ERROR; break; } arg = Tcl_GetStringFromObj(objv[i++], NULL); parent = NAME_TO_TXN(arg); if (parent == NULL) { snprintf(msg, MSG_SIZE, "Invalid parent txn: %s\n", arg); Tcl_SetResult(interp, msg, TCL_VOLATILE); return (TCL_ERROR); } break; case TXNSYNC: FLAG_CHECK2(flag, DB_DIRTY_READ); flag |= DB_TXN_SYNC; break; } } snprintf(newname, sizeof(newname), "%s.txn%d", envip->i_name, envip->i_envtxnid); ip = _NewInfo(interp, NULL, newname, I_TXN); if (ip == NULL) { Tcl_SetResult(interp, "Could not set up info", TCL_STATIC); return (TCL_ERROR); } _debug_check(); ret = envp->txn_begin(envp, parent, &txn, flag); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "txn"); if (result == TCL_ERROR) _DeleteInfo(ip); else { /* * Success. Set up return. Set up new info * and command widget for this txn. */ envip->i_envtxnid++; if (parent) ip->i_parent = _PtrToInfo(parent); else ip->i_parent = envip; _SetInfoData(ip, txn); Tcl_CreateObjCommand(interp, newname, (Tcl_ObjCmdProc *)txn_Cmd, (ClientData)txn, NULL); res = Tcl_NewStringObj(newname, strlen(newname)); Tcl_SetObjResult(interp, res); if (tx_timeflag != 0) { ret = txn->set_timeout(txn, tx_time, tx_timeflag); if (ret != 0) { result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "set_timeout"); _DeleteInfo(ip); } } if (lk_timeflag != 0) { ret = txn->set_timeout(txn, lk_time, lk_timeflag); if (ret != 0) { result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "set_timeout"); _DeleteInfo(ip); } } } return (result);}/* * tcl_TxnStat -- * * PUBLIC: int tcl_TxnStat __P((Tcl_Interp *, int, * PUBLIC: Tcl_Obj * CONST*, DB_ENV *)); */inttcl_TxnStat(interp, objc, objv, envp) Tcl_Interp *interp; /* Interpreter */ int objc; /* How many arguments? */ Tcl_Obj *CONST objv[]; /* The argument objects */ DB_ENV *envp; /* Environment pointer */{ DBTCL_INFO *ip; DB_TXN_ACTIVE *p; DB_TXN_STAT *sp; Tcl_Obj *myobjv[2], *res, *thislist, *lsnlist; u_int32_t i; int myobjc, result, ret; result = TCL_OK; /* * No args for this. Error if there are some. */ if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); return (TCL_ERROR); } _debug_check(); ret = envp->txn_stat(envp, &sp, 0); result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "txn stat"); if (result == TCL_ERROR) return (result); /* * Have our stats, now construct the name value * list pairs and free up the memory. */ res = Tcl_NewObj(); /* * MAKE_STAT_LIST assumes 'res' and 'error' label. */ MAKE_STAT_LIST("Region size", sp->st_regsize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -