Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Semaphore handling, ATMI level
0003  *
0004  * @file sem.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 #include <ndrx_config.h>
0035 #include <string.h>
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <memory.h>
0039 #include <errno.h>
0040 #include <sys/sem.h>
0041 
0042 #include <lcfint.h>
0043 #include <atmi.h>
0044 #include <atmi_shm.h>
0045 #include <ndrstandard.h>
0046 #include <ndebug.h>
0047 #include <ndrxdcmn.h>
0048 #include <userlog.h>
0049 
0050 /* shm_* stuff, and mmap() */
0051 #include <sys/mman.h>
0052 #include <sys/types.h>
0053 /* exit() etc */
0054 #include <unistd.h>
0055 #include <fcntl.h>
0056 #include <sys/stat.h>
0057 #include <sys/ipc.h>
0058 
0059 #include <nstd_shm.h>
0060 /*---------------------------Externs------------------------------------*/
0061 /*---------------------------Macros-------------------------------------*/
0062 /*---------------------------Enums--------------------------------------*/
0063 /*---------------------------Typedefs-----------------------------------*/
0064 /*---------------------------Globals------------------------------------*/
0065 expublic ndrx_sem_t G_sem_svcop;              /* Service operations       */
0066 exprivate int M_init = EXFALSE;                 /* no init yet done         */
0067 
0068 /*---------------------------Statics------------------------------------*/
0069 /*---------------------------Prototypes---------------------------------*/
0070 extern int ndrx_sem_lock(ndrx_sem_t *sem, const char *msg, int sem_num);
0071 extern int ndrx_sem_unlock(ndrx_sem_t *sem, const char *msg, int sem_num);
0072 
0073 /**
0074  * Initialise prefix part, that is needed for shm...
0075  * @param ndrx_prefix
0076  * @return 
0077  */
0078 expublic int ndrxd_sem_init(char *q_prefix)
0079 {
0080     memset(&G_sem_svcop, 0, sizeof(G_sem_svcop));
0081     
0082     /* Service queue ops */
0083     G_sem_svcop.key = G_atmi_env.ipckey + NDRX_SEM_SVC_OPS;
0084     G_sem_svcop.nrsems = G_atmi_env.nrsems;
0085     /* have read locking for system v */
0086     G_sem_svcop.maxreaders = ndrx_G_libnstd_cfg.svqreadersmax;
0087     NDRX_LOG(log_debug, "Using service semaphore key: [%d]", 
0088             G_sem_svcop.key);
0089     
0090     M_init = EXTRUE;
0091     return EXSUCCEED;
0092 }
0093 
0094 /**
0095  * Open semaphore
0096  * @param create shall we only attach (do not open)
0097  * @return EXSUCCEED/EXFAIL
0098  */
0099 expublic int ndrx_sem_open_all(int create)
0100 {
0101     int ret=EXSUCCEED;
0102 
0103     if (create)
0104     {
0105         if (EXSUCCEED!=ndrx_sem_open(&G_sem_svcop, EXTRUE))
0106         {
0107             EXFAIL_OUT(ret);
0108         }
0109     }
0110     else
0111     {
0112         if (EXSUCCEED!=ndrx_sem_attach(&G_sem_svcop))
0113         {
0114             EXFAIL_OUT(ret);
0115         }
0116     }
0117     
0118 out:
0119     return ret;
0120 }
0121 
0122 /**
0123  * Closes all semaphore resources, generally ignores errors.
0124  * @return FAIL if something failed.
0125  */
0126 expublic int ndrxd_sem_close_all(void)
0127 {
0128     int ret=EXSUCCEED;
0129 
0130     ndrx_sem_close(&G_sem_svcop);
0131     
0132     return ret;
0133 }
0134 
0135 /**
0136  * Does delete all semaphore blocks.
0137  */
0138 expublic int ndrxd_sem_delete(void)
0139 {
0140     if (M_init)
0141     {
0142         ndrx_sem_remove(&G_sem_svcop, EXFALSE);
0143     }
0144     else
0145     {
0146         NDRX_LOG(log_error, "SHM library not initialized!");
0147         return EXFAIL;
0148     }
0149 
0150     return EXSUCCEED;
0151 }
0152 
0153 /**
0154  * Does delete all semaphore blocks.
0155  */
0156 expublic void ndrxd_sem_delete_with_init(char *q_prefix)
0157 {
0158     if (!M_init)
0159     {
0160         ndrxd_sem_init(q_prefix);
0161     }
0162     
0163     if (EXSUCCEED==ndrx_sem_open(&G_sem_svcop, EXTRUE))
0164     {
0165         ndrx_sem_remove(&G_sem_svcop, EXTRUE);
0166     }
0167 }
0168 
0169 /**
0170  * Attach to semaphore block.
0171  * @lev indicates the attach level (should it be service array only)?
0172  * @return 
0173  */
0174 expublic int ndrx_sem_attach_all(void)
0175 {
0176     int ret=EXSUCCEED;
0177    
0178     /**
0179      * Library not initialised
0180      */
0181     if (!M_init)
0182     {
0183         NDRX_LOG(log_error, "ndrx shm/sem library not initialised!");
0184         ret=EXFAIL;
0185         goto out;
0186     }
0187     
0188     if (EXSUCCEED!=ndrx_sem_attach(&G_sem_svcop))
0189     {
0190         ret=EXFAIL;
0191         goto out;
0192     }
0193     
0194 out:
0195    return ret;
0196 }
0197 
0198 /**
0199  * Lock service operation
0200  * @return 
0201  */
0202 expublic int ndrx_lock_svc_op(const char *msg)
0203 {
0204     return ndrx_sem_lock(&G_sem_svcop, msg, NDRX_SEM_SVC_GLOBAL_NUM);
0205 }
0206 
0207 /**
0208  * Unlock service operation
0209  * @return 
0210  */
0211 expublic int ndrx_unlock_svc_op(const char *msg)
0212 {
0213     return ndrx_sem_unlock(&G_sem_svcop, msg, NDRX_SEM_SVC_GLOBAL_NUM);
0214 }
0215 
0216 /**
0217  * Lock the access to specific service in shared mem
0218  * Only for poll() mode
0219  * @param svcnm service name
0220  * @param typ lock type NDRX_SEM_TYP_READ / NDRX_SEM_TYP_WRITE
0221  * @return 
0222  */
0223 expublic int ndrx_lock_svc_nm(char *svcnm, const char *msg, int typ)
0224 {
0225     int semnum = 1 + ndrx_hash_fn(svcnm) % (G_atmi_env.nrsems-1);
0226     return ndrx_sem_rwlock(&G_sem_svcop, semnum, typ);
0227 }
0228 
0229 /**
0230  * Unlock the access to service
0231  * @param svcnm
0232  * @param typ lock type NDRX_SEM_TYP_READ / NDRX_SEM_TYP_WRITE
0233  * @return 
0234  */
0235 expublic int ndrx_unlock_svc_nm(char *svcnm, const char *msg, int typ)
0236 {
0237     int semnum = 1 + ndrx_hash_fn(svcnm) % (G_atmi_env.nrsems-1);
0238     return ndrx_sem_rwunlock(&G_sem_svcop, semnum, typ);
0239 }
0240 
0241 
0242 /* vim: set ts=4 sw=4 et smartindent: */