summaryrefslogtreecommitdiff
path: root/db/dbinc/tcl_db.h
diff options
context:
space:
mode:
Diffstat (limited to 'db/dbinc/tcl_db.h')
-rw-r--r--db/dbinc/tcl_db.h261
1 files changed, 261 insertions, 0 deletions
diff --git a/db/dbinc/tcl_db.h b/db/dbinc/tcl_db.h
new file mode 100644
index 000000000..adfa94db9
--- /dev/null
+++ b/db/dbinc/tcl_db.h
@@ -0,0 +1,261 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999-2002
+ * Sleepycat Software. All rights reserved.
+ *
+ * Id: tcl_db.h,v 11.30 2002/08/06 06:11:22 bostic Exp
+ */
+
+#ifndef _DB_TCL_DB_H_
+#define _DB_TCL_DB_H_
+
+#define MSG_SIZE 100 /* Message size */
+
+enum INFOTYPE {
+ I_ENV, I_DB, I_DBC, I_TXN, I_MP, I_PG, I_LOCK, I_LOGC, I_NDBM, I_MUTEX };
+
+#define MAX_ID 8 /* Maximum number of sub-id's we need */
+#define DBTCL_PREP 64 /* Size of txn_recover preplist */
+
+#define DBTCL_DBM 1
+#define DBTCL_NDBM 2
+
+typedef struct _mutex_entry {
+ union {
+ struct {
+ DB_MUTEX real_m;
+ u_int32_t real_val;
+ } r;
+ /*
+ * This is here to make sure that each of the mutex structures
+ * are 16-byte aligned, which is required on HP architectures.
+ * The db_mutex_t structure might be >32 bytes itself, or the
+ * real_val might push it over the 32 byte boundary. The best
+ * we can do is use a 48 byte boundary.
+ */
+ char c[48];
+ } u;
+} _MUTEX_ENTRY;
+
+#define m u.r.real_m
+#define val u.r.real_val
+
+typedef struct _mutex_data {
+ DB_ENV *env;
+ REGINFO reginfo;
+ _MUTEX_ENTRY *marray;
+ size_t size;
+ u_int32_t n_mutex;
+} _MUTEX_DATA;
+
+/*
+ * Why use a home grown package over the Tcl_Hash functions?
+ *
+ * We could have implemented the stuff below without maintaining our
+ * own list manipulation, efficiently hashing it with the available
+ * Tcl functions (Tcl_CreateHashEntry, Tcl_GetHashValue, etc). I chose
+ * not to do so for these reasons:
+ *
+ * We still need the information below. Using the hashing only removes
+ * us from needing the next/prev pointers. We still need the structure
+ * itself because we need more than one value associated with a widget.
+ * We need to keep track of parent pointers for sub-widgets (like cursors)
+ * so we can correctly close. We need to keep track of individual widget's
+ * id counters for any sub-widgets they may have. We need to be able to
+ * associate the name/client data outside the scope of the widget.
+ *
+ * So, is it better to use the hashing rather than
+ * the linear list we have now? I decided against it for the simple reason
+ * that to access the structure would require two calls. The first is
+ * Tcl_FindHashEntry(table, key) and then, once we have the entry, we'd
+ * have to do Tcl_GetHashValue(entry) to get the pointer of the structure.
+ *
+ * I believe the number of simultaneous DB widgets in existence at one time
+ * is not going to be that large (more than several dozen) such that
+ * linearly searching the list is not going to impact performance in a
+ * noticable way. Should performance be impacted due to the size of the
+ * info list, then perhaps it is time to revisit this decision.
+ */
+typedef struct dbtcl_info {
+ LIST_ENTRY(dbtcl_info) entries;
+ Tcl_Interp *i_interp;
+ char *i_name;
+ enum INFOTYPE i_type;
+ union infop {
+ DB_ENV *envp;
+ void *anyp;
+ DB *dbp;
+ DBC *dbcp;
+ DB_TXN *txnp;
+ DB_MPOOLFILE *mp;
+ DB_LOCK *lock;
+ _MUTEX_DATA *mutex;
+ DB_LOGC *logc;
+ } un;
+ union data {
+ int anydata;
+ db_pgno_t pgno;
+ u_int32_t lockid;
+ } und;
+ union data2 {
+ int anydata;
+ size_t pagesz;
+ } und2;
+ DBT i_lockobj;
+ FILE *i_err;
+ char *i_errpfx;
+
+ /* Callbacks--Tcl_Objs containing proc names */
+ Tcl_Obj *i_btcompare;
+ Tcl_Obj *i_dupcompare;
+ Tcl_Obj *i_hashproc;
+ Tcl_Obj *i_rep_send;
+ Tcl_Obj *i_second_call;
+
+ /* Environment ID for the i_rep_send callback. */
+ Tcl_Obj *i_rep_eid;
+
+ struct dbtcl_info *i_parent;
+ int i_otherid[MAX_ID];
+} DBTCL_INFO;
+
+#define i_anyp un.anyp
+#define i_pagep un.anyp
+#define i_envp un.envp
+#define i_dbp un.dbp
+#define i_dbcp un.dbcp
+#define i_txnp un.txnp
+#define i_mp un.mp
+#define i_lock un.lock
+#define i_mutex un.mutex
+#define i_logc un.logc
+
+#define i_data und.anydata
+#define i_pgno und.pgno
+#define i_locker und.lockid
+#define i_data2 und2.anydata
+#define i_pgsz und2.pagesz
+
+#define i_envtxnid i_otherid[0]
+#define i_envmpid i_otherid[1]
+#define i_envlockid i_otherid[2]
+#define i_envmutexid i_otherid[3]
+#define i_envlogcid i_otherid[4]
+
+#define i_mppgid i_otherid[0]
+
+#define i_dbdbcid i_otherid[0]
+
+extern int __debug_on, __debug_print, __debug_stop, __debug_test;
+
+typedef struct dbtcl_global {
+ LIST_HEAD(infohead, dbtcl_info) g_infohead;
+} DBTCL_GLOBAL;
+#define __db_infohead __dbtcl_global.g_infohead
+
+extern DBTCL_GLOBAL __dbtcl_global;
+
+#define NAME_TO_ENV(name) (DB_ENV *)_NameToPtr((name))
+#define NAME_TO_DB(name) (DB *)_NameToPtr((name))
+#define NAME_TO_DBC(name) (DBC *)_NameToPtr((name))
+#define NAME_TO_TXN(name) (DB_TXN *)_NameToPtr((name))
+#define NAME_TO_MP(name) (DB_MPOOLFILE *)_NameToPtr((name))
+#define NAME_TO_LOCK(name) (DB_LOCK *)_NameToPtr((name))
+
+/*
+ * MAKE_STAT_LIST appends a {name value} pair to a result list
+ * that MUST be called 'res' that is a Tcl_Obj * in the local
+ * function. This macro also assumes a label "error" to go to
+ * in the even of a Tcl error. For stat functions this will
+ * typically go before the "free" function to free the stat structure
+ * returned by DB.
+ */
+#define MAKE_STAT_LIST(s,v) \
+do { \
+ result = _SetListElemInt(interp, res, (s), (v)); \
+ if (result != TCL_OK) \
+ goto error; \
+} while (0)
+
+/*
+ * MAKE_STAT_LSN appends a {name {LSNfile LSNoffset}} pair to a result list
+ * that MUST be called 'res' that is a Tcl_Obj * in the local
+ * function. This macro also assumes a label "error" to go to
+ * in the even of a Tcl error. For stat functions this will
+ * typically go before the "free" function to free the stat structure
+ * returned by DB.
+ */
+#define MAKE_STAT_LSN(s, lsn) \
+do { \
+ myobjc = 2; \
+ myobjv[0] = Tcl_NewLongObj((long)(lsn)->file); \
+ myobjv[1] = Tcl_NewLongObj((long)(lsn)->offset); \
+ lsnlist = Tcl_NewListObj(myobjc, myobjv); \
+ myobjc = 2; \
+ myobjv[0] = Tcl_NewStringObj((s), strlen(s)); \
+ myobjv[1] = lsnlist; \
+ thislist = Tcl_NewListObj(myobjc, myobjv); \
+ result = Tcl_ListObjAppendElement(interp, res, thislist); \
+ if (result != TCL_OK) \
+ goto error; \
+} while (0)
+
+/*
+ * MAKE_STAT_STRLIST appends a {name string} pair to a result list
+ * that MUST be called 'res' that is a Tcl_Obj * in the local
+ * function. This macro also assumes a label "error" to go to
+ * in the even of a Tcl error. For stat functions this will
+ * typically go before the "free" function to free the stat structure
+ * returned by DB.
+ */
+#define MAKE_STAT_STRLIST(s,s1) \
+do { \
+ result = _SetListElem(interp, res, (s), strlen(s), \
+ (s1), strlen(s1)); \
+ if (result != TCL_OK) \
+ goto error; \
+} while (0)
+
+/*
+ * FLAG_CHECK checks that the given flag is not set yet.
+ * If it is, it sets up an error message.
+ */
+#define FLAG_CHECK(flag) \
+do { \
+ if ((flag) != 0) { \
+ Tcl_SetResult(interp, \
+ " Only 1 policy can be specified.\n", \
+ TCL_STATIC); \
+ result = TCL_ERROR; \
+ break; \
+ } \
+} while (0)
+
+/*
+ * FLAG_CHECK2 checks that the given flag is not set yet or is
+ * only set to the given allowed value.
+ * If it is, it sets up an error message.
+ */
+#define FLAG_CHECK2(flag,val) \
+do { \
+ if (((flag) & ~(val)) != 0) { \
+ Tcl_SetResult(interp, \
+ " Only 1 policy can be specified.\n", \
+ TCL_STATIC); \
+ result = TCL_ERROR; \
+ break; \
+ } \
+} while (0)
+
+/*
+ * IS_HELP checks whether the arg we bombed on is -?, which is a help option.
+ * If it is, we return TCL_OK (but leave the result set to whatever
+ * Tcl_GetIndexFromObj says, which lists all the valid options. Otherwise
+ * return TCL_ERROR.
+ */
+#define IS_HELP(s) \
+ (strcmp(Tcl_GetStringFromObj(s,NULL), "-?") == 0) ? TCL_OK : TCL_ERROR
+
+#include "dbinc_auto/tcl_ext.h"
+#endif /* !_DB_TCL_DB_H_ */