diff --git a/src/as/asCa.c b/src/as/asCa.c index e8facb0c6..719a175e0 100644 --- a/src/as/asCa.c +++ b/src/as/asCa.c @@ -69,8 +69,8 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000). #include #include -static int taskid=0; -static int caInitializing=FALSE; +LOCAL int taskid=0; +LOCAL int caInitializing=FALSE; extern ASBASE *pasbase; typedef struct { @@ -79,7 +79,29 @@ typedef struct { evid evid; } CAPVT; -static void connectCallback(struct connection_handler_args cha) +LOCAL void accessRightsCallback(struct access_rights_handler_args arha) +{ + chid chid = arha.chid; + ASGINP *pasginp; + ASG *pasg; + CAPVT *pcapvt; + int Ilocked=FALSE; + + if(!caInitializing) { + FASTLOCK(&asLock); + Ilocked = TRUE; + } + pasginp = (ASGINP *)ca_puser(chid); + pasg = (ASG *)pasginp->pasg; + pcapvt = pasginp->capvt; + if(!ca_read_access(chid)) { + pasg->inpBad |= (1<inpIndex); + if(!caInitializing) asComputeAsg(pasg); + } /*eventCallback will set inpBad false*/ + if(Ilocked) FASTUNLOCK(&asLock); +} + +LOCAL void connectCallback(struct connection_handler_args cha) { chid chid = cha.chid; ASGINP *pasginp; @@ -100,8 +122,8 @@ static void connectCallback(struct connection_handler_args cha) } /*eventCallback will set inpBad false*/ if(Ilocked) FASTUNLOCK(&asLock); } - -static void eventCallback(struct event_handler_args eha) + +LOCAL void eventCallback(struct event_handler_args eha) { ASGINP *pasginp; CAPVT *pcapvt; @@ -129,7 +151,7 @@ static void eventCallback(struct event_handler_args eha) if(Ilocked) FASTUNLOCK(&asLock); } -static void asCaTask(void) +LOCAL void asCaTask(void) { ASG *pasg; ASGINP *pasginp; @@ -149,6 +171,9 @@ static void asCaTask(void) SEVCHK(ca_build_and_connect(pasginp->inp,TYPENOTCONN,0, &pcapvt->chid,0,connectCallback,pasginp), "ca_build_and_connect"); + /*Note calls accessRightsCallback immediately called for local Pvs*/ + SEVCHK(ca_replace_access_rights_event(pcapvt->chid,accessRightsCallback), + "ca_replace_access_rights_event"); /*Note calls eventCallback immediately called for local Pvs*/ SEVCHK(ca_add_event(DBR_STS_DOUBLE,pcapvt->chid, eventCallback,pasginp,&pcapvt->evid), diff --git a/src/as/asDbLib.c b/src/as/asDbLib.c index eae09ca1b..a04d220f5 100644 --- a/src/as/asDbLib.c +++ b/src/as/asDbLib.c @@ -72,11 +72,11 @@ extern struct dbBase *pdbBase; static FILE *stream; #define BUF_SIZE 100 +FAST_LOCK asLock; static char *my_buffer; static char *my_buffer_ptr=NULL; static char *pacf=NULL; -FAST_LOCK asLock; -int asLockInit=TRUE; +static int asLockInit=TRUE; static int initTaskId=0; @@ -143,6 +143,44 @@ int asSetFilename(char *acf) return(0); } +static long asInitCommon(void) +{ + long status; + char buffer[BUF_SIZE]; + + if(!pacf) return(0); + if(asLockInit) { + FASTLOCKINIT(&asLock); + asLockInit = FALSE; + } + FASTLOCK(&asLock); + if(asActive)asCaStop(); + buffer[0] = 0; + my_buffer = buffer; + my_buffer_ptr = my_buffer; + stream = fopen(pacf,"r"); + if(!stream) { + errMessage(0,"asInit failure"); + FASTUNLOCK(&asLock); + return(-1); + } + status = asInitialize(my_yyinput); + if(fclose(stream)==EOF) errMessage(0,"asInit fclose failure"); + if(asActive) { + asDbAddRecords(); + asCaStart(); + } + FASTUNLOCK(&asLock); + return(status); +} + +int asInit(void) +{ + + asInitCommon(); + return(0); +} + static void wdCallback(ASDBCALLBACK *pcallback) { pcallback->status = S_asLib_InitFailed; @@ -154,35 +192,7 @@ static void asInitTask(ASDBCALLBACK *pcallback) long status; taskwdInsert(taskIdSelf(),wdCallback,pcallback); - if(asLockInit) { - FASTLOCKINIT(&asLock); - asLockInit = FALSE; - } - if(asActive)asCaStop(); - FASTLOCK(&asLock); - my_buffer = calloc(1,BUF_SIZE); - my_buffer_ptr = my_buffer; - if(!my_buffer) { - errMessage(0,"asInit malloc failure"); - FASTUNLOCK(&asLock); - taskwdRemove(taskIdSelf()); - return; - } - stream = fopen(pacf,"r"); - if(!stream) { - errMessage(0,"asInit failure"); - FASTUNLOCK(&asLock); - taskwdRemove(taskIdSelf()); - return; - } - status = asInitialize(my_yyinput); - if(fclose(stream)==EOF) errMessage(0,"asInit fclose failure"); - free((void *)my_buffer); - if(asActive) { - asDbAddRecords(); - asCaStart(); - } - FASTUNLOCK(&asLock); + status = asInitCommon(); taskwdRemove(taskIdSelf()); initTaskId = 0; if(pcallback) { @@ -190,10 +200,10 @@ static void asInitTask(ASDBCALLBACK *pcallback) callbackRequest(&pcallback->callback); } status = taskDelete(taskIdSelf()); - if(status!=OK) errMessage(0,"asInitTask: taskDelete Failure"); + if(status) errMessage(0,"asInitTask: taskDelete Failure"); } - -int asInit(ASDBCALLBACK *pcallback) + +int asInitAsyn(ASDBCALLBACK *pcallback) { if(!pacf) return(0); @@ -255,7 +265,7 @@ long asSubProcess(struct subRecord *precord) if(!precord->pact && precord->val==1.0) { db_post_events(precord,&precord->val,DBE_VALUE); callbackSetPriority(precord->prio,&pcallback->callback); - asInit(pcallback); + asInitAsyn(pcallback); precord->pact=TRUE; return(1); } diff --git a/src/as/asLibRoutines.c b/src/as/asLibRoutines.c index f11793ac9..47c01f1f6 100644 --- a/src/as/asLibRoutines.c +++ b/src/as/asLibRoutines.c @@ -170,8 +170,9 @@ long asAddMember(ASMEMBERPVT *pasMemberPvt,char *asgName) { ASGMEMBER *pasgmember; ASG *pgroup; + ASGCLIENT *pasgclient; - if(!asActive) return(0); + if(!asActive) return(S_asLib_asNotActive); if(*pasMemberPvt) { pasgmember = *pasMemberPvt; } else { @@ -196,6 +197,11 @@ long asAddMember(ASMEMBERPVT *pasMemberPvt,char *asgName) got_it: pasgmember->pasg = pgroup; ellAdd(&pgroup->memberList,(ELLNODE *)pasgmember); + pasgclient = (ASGCLIENT *)ellFirst(&pasgmember->clientList); + while(pasgclient) { + asCompute((ASCLIENTPVT)pasgclient); + pasgclient = (ASGCLIENT *)ellNext((ELLNODE *)pasgclient); + } return(0); } @@ -203,8 +209,9 @@ long asRemoveMember(ASMEMBERPVT *asMemberPvt) { ASGMEMBER *pasgmember; - if(!asActive) return(0); + if(!asActive) return(S_asLib_asNotActive); pasgmember = *asMemberPvt; + if(!pasgmember) return(S_asLib_badMember); if(ellCount(&pasgmember->clientList)>0) return(S_asLib_clientsExist); if(pasgmember->pasg) { ellDelete(&pasgmember->pasg->memberList,(ELLNODE *)pasgmember); @@ -222,11 +229,12 @@ long asChangeGroup(ASMEMBERPVT *asMemberPvt,char *newAsgName) ASGMEMBER *pasgmember; long status; - if(!asActive) return(0); + if(!asActive) return(S_asLib_asNotActive); + pasgmember = *asMemberPvt; + if(!pasgmember) return(S_asLib_badMember); #ifdef vxWorks FASTLOCK(&asLock); #endif - pasgmember = *asMemberPvt; if(pasgmember->pasg) { ellDelete(&pasgmember->pasg->memberList,(ELLNODE *)pasgmember); } else { @@ -255,9 +263,11 @@ void *asGetMemberPvt(ASMEMBERPVT asMemberPvt) void asPutMemberPvt(ASMEMBERPVT asMemberPvt,void *userPvt) { ASGMEMBER *pasgmember = asMemberPvt; + if(!asActive) return; if(!pasgmember) return; pasgmember->userPvt = userPvt; + return; } long asAddClient(ASCLIENTPVT *pasClientPvt,ASMEMBERPVT asMemberPvt, @@ -265,9 +275,12 @@ long asAddClient(ASCLIENTPVT *pasClientPvt,ASMEMBERPVT asMemberPvt, { ASGMEMBER *pasgmember = asMemberPvt; ASGCLIENT *pasgclient; + long status; - if(!asActive) return(0); + if(!asActive) return(S_asLib_asNotActive); + if(!pasgmember) return(S_asLib_badMember); pasgclient = freeListCalloc(freeListPvt); + if(!pasgclient) return(S_asLib_noMemory); *pasClientPvt = pasgclient; pasgclient->pasgMember = asMemberPvt; pasgclient->level = asl; @@ -289,7 +302,8 @@ long asChangeClient(ASCLIENTPVT asClientPvt,int asl,char *user,char *host) ASGCLIENT *pasgclient = asClientPvt; long status; - if(!asActive) return(0); + if(!asActive) return(S_asLib_asNotActive); + if(!pasgclient) return(S_asLib_badClient); pasgclient->level = asl; pasgclient->user = user; pasgclient->host = host; @@ -308,8 +322,8 @@ long asRemoveClient(ASCLIENTPVT *asClientPvt) ASGCLIENT *pasgclient = *asClientPvt; ASGMEMBER *pasgMember; - if(!asActive) return(0); - if(!pasgclient) return(0); + if(!asActive) return(S_asLib_asNotActive); + if(!pasgclient) return(S_asLib_badClient); #ifdef vxWorks FASTLOCK(&asLock); #endif @@ -330,17 +344,20 @@ long asRemoveClient(ASCLIENTPVT *asClientPvt) return(0); } -void asRegisterClientCallback(ASCLIENTPVT asClientPvt, +long asRegisterClientCallback(ASCLIENTPVT asClientPvt, ASCLIENTCALLBACK pcallback) { ASGCLIENT *pasgclient = asClientPvt; #ifdef vxWorks + if(!asActive) return(S_asLib_asNotActive); + if(!pasgclient) return(S_asLib_badClient); FASTLOCK(&asLock); pasgclient->pcallback = pcallback; (*pasgclient->pcallback)(pasgclient,asClientCOAR); FASTUNLOCK(&asLock); #endif + return(0); } void *asGetClientPvt(ASCLIENTPVT asClientPvt) @@ -364,6 +381,7 @@ long asComputeAllAsg(void) { ASG *pasg; + if(!asActive) return(S_asLib_asNotActive); pasg = (ASG *)ellFirst(&pasbase->asgList); while(pasg) { asComputeAsg(pasg); @@ -378,7 +396,7 @@ long asComputeAsg(ASG *pasg) ASGMEMBER *pasgmember; ASGCLIENT *pasgclient; - if(!asActive) return(0); + if(!asActive) return(S_asLib_asNotActive); pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); while(pasgrule) { double result; @@ -412,13 +430,19 @@ long asCompute(ASCLIENTPVT asClientPvt) { asAccessRights access=asNOACCESS; ASGCLIENT *pasgclient = asClientPvt; - ASGMEMBER *pasgMember = pasgclient->pasgMember; - ASG *pasg = pasgMember->pasg; + ASGMEMBER *pasgMember; + ASG *pasg; ASGRULE *pasgrule; - asAccessRights oldaccess=pasgclient->access; + asAccessRights oldaccess; GPHENTRY *pgphentry; - if(!pasg) return(0); + if(!asActive) return(S_asLib_asNotActive); + if(!pasgclient) return(S_asLib_badClient); + pasgMember = pasgclient->pasgMember; + if(!pasgMember) return(S_asLib_badMember); + pasg = pasgMember->pasg; + if(!pasg) return(S_asLib_badAsg); + oldaccess=pasgclient->access; pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); while(pasgrule) { if(access == asWRITE) break; @@ -791,7 +815,9 @@ int asDumpMem(char *asgname,void (*memcallback)(ASMEMBERPVT),int clients) int asDumpHash(void) { + if(!asActive) return(0); gphDump(pasbase->phash); + return(0); } /*Start of private routines*/