00001 /*- 00002 * See the file LICENSE for redistribution information. 00003 * 00004 * Copyright (c) 1996, 1997, 1998, 1999, 2000 00005 * Sleepycat Software. All rights reserved. 00006 */ 00007 00008 #include "config.h" 00009 00010 #ifndef lint 00011 static const char revid[] = "$Id: xa__map_8c-source.html,v 1.1 2008年06月08日 10:25:51 sebdiaz Exp $"; 00012 #endif /* not lint */ 00013 00014 #ifndef NO_SYSTEM_INCLUDES 00015 #include <sys/types.h> 00016 00017 #include <errno.h> 00018 #include <string.h> 00019 #endif 00020 00021 #include "db_int.h" 00022 #include "txn.h" 00023 00024 /* 00025 * This file contains all the mapping information that we need to support 00026 * the DB/XA interface. 00027 */ 00028 00029 /* 00030 * CDB___db_rmid_to_env 00031 * Return the environment associated with a given XA rmid. 00032 * 00033 * PUBLIC: int CDB___db_rmid_to_env __P((int rmid, DB_ENV **envp)); 00034 */ 00035 int 00036 CDB___db_rmid_to_env(rmid, envp) 00037 int rmid; 00038 DB_ENV **envp; 00039 { 00040 DB_ENV *env; 00041 00042 env = TAILQ_FIRST(&DB_GLOBAL(db_envq)); 00043 if (env != NULL && env->xa_rmid == rmid) { 00044 *envp = env; 00045 return (0); 00046 } 00047 00048 /* 00049 * When we map an rmid, move that environment to be the first one in 00050 * the list of environments, so we acquire the correct environment 00051 * in DB->open. 00052 */ 00053 for (; env != NULL; env = TAILQ_NEXT(env, links)) 00054 if (env->xa_rmid == rmid) { 00055 TAILQ_REMOVE(&DB_GLOBAL(db_envq), env, links); 00056 TAILQ_INSERT_HEAD(&DB_GLOBAL(db_envq), env, links); 00057 *envp = env; 00058 return (0); 00059 } 00060 00061 return (1); 00062 } 00063 00064 /* 00065 * CDB___db_xid_to_txn 00066 * Return the txn that corresponds to this XID. 00067 * 00068 * PUBLIC: int CDB___db_xid_to_txn __P((DB_ENV *, XID *, size_t *)); 00069 */ 00070 int 00071 CDB___db_xid_to_txn(dbenv, xid, offp) 00072 DB_ENV *dbenv; 00073 XID *xid; 00074 size_t *offp; 00075 { 00076 DB_TXNMGR *mgr; 00077 DB_TXNREGION *tmr; 00078 struct __txn_detail *td; 00079 00080 mgr = dbenv->tx_handle; 00081 tmr = mgr->reginfo.primary; 00082 00083 /* 00084 * Search the internal active transaction table to find the 00085 * matching xid. If this is a performance hit, then we 00086 * can create a hash table, but I doubt it's worth it. 00087 */ 00088 R_LOCK(dbenv, &mgr->reginfo); 00089 for (td = SH_TAILQ_FIRST(&tmr->active_txn, __txn_detail); 00090 td != NULL; 00091 td = SH_TAILQ_NEXT(td, links, __txn_detail)) 00092 if (memcmp(xid->data, td->xid, XIDDATASIZE) == 0) 00093 break; 00094 R_UNLOCK(dbenv, &mgr->reginfo); 00095 00096 if (td == NULL) 00097 return (EINVAL); 00098 00099 *offp = R_OFFSET(&mgr->reginfo, td); 00100 return (0); 00101 } 00102 00103 /* 00104 * CDB___db_map_rmid 00105 * Create a mapping between the specified rmid and environment. 00106 * 00107 * PUBLIC: int CDB___db_map_rmid __P((int, DB_ENV *)); 00108 */ 00109 int 00110 CDB___db_map_rmid(rmid, env) 00111 int rmid; 00112 DB_ENV *env; 00113 { 00114 env->xa_rmid = rmid; 00115 TAILQ_INSERT_TAIL(&DB_GLOBAL(db_envq), env, links); 00116 return (0); 00117 } 00118 00119 /* 00120 * CDB___db_unmap_rmid 00121 * Destroy the mapping for the given rmid. 00122 * 00123 * PUBLIC: int CDB___db_unmap_rmid __P((int)); 00124 */ 00125 int 00126 CDB___db_unmap_rmid(rmid) 00127 int rmid; 00128 { 00129 DB_ENV *e; 00130 00131 for (e = TAILQ_FIRST(&DB_GLOBAL(db_envq)); 00132 e->xa_rmid != rmid; 00133 e = TAILQ_NEXT(e, links)); 00134 00135 if (e == NULL) 00136 return (EINVAL); 00137 00138 TAILQ_REMOVE(&DB_GLOBAL(db_envq), e, links); 00139 return (0); 00140 } 00141 00142 /* 00143 * CDB___db_map_xid 00144 * Create a mapping between this XID and the transaction at 00145 * "off" in the shared region. 00146 * 00147 * PUBLIC: int CDB___db_map_xid __P((DB_ENV *, XID *, size_t)); 00148 */ 00149 int 00150 CDB___db_map_xid(env, xid, off) 00151 DB_ENV *env; 00152 XID *xid; 00153 size_t off; 00154 { 00155 REGINFO *infop; 00156 TXN_DETAIL *td; 00157 00158 infop = &((DB_TXNMGR *)env->tx_handle)->reginfo; 00159 td = (TXN_DETAIL *)R_ADDR(infop, off); 00160 00161 R_LOCK(env, infop); 00162 memcpy(td->xid, xid->data, XIDDATASIZE); 00163 td->bqual = (u_int32_t)xid->bqual_length; 00164 td->gtrid = (u_int32_t)xid->gtrid_length; 00165 td->format = (int32_t)xid->formatID; 00166 R_UNLOCK(env, infop); 00167 00168 return (0); 00169 } 00170 00171 /* 00172 * CDB___db_unmap_xid 00173 * Destroy the mapping for the specified XID. 00174 * 00175 * PUBLIC: void CDB___db_unmap_xid __P((DB_ENV *, XID *, size_t)); 00176 */ 00177 00178 void 00179 CDB___db_unmap_xid(env, xid, off) 00180 DB_ENV *env; 00181 XID *xid; 00182 size_t off; 00183 { 00184 TXN_DETAIL *td; 00185 00186 COMPQUIET(xid, NULL); 00187 00188 td = (TXN_DETAIL *)R_ADDR(&((DB_TXNMGR *)env->tx_handle)->reginfo, off); 00189 memset(td->xid, 0, sizeof(td->xid)); 00190 }