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

📄 gatepv.cc

📁 EPICS CA gateway, base on channel access protocol
💻 CC
📖 第 1 页 / 共 4 页
字号:
/*************************************************************************\* Copyright (c) 2002 The University of Chicago, as Operator of Argonne* National Laboratory.* Copyright (c) 2002 Berliner Speicherring-Gesellschaft fuer Synchrotron-* Strahlung mbH (BESSY).* Copyright (c) 2002 The Regents of the University of California, as* Operator of Los Alamos National Laboratory.* This file is distributed subject to a Software License Agreement found* in the file LICENSE that is included with this distribution. \*************************************************************************//*+********************************************************************* * * File:       gatePv.cc * Project:    CA Proxy Gateway * * Descr.:     PV = Client side (lower half) of Proxy Gateway Channel *             Handles all CAC related stuff: *             - Connections (and exception handling) *             - Monitors (value and ALH data) *             - Put operations (Gets are answered by the VC) * * Author(s):  J. Kowalkowski, J. Anderson, K. Evans (APS) *             R. Lange (BESSY) * *********************************************************************-*/#define DEBUG_TOTAL_PV 0#define DEBUG_PV_CON_LIST 0#define DEBUG_PV_LIST 0#define DEBUG_VC_DELETE 0#define DEBUG_GDD 0#define DEBUG_PUT 0#define DEBUG_BEAM 0#define DEBUG_ENUM 0#define DEBUG_DELAY 0#define DEBUG_SLIDER 0#define DEBUG_HISTORY 0#if DEBUG_HISTORY# define HISTNAME "GW:432:S05"# define HISTNUM 10#endif#define OMIT_CHECK_EVENT 1#include <stdio.h>#include <string.h>#include <fcntl.h>#include <time.h>#include <sys/types.h>#ifdef WIN32#else# include <unistd.h># include <sys/time.h>#endif#include "tsDLList.h"#include <gdd.h>#include <gddApps.h>#include <gddAppTable.h>#include <dbMapper.h>#include "gateResources.h"#include "gateServer.h"#include "gatePv.h"#include "gateVc.h"#include "gateAs.h"// extern "C" wrappers needed by CA routines for callbacksextern "C" {	extern void connectCB(CONNECT_ARGS args) {	// connection callback		gatePvData::connectCB(args);	}	extern void accessCB(ACCESS_ARGS args) {	// access security callback		gatePvData::accessCB(args);	}	extern void eventCB(EVENT_ARGS args) {      // value-changed callback		gatePvData::eventCB(args);	}    extern void alhCB(EVENT_ARGS args) {        // alh info value-changed callback		gatePvData::alhCB(args);	}	extern void putCB(EVENT_ARGS args) {        // put callback		gatePvData::putCB(args);	}	extern void getCB(EVENT_ARGS args) {        // get callback		gatePvData::getCB(args);	}}// quick access to global_resources#define GR global_resources#define GETDD(ap) gddApplicationTypeTable::AppTable().getDD(GR->ap)const char* const gatePvData::pv_state_names[] =	{ "dead", "inactive", "active", "connecting", "disconnected" };// ------------------------- gdd destructors --------------------------------// Apart from the FixedString destructor, which is definitely needed,// these are probably not necessary.  The default gddDestructor does// delete [] (aitUint8 *)v. (aitUint=char) Since delete calls free,// which casts the pointer to a char * anyway, our specific casts are// probably wasted.// Fixed Stringclass gateFixedStringDestruct : public gddDestructor{public:	gateFixedStringDestruct(void) { }	void run(void *v) { delete [] (aitFixedString *)v; }};// Enumclass gateEnumDestruct : public gddDestructor{public:	gateEnumDestruct(void) { }	void run(void *v) { delete [] (aitEnum16 *)v; }};// Intclass gateIntDestruct : public gddDestructor{public:	gateIntDestruct(void) { }	void run(void *v) { delete [] (aitInt32 *)v; }};// Char  (Default would also work here)class gateCharDestruct : public gddDestructor{public:	gateCharDestruct(void) { }	void run(void *v) { delete [] (aitInt8 *)v; }};// Floatclass gateFloatDestruct : public gddDestructor{public:	gateFloatDestruct(void) { }	void run(void *v) { delete [] (aitFloat32 *)v; }};// Doubleclass gateDoubleDestruct : public gddDestructor{public:	gateDoubleDestruct(void) { }	void run(void *v) { delete [] (aitFloat64 *)v; }};// Shortclass gateShortDestruct : public gddDestructor{public:	gateShortDestruct(void) { }	void run(void *v) { delete [] (aitInt16 *)v; }};// ------------------------- pv data methods ------------------------gatePvData::gatePvData(gateServer* m,gateAsEntry* pase,const char* name){	gateDebug2(5,"gatePvData(gateServer=%p,name=%s)\n",(void *)m,name);	initClear();	init(m,pase,name);#ifdef STAT_PVS	mrg->setStat(statPvTotal,++mrg->total_pv);#endif#if DEBUG_TOTAL_PV	printf("gatePvdata: name=%s total_pv=%ld total_alive=%ld\n",	  name,mrg->total_pv,mrg->total_alive);#endif#if DEBUG_HISTORY	if(!strncmp(HISTNAME,name,HISTNUM)) {		printf("%s gatePvData::gatePvData: %s state=%s\n",timeStamp(),name,		  getStateName());	}#endif}gatePvData::~gatePvData(void){	gateDebug1(5,"~gatePvData() name=%s\n",name());#ifdef STAT_PVS	switch(getState())	{	case gatePvDisconnect:		mrg->setStat(statDisconnected,--mrg->total_disconnected);		mrg->setStat(statUnconnected,--mrg->total_unconnected);		break;	case gatePvDead:		mrg->setStat(statDead,--mrg->total_dead);		mrg->setStat(statUnconnected,--mrg->total_unconnected);		break;	case gatePvConnect:		mrg->setStat(statConnecting,--mrg->total_connecting);		mrg->setStat(statUnconnected,--mrg->total_unconnected);		break;	case gatePvActive:		mrg->setStat(statActive,--mrg->total_active);		mrg->setStat(statAlive,--mrg->total_alive);		break;	case gatePvInactive:		mrg->setStat(statInactive,--mrg->total_inactive);		mrg->setStat(statAlive,--mrg->total_alive);		break;	}	mrg->setStat(statPvTotal,--mrg->total_pv);#endif#if DEBUG_TOTAL_PV	printf("~gatePvdata: name=%s total_pv=%ld total_alive=%ld\n",	  name(),mrg->total_pv),mrg->total_alive;#endif	if(vc) {		delete vc;		vc=NULL;	}	unmonitor();	alhUnmonitor();	status=ca_clear_channel(chID);	if(status != ECA_NORMAL) {	    fprintf(stderr,"%s ~gatePvData: ca_clear_channel failed for %s:\n"		  " %s\n",		  timeStamp(),	      name()?name():"Unknown",ca_message(status));	}	delete [] pv_name;	// Clear the callback_list;	gatePvCallbackId *id = NULL;	while((id=callback_list.first()))	{		callback_list.remove(*id);		delete id;	}	// Clear the async exist test list	gateAsyncE* asynce = NULL;	while((asynce=eio.first()))	{		asynce->removeFromQueue();	}}void gatePvData::initClear(void){	setVC(NULL);	status=0;	markNotMonitored();	markNoGetPending();	markAlhNotMonitored();	markAlhNoGetPending();	markNoAbort();	markAddRemoveNotNeeded();}void gatePvData::init(gateServer* m,gateAsEntry* pase, const char* name){	gateDebug2(5,"gatePvData::init(gateServer=%p,name=%s)\n",(void *)m,name);	gateDebug1(5,"gatePvData::init entry pattern=%s)\n",pase->pattern);	mrg=m;	asentry=pase;	setTimes();	status=0;	pv_name=strDup(name);	if(asentry==NULL)		status=-1;	else	{#ifdef USE_313		status=ca_search_and_connect(pv_name,&chID,::connectCB,this);#else		status=ca_create_channel(pv_name,::connectCB,this,		  CA_PRIORITY_DEFAULT,&chID);#endif		if(status != ECA_NORMAL) {			fprintf(stderr,"gatePvData::init: ca_search_and_connect for %s:\n"			  " %s\n",			  this->name()?this->name():"Unknown",ca_message(status));		}	}	if(status==ECA_NORMAL)	{		status=ca_replace_access_rights_event(chID,::accessCB);		setState(gatePvConnect);#ifdef STAT_PVS		mrg->setStat(statConnecting,++mrg->total_connecting);		mrg->setStat(statUnconnected,++mrg->total_unconnected);#endif		if(status==ECA_NORMAL)			status=0;		else			status=-1;	}	else	{		gateDebug0(5,"gatePvData::init() search and connect failed!\n");		setState(gatePvDead);#ifdef STAT_PVS		mrg->setStat(statDead,++mrg->total_dead);		mrg->setStat(statUnconnected,++mrg->total_unconnected);#endif		status=-1;	}		if(status)	{		// what do I do here? Nothing for now, let creator fix trouble	}	else	{		// Put PV into connecting list		status = mrg->conAdd(pv_name,*this);		if(status) fprintf(stderr,"%s Put into connecting list failed for %s\n",		  timeStamp(),pv_name);#if DEBUG_PV_CON_LIST		printf("%s gatePvData::init: [%lu|%lu|%lu,%lu|%lu,%lu,%lu]: name=%s\n",		  timeStamp(),		  mrg->total_vc,mrg->total_pv,mrg->total_active,mrg->total_inactive,		  mrg->total_connecting,mrg->total_dead,mrg->total_disconnected,#endif	}	#if OMIT_CHECK_EVENT#else	checkEvent(); // do ca_pend_event#endif}aitEnum gatePvData::nativeType(void) const{	return gddDbrToAit[fieldType()].type;}int gatePvData::activate(gateVcData* vcd){	gateDebug2(5,"gatePvData::activate(gateVcData=%p) name=%s\n",	  (void *)vcd,name());		int rc=-1;	#if DEBUG_DELAY		if(!strncmp("Xorbit",name(),6)) {			printf("%s gatePvData::activate: %s state=%d\n",timeStamp(),name(),			  getState());		}#endif#if DEBUG_HISTORY		if(!strncmp(HISTNAME,name(),HISTNUM)) {			printf("%s gatePvData::activate: %s state=%s\n",timeStamp(),name(),			  getStateName());		}#endif	switch(getState())	{	case gatePvInactive:		gateDebug1(10,"gatePvData::activate() %s PV\n",getStateName());		markAddRemoveNeeded();		vc=vcd;		setState(gatePvActive);#ifdef STAT_PVS		mrg->setStat(statActive,++mrg->total_active);		mrg->setStat(statInactive,--mrg->total_inactive);#endif		setActiveTime();		vc->setReadAccess(ca_read_access(chID)?aitTrue:aitFalse);		vc->setWriteAccess(ca_write_access(chID)?aitTrue:aitFalse);		if(ca_read_access(chID)) rc=get();		else rc=0;		break;	case gatePvDisconnect:	case gatePvDead:		gateDebug1(3,"gatePvData::activate() %s PV ?\n",getStateName());		vc=NULL; // NOTE: be sure vc does not respond		break;	case gatePvActive:		gateDebug1(2,"gatePvData::activate() %s PV ?\n",getStateName());		break;	case gatePvConnect:		// already pending, just return		gateDebug1(3,"gatePvData::activate() %s PV ?\n",getStateName());		markAddRemoveNeeded();		break;	}	return rc;}int gatePvData::deactivate(void){	gateDebug1(5,"gatePvData::deactivate() name=%s\n",name());#if DEBUG_VC_DELETE	printf("gatePvData::deactivate: %s\n",name());#endif	int rc=0;	switch(getState())	{	case gatePvActive:		gateDebug1(10,"gatePvData::deactivate() %s PV\n",getStateName());		unmonitor();		alhUnmonitor();		setState(gatePvInactive);#ifdef STAT_PVS		mrg->setStat(statActive,--mrg->total_active);		mrg->setStat(statInactive,++mrg->total_inactive);#endif		vc=NULL;		setInactiveTime();		break;	case gatePvConnect:		// delete from the connect pending list		gateDebug1(10,"gatePvData::deactivate() %s PV ?\n",getStateName());		markAddRemoveNotNeeded();		vc=NULL;		break;	default:		gateDebug1(3,"gatePvData::deactivate() %s PV ?\n",getStateName());		rc=-1;		break;	}	return rc;}// Called in the connectCB if ca_state is cs_connint gatePvData::life(void){	int rc=0;	event_count=0;	gateDebug1(5,"gatePvData::life() name=%s\n",name());#if DEBUG_DELAY	if(!strncmp("Xorbit",name(),6)) {		printf("%s gatePvData::life: loop_count=%d %s state=%d\n",		  timeStamp(),mrg->loop_count,name(),getState());	}#endif#if DEBUG_HISTORY

⌨️ 快捷键说明

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