⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipc_saf.c

📁 API
💻 C
字号:
/*
 *	有关存储转发的共享内存及信号灯操作
 *
 * SAF,SWITCHSRV用于控制交易的时序性
 *
 * 周国祥	2001/06/15 最后修改
 */
#include <signal.h>
#include <setjmp.h>
#include "public.h"
#include "saf_shm.h"
#include "macro_def.h"
#include "mytools.h"

char	*get_workdir();

int _saf_shmid;
int _saf_semid;

void saf_lock_read();
void saf_unlock_read();
void saf_lock_write();
void saf_unlock_write();

static struct sembuf semb[] = {
				0 , -1 , 0 ,
				1 , -1 , SEM_UNDO ,
				1 , 1 , SEM_UNDO ,
				2 ,  0 , 0 
};

SAF_HEAD	*saf_head;
SAF_CARD	*saf_card;
SAF_ITEM	*saf_item;

int get_ipc_saf ()
{
	char dir[200];
	key_t SHMKEY;
	key_t SEMKEY;
	static char	have_get_ipc = 0;

	if (have_get_ipc)
		return SUCC;

	sprintf ( dir , "%s/%s" , get_workdir(), SAF_KEYFILE );
	
	SHMKEY = ftok ( dir , 1 );
	SEMKEY = ftok ( dir , 1 );
	
	if ( SHMKEY < 0 || SEMKEY < 0 ) {
		return FAIL;
	}
	
	if ((_saf_shmid = shmget(SHMKEY, sizeof(SAF_HEAD) * MAX_HEAD + sizeof(SAF_CARD) * MAX_CARD + sizeof(SAF_ITEM) * MAX_ITEM, PERMS)) < 0 ) {
		return FAIL;
	}

	if ((saf_head = (SAF_HEAD *)shmat(_saf_shmid, (char *)0, 0)) == (SAF_HEAD *)-1) {
		return FAIL;
	}
	saf_card = (SAF_CARD *)(saf_head + MAX_HEAD);
	saf_item = (SAF_ITEM *)(saf_card + MAX_CARD);
	
errcall(DEBUG, "XXXXsaf_head=%x, saf_card=%x, saf_item=%x", saf_head, saf_card, saf_item);
	if ((_saf_semid = semget(SEMKEY, 3, PERMS)) < 0 ) {
		return FAIL;
	}
	
	have_get_ipc = 1;
	return SUCC;
}

int init_ipc_saf ()
{
	char dir[200];
	key_t SHMKEY;
	key_t SEMKEY;
	int i;
	SAF_HEAD *s_head;
	SAF_CARD *c_head;
	SAF_ITEM *i_head;
	time_t	tm;

	sprintf(dir, "%s/%s", get_workdir(), SAF_KEYFILE);

	SHMKEY = ftok ( dir , 1 );
	SEMKEY = ftok ( dir , 1 );
	
	if ( SHMKEY < 0 || SEMKEY < 0 ) 
		return FAIL;
	
	if ((_saf_shmid = shmget(SHMKEY, sizeof(SAF_HEAD) * MAX_HEAD + sizeof(SAF_CARD) * MAX_CARD + sizeof(SAF_ITEM) * MAX_ITEM , IPC_CREAT|PERMS)) < 0 )
		return FAIL;

	if ((saf_head = (SAF_HEAD *)shmat(_saf_shmid, (char *)0, 0)) == (SAF_HEAD *)-1)
		return FAIL;
	
/*
	memset (saf_head, '\0', sizeof(SAF_HEAD) * MAX_HEAD + sizeof(SAF_CARD) * MAX_CARD + sizeof(SAF_ITEM) * MAX_ITEM);
*/
	
	saf_card = (SAF_CARD *)(saf_head + MAX_HEAD);
	saf_item = (SAF_ITEM *)(saf_card + MAX_CARD);

	time(&tm);
	for (i = 0; i < MAX_HEAD; i++) {
		s_head = saf_head + i;

		s_head->card_cnt = 0;
		s_head->rcv_bankid[0] = '\0';
		s_head->rcv_hostid[0] = '\0';
		strcpy(s_head->ret_code, "00");
		s_head->ret_time = tm;
		s_head->err_cnt = 0;
		s_head->chead = NULL;
	}

	for (i = 0; i < MAX_CARD; i++) {
		c_head = saf_card + i;

		c_head->flag = 0;
		c_head->pid = -1;
		c_head->item_cnt = 0;
		c_head->card_id[0] = '\0';
		strcpy(c_head->ret_code, "00");
		c_head->ret_time = tm;
		c_head->err_cnt = 0;
		c_head->next = NULL;
		c_head->prev = NULL;
		c_head->ihead = NULL;
	}

	for (i = 0; i < MAX_ITEM; i++) {
		i_head = saf_item + i;

		i_head->flag = 0;
		memset(&(i_head->saf_pub), '\0', sizeof(PUBLIC));
		i_head->next = NULL;
		i_head->prev = NULL;
	}

	if ((_saf_semid = semget(SEMKEY, 3, IPC_CREAT|PERMS)) < 0 ) 
		return FAIL;
	
	semctl ( _saf_semid , 0 , SETVAL , 1 );	/* 用于置读写锁 */
	semctl ( _saf_semid , 1 , SETVAL , 0 );	/* 用于读锁 */
	semctl ( _saf_semid , 2 , SETVAL , 0 ); /* 用于写锁 */

	return SUCC;
}

int clear_ipc_saf ()
{
	SAF_HEAD *s_head;
	SAF_CARD *c_head;
	SAF_ITEM *i_head;
	time_t	tm;
	int	i;

	time(&tm);
/****
	saf_lock_write();
****/

	for (i = 0; i < MAX_HEAD; i++) {
		s_head = saf_head + i;

		s_head->card_cnt = 0;
		s_head->rcv_bankid[0] = '\0';
		s_head->rcv_hostid[0] = '\0';
		strcpy(s_head->ret_code, "00");
		s_head->ret_time = tm;
		s_head->err_cnt = 0;
		s_head->chead = NULL;
	}

	for (i = 0; i < MAX_CARD; i++) {
		c_head = saf_card + i;

		c_head->flag = 0;
		c_head->pid = -1;
		c_head->item_cnt = 0;
		c_head->card_id[0] = '\0';
		strcpy(c_head->ret_code, "00");
		c_head->ret_time = tm;
		c_head->err_cnt = 0;
		c_head->next = NULL;
		c_head->prev = NULL;
		c_head->ihead = NULL;
	}

	for (i = 0; i < MAX_ITEM; i++) {
		i_head = saf_item + i;

		i_head->flag = 0;
		memset(&(i_head->saf_pub), '\0', sizeof(PUBLIC));
		i_head->next = NULL;
		i_head->prev = NULL;
	}

	semctl ( _saf_semid , 0 , SETVAL , 1 );	/* 用于置读写锁 */
	semctl ( _saf_semid , 1 , SETVAL , 0 );	/* 用于读锁 */
	semctl ( _saf_semid , 2 , SETVAL , 0 ); /* 用于写锁 */

/*******
	saf_unlock_write();
*******/
	return SUCC;
}

int del_ipc_saf ()
{
	shmctl(_saf_shmid, IPC_RMID, (struct shmid_ds *)0);
	
	semctl(_saf_semid, 0, IPC_RMID, 0);
	
	return SUCC;
}

void saf_lock_read ()
{
	struct sembuf semb[] = {
		0 , -1 , SEM_UNDO ,
		2 , 0 , 0 ,		/* 看是否有在写操作, 等待变为0 */
		1 , 1 , SEM_UNDO ,	/* 增加一个读操作 */
		0 , 1 , SEM_UNDO ,
	};

	semop ( _saf_semid , &(semb[0]) , 1 );
	semop ( _saf_semid , &(semb[1]) , 1 );
	semop ( _saf_semid , &(semb[2]) , 1 );
	semop ( _saf_semid , &(semb[3]) , 1 );
}

void saf_unlock_read ()
{
	struct sembuf semb[] = {
		1 , -1 , SEM_UNDO ,
	};
	
	semop ( _saf_semid , &(semb[0]) , 1 );
}

void saf_lock_write ()
{
	struct sembuf semb[] = {
		0 , -1 , SEM_UNDO,
		1 , 0 , 0 ,		/* 看有无在读操作,等待读完 */
		2 , 0 , 0 ,		/* 看有无在写操作,等待写完 */
		2 , 1 , SEM_UNDO,	/* 增加一个写操作 */
		0 , 1 , SEM_UNDO
	};
	int v;
	
	semop ( _saf_semid , &(semb[0]) , 1 );
	semop ( _saf_semid , &(semb[1]) , 1 );
	semop ( _saf_semid , &(semb[2]) , 1 );
	semop ( _saf_semid , &(semb[3]) , 1 );
	semop ( _saf_semid , &(semb[4]) , 1 );
}

void saf_unlock_write ()
{	
	struct sembuf semb[] = {
		2 , -1 , SEM_UNDO
	};
	
	semop ( _saf_semid , &(semb[0]) , 1 );
}

#ifndef wyz_add_0614
/************************************************
功能:
	查找SAF内存表中是否有该方向的交易
输入:
	PUBLIC
返回:
	0	该方向没有SAF
	1	该方向有SAF
		如果pub->Resp_code!=SUCCESS,返回
		SYS_PAUSE,否则返回pub->Resp_code
*************************************************/
int search_saf(pub)
PUBLIC *pub;
{
	SAF_HEAD *s_head, *one_head = NULL;
	SAF_CARD *c_head, *one_card = NULL;
	SAF_ITEM *i_head, *one_item = NULL;
	int	c_idx, i_idx;
	PUBLIC *s_pub;
	int	i;

/**************zgx010714 moved to switchsrv
	if (get_ipc_saf() != SUCC) 
		return 0;
****************/

	saf_lock_read();

	/* 查找转发项的方向 */
	for (i = 0; i < MAX_HEAD; i++) {
		s_head = saf_head + i;
		if (s_head->card_cnt == 0)
			continue;
#ifdef zgx020111_modi
		if (!strcmp(s_head->rcv_bankid, pub->Rcv_bank_id) &&
		    !strcmp(s_head->rcv_hostid, pub->Rcv_host_id)) {
#else
		if (!strcmp(s_head->rcv_bankid, "9999") &&
		    !strcmp(s_head->rcv_hostid, "99")) {
#endif
			one_head = s_head;
			break;
		}
	}
	
	if (one_head == NULL) {
		/* 不存在此方向*/
		saf_unlock_read();
		return 0;
	}

	/* 查找此方向此卡的转发项 */
	c_idx = (int)one_head->chead;
	while (c_idx) {
		c_head = (SAF_CARD *)(saf_card + c_idx - 1);
		if (!strcmp(c_head->card_id, pub->Card_no)) {
			one_card = c_head;
			break;
		}
		c_idx = (int)c_head->next;
	}
	
	if (one_card == NULL) {
		/* 此方向没有此卡的转发项 */
		saf_unlock_read();
		return 0;
	}

#ifdef zgx010705_del
	/* 查找此PUBLIC对应的转发项 */
	i_idx = (int)one_card->ihead;
	while (i_idx) {
		i_head = &saf_item[i_idx - 1];
		s_pub = &(i_head->saf_pub);
		if (s_pub->Tran_type != ACQ_ADVICE &&
		    s_pub->Tran_type != ACQ_REV_ADVICE) {
			one_item = i_head;
			break;
		}
		i_idx = (int)i_head->next;
	}
	if (one_item == NULL) {
		/* 没有该项 */
		saf_unlock_read();
		return 0;
	}

#endif

#ifdef wyz_mod_020119
	if (!strcmp(one_card->ret_code, SYS_FAIL) ||
	    !strcmp(one_card->ret_code, NET_FAIL) ||
	    !strcmp(one_card->ret_code, TIME_OUT))
		strcpy(pub->Resp_code, one_card->ret_code);
	else if (!strcmp(one_card->ret_code, "00")) {
		/*
		 * 暂时当上次未出错,即放行。
		 * 如此可能会因正在处理的一笔有问题而影响到时序性
		 */
		saf_unlock_read();
		return 0;
	} else {
		strcpy(pub->Resp_code, SYS_PAUSE);
	}
#else
	strcpy(pub->Resp_code, RE_ENTER_TRANS);
#endif

	saf_unlock_read();
	return 1;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -