Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Transaction Branch ID handler.
0003  *   Fore each RM there is seperate TID counter.
0004  *   The TIDs start with 0 which is default.
0005  *
0006  * @file btid.c
0007  */
0008 /* -----------------------------------------------------------------------------
0009  * Enduro/X Middleware Platform for Distributed Transaction Processing
0010  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0011  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0012  * This software is released under one of the following licenses:
0013  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0014  * See LICENSE file for full text.
0015  * -----------------------------------------------------------------------------
0016  * AGPL license:
0017  *
0018  * This program is free software; you can redistribute it and/or modify it under
0019  * the terms of the GNU Affero General Public License, version 3 as published
0020  * by the Free Software Foundation;
0021  *
0022  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0023  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0024  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0025  * for more details.
0026  *
0027  * You should have received a copy of the GNU Affero General Public License along 
0028  * with this program; if not, write to the Free Software Foundation, Inc.,
0029  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0030  *
0031  * -----------------------------------------------------------------------------
0032  * A commercial use license is available from Mavimax, Ltd
0033  * contact@mavimax.com
0034  * -----------------------------------------------------------------------------
0035  */
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <string.h>
0039 #include <errno.h>
0040 #include <regex.h>
0041 #include <utlist.h>
0042 
0043 #include <ndebug.h>
0044 #include <atmi.h>
0045 #include <atmi_int.h>
0046 #include <typed_buf.h>
0047 #include <ndrstandard.h>
0048 #include <ubf.h>
0049 #include <Exfields.h>
0050 #include <tperror.h>
0051 #include <exnet.h>
0052 #include <ndrxdcmn.h>
0053 
0054 #include "tmsrv.h"
0055 #include "../libatmisrv/srv_int.h"
0056 #include <xa_cmn.h>
0057 #include <atmi_int.h>
0058 /*---------------------------Externs------------------------------------*/
0059 /*---------------------------Macros-------------------------------------*/
0060 /*---------------------------Enums--------------------------------------*/
0061 /*---------------------------Typedefs-----------------------------------*/
0062 /*---------------------------Globals------------------------------------*/
0063 /*---------------------------Statics------------------------------------*/
0064 /*---------------------------Prototypes---------------------------------*/
0065 
0066 /**
0067  * This assumes big transaction is locked.
0068  * This just gets new branch qualifier
0069  * @param rmid resource manager id
0070  * @return new TID
0071  */
0072 expublic long tms_btid_gettid(atmi_xa_log_t *p_tl, short rmid)
0073 {
0074     long ret = p_tl->rmstatus[rmid-1].tidcounter;
0075     
0076     p_tl->rmstatus[rmid-1].tidcounter++;
0077     
0078     NDRX_LOG(log_info, "New Branch TID %ld for rmid %hd", ret, rmid);
0079     
0080     return ret;
0081 }
0082 
0083 /**
0084  * Find branch transaction by id
0085  * @param[in] p_tl Transaction entry
0086  * @param[in] rmid Resource manager id
0087  * @param[in] btid transaction id
0088  * @return transaction branch or NULL if not found
0089  */
0090 expublic atmi_xa_rm_status_btid_t *tms_btid_find(atmi_xa_log_t *p_tl, 
0091         short rmid, long btid)
0092 {
0093     atmi_xa_rm_status_btid_t *ret = NULL;
0094     
0095     EXHASH_FIND_LONG(p_tl->rmstatus[rmid-1].btid_hash, (&btid), ret);
0096     
0097     return ret;
0098 }
0099 
0100 
0101 /**
0102  * Add transaction branch to whole transaction
0103  * @param[in] p_tl transaction obj
0104  * @param[in] rmid resource manager id
0105  * @param[in] btid branch transaction id
0106  * @param[in] rmstatus Resource status
0107  * @param[in] rmerrorcode last error reported for btid
0108  * @param[in] rmreason reason code reported for btid
0109  * @param[out] bt pointer to allocated TID
0110  * @return EXSUCCEED/EXFAIL
0111  */    
0112 expublic int tms_btid_add(atmi_xa_log_t *p_tl, short rmid, 
0113             long btid, char rmstatus, int  rmerrorcode, short rmreason,
0114             atmi_xa_rm_status_btid_t **bt)
0115  {
0116     int ret = EXSUCCEED;
0117     *bt = NDRX_MALLOC(sizeof(atmi_xa_rm_status_btid_t));
0118     
0119     if (NULL==*bt)
0120     {
0121         NDRX_LOG(log_error, "Failed to malloc %d bytes: %s", 
0122                 sizeof(atmi_xa_rm_status_btid_t), strerror(errno));
0123         EXFAIL_OUT(ret);
0124     }
0125     
0126     (*bt)->rmid = rmid;
0127     (*bt)->btid = btid;
0128     (*bt)->rmstatus = rmstatus;
0129     (*bt)->rmerrorcode = rmerrorcode;
0130     (*bt)->rmreason = rmreason;
0131     
0132     EXHASH_ADD_LONG((p_tl->rmstatus[rmid-1].btid_hash), btid, (*bt));
0133     
0134     /* If end point self assigned transaction ID,
0135      * then step up the counter.
0136      * This might happen only if join is used and process have used
0137      * 0 tid 
0138      */
0139     if (p_tl->rmstatus[rmid-1].tidcounter <= btid)
0140     {
0141         p_tl->rmstatus[rmid-1].tidcounter = btid + 1;
0142     }
0143     
0144 out:
0145     return ret;
0146 }
0147 
0148 /**
0149  * Add or update branch tid entry
0150  * @param[in] p_tl transaction object
0151  * @param[in] rmid resource manager id, starting from 1
0152  * @param[in,out] btid branch tid
0153  * @param[in] rmstatus branch tid status
0154  * @param[in] rmerrorcode branch tid error code
0155  * @param[in] rmreason branch tid reasoncode
0156  * @param[out] exists did record exist? EXTRUE/EXFAIL
0157  * @param[out] bt btranch transaction object ptr output
0158  * @return EXSUCCEED/EXFAIL
0159  */
0160 expublic int tms_btid_addupd(atmi_xa_log_t *p_tl, short rmid, 
0161             long *btid, char rmstatus, int  rmerrorcode, short rmreason,
0162             int *exists, atmi_xa_rm_status_btid_t **bt)
0163 {
0164     int ret = EXSUCCEED;
0165     
0166     if (EXFAIL!=*btid)
0167     {   
0168         *bt = tms_btid_find(p_tl, rmid, *btid);
0169     }
0170     
0171     if (NULL!=(*bt))
0172     {
0173         /* only if new status is higher than old status
0174          * used by registering transaction
0175          * During the transaction we register with XA_RM_STATUS_NULL
0176          */
0177         if (XA_RM_STATUS_NULL!=rmstatus)
0178         {
0179             (*bt)->rmstatus = rmstatus;
0180             (*bt)->rmerrorcode = rmerrorcode;
0181             (*bt)->rmreason = rmreason;
0182         }
0183         
0184         if (NULL!=exists)
0185         {
0186             *exists = EXTRUE;
0187         }
0188     }
0189     else
0190     {
0191         if (EXFAIL==*btid)
0192         {
0193             /* generate new TID */
0194             *btid = tms_btid_gettid(p_tl, rmid);
0195         }
0196         
0197         ret = tms_btid_add(p_tl, rmid, *btid, rmstatus, rmerrorcode, rmreason, bt);
0198         
0199         if (NULL!=exists)
0200         {
0201             *exists = EXFALSE;
0202         }
0203         
0204     }
0205     
0206 out:
0207     return ret;
0208 }
0209 
0210 
0211 /* vim: set ts=4 sw=4 et smartindent: */