xa_map.c

Go to the documentation of this file.
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 }

Generated on Sun Jun 8 10:56:39 2008 for GNUmifluz by  doxygen 1.5.5