Fixed many bugs
This commit is contained in:
@@ -385,7 +385,10 @@ static void getOptions(DBADDR *paddr,void **poriginal,long *options,void *pflin)
|
||||
|
||||
struct rset *dbGetRset(struct dbAddr *paddr)
|
||||
{
|
||||
return(((struct dbFldDes *)paddr->pfldDes)->pdbRecDes->prset);
|
||||
struct dbFldDes *pfldDes = (struct dbFldDes *)paddr->pfldDes;
|
||||
|
||||
if(!pfldDes) return(0);
|
||||
return(pfldDes->pdbRecDes->prset);
|
||||
}
|
||||
|
||||
int dbIsValueField(struct dbFldDes *pdbFldDes)
|
||||
@@ -422,10 +425,14 @@ long dbScanPassive(dbCommon *pfrom, dbCommon *pto)
|
||||
/*KLUDGE: Following needed so that dbPutLink to PROC field works correctly*/
|
||||
long dbScanLink(dbCommon *pfrom, dbCommon *pto)
|
||||
{
|
||||
long status;
|
||||
long status;
|
||||
unsigned char pact;
|
||||
|
||||
if(pfrom && pfrom->ppn) dbNotifyAdd(pfrom,pto);
|
||||
pact = pfrom->pact;
|
||||
pfrom->pact = TRUE;
|
||||
status = dbProcess(pto);
|
||||
pfrom->pact = pact;
|
||||
return(status);
|
||||
}
|
||||
|
||||
@@ -846,7 +853,7 @@ long dbGet(DBADDR *paddr,short dbrType,void *pbuffer,long *options,
|
||||
|
||||
if(nRequest) {
|
||||
if(no_elements<(*nRequest)) *nRequest = no_elements;
|
||||
n = no_elements;
|
||||
n = *nRequest;
|
||||
} else {
|
||||
n = 1;
|
||||
}
|
||||
@@ -858,7 +865,9 @@ long dbGet(DBADDR *paddr,short dbrType,void *pbuffer,long *options,
|
||||
return(S_db_badDbrtype);
|
||||
}
|
||||
/* convert database field and place it in the buffer */
|
||||
if(pfl!=NULL) {
|
||||
if(n<=0) {
|
||||
;/*do nothing*/
|
||||
} else if(pfl!=NULL) {
|
||||
DBADDR localAddr;
|
||||
|
||||
localAddr = *paddr; /*Structure copy*/
|
||||
@@ -1069,7 +1078,7 @@ long dbPut(DBADDR *paddr,short dbrType,void *pbuffer,long nRequest)
|
||||
status = putSpecial(paddr,0);
|
||||
if(status) return(status);
|
||||
}
|
||||
if(no_elements<=1) {
|
||||
if((no_elements<=1) && (!prset || !(prset->put_array_info))) {
|
||||
status = (*dbFastPutConvertRoutine[dbrType][field_type])
|
||||
(pbuffer,paddr->pfield, paddr);
|
||||
} else {
|
||||
|
||||
@@ -89,10 +89,10 @@ void dbCaRemoveLink( struct link *plink)
|
||||
|
||||
if(!pca) return;
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
pca->link_action = CA_DELETE;
|
||||
if(!pca->link_action){/*If not on work list add it*/
|
||||
ellAdd(&caList,&pca->node);
|
||||
}
|
||||
pca->link_action = CA_DELETE;
|
||||
plink->value.pv_link.pvt = 0;
|
||||
pca->plink = 0;
|
||||
semGive(caListSem);
|
||||
@@ -133,7 +133,10 @@ long dbCaGetLink(struct link *plink,short dbrType, char *pdest,
|
||||
pca->pgetString = dbCalloc(MAX_STRING_SIZE,sizeof(char));
|
||||
semGive(pca->lock);
|
||||
semTake(caListSem,WAIT_FOREVER);
|
||||
pca->link_action = CA_MONITOR_STRING;
|
||||
if(!pca->link_action){/*If not on work list add it*/
|
||||
pca->link_action = CA_MONITOR_STRING;
|
||||
ellAdd(&caList,&pca->node);
|
||||
}
|
||||
semGive(caListSem);
|
||||
semGive(caWakeupSem);
|
||||
semStatus = semTake(pca->lock,WAIT_FOREVER);
|
||||
@@ -158,7 +161,8 @@ long dbCaGetLink(struct link *plink,short dbrType, char *pdest,
|
||||
if(!nelements || *nelements == 1){
|
||||
pconvert=
|
||||
dbFastGetConvertRoutine[dbDBRoldToDBFnew[pca->dbrType]][dbrType];
|
||||
status = (*(pconvert))(pca->pgetNative, pdest, 0);
|
||||
/*Ignore error routine*/
|
||||
(*(pconvert))(pca->pgetNative, pdest, 0);
|
||||
}else{
|
||||
unsigned long ntoget = *nelements;
|
||||
struct db_addr dbAddr;
|
||||
@@ -170,7 +174,8 @@ long dbCaGetLink(struct link *plink,short dbrType, char *pdest,
|
||||
dbAddr.pfield = pca->pgetNative;
|
||||
/*Following will only be used for pca->dbrType == DBR_STRING*/
|
||||
dbAddr.field_size = MAX_STRING_SIZE;
|
||||
status = (*(pconvert))(&dbAddr,pdest,nelements,ntoget,0);
|
||||
/*Ignore error routine*/
|
||||
(*(pconvert))(&dbAddr,pdest,ntoget,ntoget,0);
|
||||
}
|
||||
done:
|
||||
if(psevr) *psevr = pca->sevr;
|
||||
@@ -242,16 +247,15 @@ long dbCaPutLink(struct link *plink,short dbrType,
|
||||
semGive(caWakeupSem);
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
static void caEventHandler(struct event_handler_args arg)
|
||||
static void eventCallback(struct event_handler_args arg)
|
||||
{
|
||||
caLink *pca = (caLink *)arg.usr;
|
||||
struct link *plink;
|
||||
long size;
|
||||
|
||||
if(!pca) {
|
||||
epicsPrintf("caEventHandler why was arg.usr NULL\n");
|
||||
epicsPrintf("eventCallback why was arg.usr NULL\n");
|
||||
return;
|
||||
}
|
||||
plink = pca->plink;
|
||||
@@ -259,16 +263,18 @@ static void caEventHandler(struct event_handler_args arg)
|
||||
dbCommon *precord = 0;
|
||||
|
||||
if(plink) precord = (dbCommon *)plink->value.pv_link.precord;
|
||||
if(precord)
|
||||
epicsPrintf("dbCa: caEventHandler record %s error %s\n",
|
||||
if(precord) {
|
||||
if(arg.status!=ECA_NORDACCESS)
|
||||
epicsPrintf("dbCa: eventCallback record %s error %s\n",
|
||||
precord->name,ca_message(arg.status));
|
||||
else
|
||||
epicsPrintf("dbCa: caEventHandler error %s\n",
|
||||
} else {
|
||||
epicsPrintf("dbCa: eventCallback error %s\n",
|
||||
ca_message(arg.status));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(!arg.dbr) {
|
||||
epicsPrintf("caEventHandler why was arg.dbr NULL\n");
|
||||
epicsPrintf("eventCallback why was arg.dbr NULL\n");
|
||||
return;
|
||||
}
|
||||
semTake(pca->lock,WAIT_FOREVER);
|
||||
@@ -289,7 +295,7 @@ static void caEventHandler(struct event_handler_args arg)
|
||||
pca->gotInNative = TRUE;
|
||||
break;
|
||||
default:
|
||||
errMessage(-1,"dbCa: caEventHandler Logic Error\n");
|
||||
errMessage(-1,"dbCa: eventCallback Logic Error\n");
|
||||
break;
|
||||
}
|
||||
pca->sevr=(unsigned short)((struct dbr_sts_double *)arg.dbr)->severity;
|
||||
@@ -301,13 +307,36 @@ static void caEventHandler(struct event_handler_args arg)
|
||||
if(precord) {
|
||||
if((ppv_link->pvlMask&pvlOptCP)
|
||||
|| ((ppv_link->pvlMask&pvlOptCPP)&&(precord->scan==0)))
|
||||
scanOnce(ppv_link->precord);
|
||||
scanOnce(precord);
|
||||
}
|
||||
}
|
||||
semGive(pca->lock);
|
||||
}
|
||||
|
||||
static void dbCaLinkConnectionHandler(struct connection_handler_args arg)
|
||||
static void accessRightsCallback(struct access_rights_handler_args arg)
|
||||
{
|
||||
caLink *pca = (caLink *)ca_puser(arg.chid);
|
||||
struct link *plink;
|
||||
|
||||
if(!pca) {
|
||||
epicsPrintf("accessRightsCallback why was arg.usr NULL\n");
|
||||
return;
|
||||
}
|
||||
if(ca_read_access(arg.chid) || ca_write_access(arg.chid)) return;
|
||||
plink = pca->plink;
|
||||
if(plink) {
|
||||
struct pv_link *ppv_link = &(plink->value.pv_link);
|
||||
dbCommon *precord = ppv_link->precord;
|
||||
|
||||
if(precord) {
|
||||
if((ppv_link->pvlMask&pvlOptCP)
|
||||
|| ((ppv_link->pvlMask&pvlOptCPP)&&(precord->scan==0)))
|
||||
scanOnce(precord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void connectionCallback(struct connection_handler_args arg)
|
||||
{
|
||||
caLink *pca;
|
||||
int status;
|
||||
@@ -342,13 +371,13 @@ static void dbCaLinkConnectionHandler(struct connection_handler_args arg)
|
||||
pca->pputNative = dbCalloc(pca->nelements,element_size);
|
||||
status = ca_add_array_event(
|
||||
ca_field_type(arg.chid)+DBR_STS_STRING, ca_element_count(arg.chid),
|
||||
arg.chid, caEventHandler,pca,0.0,0.0,0.0,0);
|
||||
arg.chid, eventCallback,pca,0.0,0.0,0.0,0);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
|
||||
ca_message(status));
|
||||
if(pca->pgetString) {
|
||||
status = ca_add_array_event(DBR_STS_STRING,1,
|
||||
arg.chid, caEventHandler,pca,0.0,0.0,0.0,0);
|
||||
arg.chid, eventCallback,pca,0.0,0.0,0.0,0);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
|
||||
ca_message(status));
|
||||
@@ -385,10 +414,17 @@ void dbCaTask()
|
||||
status = ca_search_and_connect(
|
||||
pca->plink->value.pv_link.pvname,
|
||||
&(pca->chid),
|
||||
dbCaLinkConnectionHandler,(void *)pca);
|
||||
if(status!=ECA_NORMAL)
|
||||
connectionCallback,(void *)pca);
|
||||
if(status!=ECA_NORMAL) {
|
||||
epicsPrintf("dbCaTask ca_search_and_connect %s\n",
|
||||
ca_message(status));
|
||||
break;
|
||||
}
|
||||
status = ca_replace_access_rights_event(pca->chid,
|
||||
accessRightsCallback);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_replace_access_rights_event %s\n",
|
||||
ca_message(status));
|
||||
break;
|
||||
case CA_DELETE:
|
||||
if(pca->chid) ca_clear_channel(pca->chid);
|
||||
@@ -422,7 +458,7 @@ void dbCaTask()
|
||||
case CA_MONITOR_STRING:
|
||||
if(ca_state(pca->chid) == cs_conn){
|
||||
status = ca_add_array_event(DBR_STS_STRING,1,
|
||||
pca->chid, caEventHandler,pca,0.0,0.0,0.0,0);
|
||||
pca->chid, eventCallback,pca,0.0,0.0,0.0,0);
|
||||
if(status!=ECA_NORMAL)
|
||||
epicsPrintf("dbCaTask ca_add_array_event %s\n",
|
||||
ca_message(status));
|
||||
|
||||
@@ -45,9 +45,8 @@
|
||||
#include <recSup.h>
|
||||
#include <recGbl.h>
|
||||
|
||||
|
||||
/* DATABASE ACCESS GET CONVERSION SUPPORT */
|
||||
|
||||
|
||||
static long getStringString (
|
||||
DBADDR *paddr, void *pto, long nRequest, long no_elements, long offset)
|
||||
{
|
||||
@@ -90,15 +89,21 @@ static long getStringChar(
|
||||
if(sscanf(psrc,"%hd",&value) == 1) {
|
||||
*pbuffer = (char)value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = '0';
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%hd",&value) == 1) {
|
||||
*pbuffer = (char)value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = '0';
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -121,15 +126,21 @@ static long getStringUchar(
|
||||
if(sscanf(psrc,"%hu",&value) == 1) {
|
||||
*pbuffer = (unsigned char)value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = '0';
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%hu",&value) == 1) {
|
||||
*pbuffer = (unsigned char)value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = '0';
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -152,15 +163,21 @@ static long getStringShort(
|
||||
if(sscanf(psrc,"%hd",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%hd",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -183,15 +200,21 @@ static long getStringUshort(
|
||||
if(sscanf(psrc,"%hu",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%hu",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -214,15 +237,21 @@ static long getStringLong(
|
||||
if(sscanf(psrc,"%ld",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%ld",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -239,21 +268,29 @@ static long getStringUlong(
|
||||
{
|
||||
unsigned long *pbuffer = (unsigned long *)pto;
|
||||
char *psrc=(char *)paddr->pfield;
|
||||
unsigned long value;
|
||||
double value;
|
||||
|
||||
/*Convert to double first so that numbers like 1.0e3 convert properly*/
|
||||
/*Problem was old database access said to get unsigned long as double*/
|
||||
if(nRequest==1 && offset==0) {
|
||||
if(sscanf(psrc,"%lu",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
if(sscanf(psrc,"%lf",&value) == 1) {
|
||||
*pbuffer = (unsigned long)value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%lu",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
if(sscanf(psrc,"%lf",&value) == 1) {
|
||||
*pbuffer = (unsigned long)value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -276,16 +313,21 @@ static long getStringFloat(
|
||||
if(sscanf(psrc,"%f",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0.0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%f",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0.0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -308,16 +350,21 @@ static long getStringDouble(
|
||||
if(sscanf(psrc,"%lf",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
return(0);
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0.0;
|
||||
return(0);
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
psrc += MAX_STRING_SIZE*offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(psrc,"%lf",&value) == 1) {
|
||||
*pbuffer = value;
|
||||
} else if(strlen(psrc) == 0) {
|
||||
*pbuffer = 0.0;
|
||||
} else {
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
pbuffer++;
|
||||
if(++offset==no_elements)
|
||||
@@ -1504,9 +1551,10 @@ static long getFloatString(
|
||||
float *psrc=(float *)(paddr->pfield);
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
|
||||
if((prset=dbGetRset(paddr)) && (prset->get_precision))
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
if(prset && (prset->get_precision))
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
@@ -1627,17 +1675,14 @@ static long getFloatUlong(
|
||||
{
|
||||
unsigned long *pbuffer = (unsigned long *)pto;
|
||||
float *psrc=(float *)(paddr->pfield);
|
||||
long ltemp; /*vxWorks does not support float to unsigned long*/
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
ltemp = *psrc;
|
||||
*pbuffer = ltemp;
|
||||
*pbuffer = *psrc;
|
||||
return(0);
|
||||
}
|
||||
psrc += offset;
|
||||
while (nRequest) {
|
||||
ltemp = *psrc++;
|
||||
*pbuffer++ = ltemp;
|
||||
*pbuffer++ = *psrc++;
|
||||
if(++offset==no_elements) psrc=(float *)paddr->pfield;
|
||||
nRequest--;
|
||||
}
|
||||
@@ -1708,9 +1753,10 @@ static long getDoubleString(
|
||||
double *psrc=(double *)(paddr->pfield);
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
|
||||
if((prset=dbGetRset(paddr)) && (prset->get_precision))
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
if(prset && (prset->get_precision))
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
@@ -1831,17 +1877,14 @@ static long getDoubleUlong(
|
||||
{
|
||||
unsigned long *pbuffer = (unsigned long *)pto;
|
||||
double *psrc=(double *)(paddr->pfield);
|
||||
long ltemp; /*vxWorks does not support double to unsigned long*/
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
ltemp = *psrc;
|
||||
*pbuffer = ltemp;
|
||||
*pbuffer = *psrc;
|
||||
return(0);
|
||||
}
|
||||
psrc += offset;
|
||||
while (nRequest) {
|
||||
ltemp = *psrc++;
|
||||
*pbuffer++ = ltemp;
|
||||
*pbuffer++ = *psrc++;
|
||||
if(++offset==no_elements) psrc=(double *)paddr->pfield;
|
||||
nRequest--;
|
||||
}
|
||||
@@ -2268,21 +2311,19 @@ static long putStringUshort(
|
||||
{
|
||||
char *pbuffer = (char *)pfrom;
|
||||
unsigned short *pdest=(unsigned short *)paddr->pfield;
|
||||
float value;
|
||||
unsigned short value;
|
||||
|
||||
/*Convert to float first so that numbers like 1.0e3 convert properly*/
|
||||
/*Problem was old database access said to get unsigned short as float*/
|
||||
if(nRequest==1 && offset==0) {
|
||||
if(sscanf(pbuffer,"%f",&value) == 1) {
|
||||
*pdest = (unsigned short)value;
|
||||
if(sscanf(pbuffer,"%hu",&value) == 1) {
|
||||
*pdest = value;
|
||||
return(0);
|
||||
}
|
||||
else return(-1);
|
||||
}
|
||||
pdest += offset;
|
||||
while (nRequest) {
|
||||
if(sscanf(pbuffer,"%f",&value) == 1) {
|
||||
*pdest = (unsigned short)value;
|
||||
if(sscanf(pbuffer,"%hu",&value) == 1) {
|
||||
*pdest = value;
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
@@ -3721,10 +3762,11 @@ static long putFloatString(
|
||||
char *pdest=(char *)(paddr->pfield);
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
short size=paddr->field_size;
|
||||
|
||||
if((prset=dbGetRset(paddr)) && (prset->get_precision))
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
if(prset && (prset->get_precision))
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
@@ -3846,17 +3888,14 @@ static long putFloatUlong(
|
||||
{
|
||||
float *pbuffer = (float *)pfrom;
|
||||
unsigned long *pdest=(unsigned long *)(paddr->pfield);
|
||||
long ltemp;/*vxWorks does not support float to unsigned long*/
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
ltemp = *pbuffer;
|
||||
*pdest = ltemp;
|
||||
*pdest = *pbuffer;
|
||||
return(0);
|
||||
}
|
||||
pdest += offset;
|
||||
while (nRequest) {
|
||||
ltemp = *pbuffer++;
|
||||
*pdest++ = ltemp;
|
||||
*pdest++ = *pbuffer++;
|
||||
if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield;
|
||||
nRequest--;
|
||||
}
|
||||
@@ -3927,10 +3966,11 @@ static long putDoubleString(
|
||||
char *pdest=(char *)(paddr->pfield);
|
||||
long status = 0;
|
||||
int precision = 0;
|
||||
struct rset *prset;
|
||||
struct rset *prset = 0;
|
||||
short size=paddr->field_size;
|
||||
|
||||
if((prset=dbGetRset(paddr)) && (prset->get_precision))
|
||||
if(paddr) prset = dbGetRset(paddr);
|
||||
if(prset && (prset->get_precision))
|
||||
status = (*prset->get_precision)(paddr,&precision);
|
||||
else
|
||||
status=S_db_precision;
|
||||
@@ -4052,17 +4092,14 @@ static long putDoubleUlong(
|
||||
{
|
||||
double *pbuffer = (double *)pfrom;
|
||||
unsigned long *pdest=(unsigned long *)(paddr->pfield);
|
||||
long ltemp;/*vxWorks does not support double to unsigned long*/
|
||||
|
||||
if(nRequest==1 && offset==0) {
|
||||
ltemp = *pbuffer;
|
||||
*pdest = ltemp;
|
||||
*pdest = *pbuffer;
|
||||
return(0);
|
||||
}
|
||||
pdest += offset;
|
||||
while (nRequest) {
|
||||
ltemp = *pbuffer++;
|
||||
*pdest++ = ltemp;
|
||||
*pdest++ = *pbuffer++;
|
||||
if(++offset==no_elements) pdest=(unsigned long *)paddr->pfield;
|
||||
nRequest--;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,10 @@ static long cvt_st_c(
|
||||
*to = (char) value;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(strlen(from) == 0) {
|
||||
*to = '0';
|
||||
return(0);
|
||||
}
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
|
||||
@@ -125,10 +128,14 @@ static long cvt_st_uc(
|
||||
unsigned char *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
short value;
|
||||
unsigned short value;
|
||||
|
||||
if (sscanf(from, "%hu", &value) == 1) {
|
||||
*to = (unsigned char) value;
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = '0';
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -147,6 +154,10 @@ static long cvt_st_s(
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
@@ -157,12 +168,16 @@ static long cvt_st_us(
|
||||
unsigned short *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
short value;
|
||||
unsigned short value;
|
||||
|
||||
if (sscanf(from, "%hu", &value) == 1) {
|
||||
*to = (unsigned short) value;
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
@@ -179,6 +194,10 @@ static long cvt_st_l(
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
@@ -189,10 +208,16 @@ static long cvt_st_ul(
|
||||
unsigned long *to,
|
||||
struct dbAddr *paddr)
|
||||
{
|
||||
unsigned long value;
|
||||
double value;
|
||||
|
||||
if (sscanf(from, "%lu", &value) == 1) {
|
||||
*to = value;
|
||||
/*Convert to double first so that numbers like 1.0e3 convert properly*/
|
||||
/*Problem was old database access said to get unsigned long as double*/
|
||||
if (sscanf(from, "%lf", &value) == 1) {
|
||||
*to = (unsigned long)value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -211,6 +236,10 @@ static long cvt_st_f(
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0.0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
@@ -227,6 +256,10 @@ static long cvt_st_d(
|
||||
*to = value;
|
||||
return(0);
|
||||
}
|
||||
if(strlen(from) == 0) {
|
||||
*to = 0.0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(-1); /* Change to SYMBOL */
|
||||
}
|
||||
|
||||
336
src/db/dbScan.c
336
src/db/dbScan.c
@@ -1,5 +1,4 @@
|
||||
/* dbScan.c */
|
||||
/* base/src/db $Id$ */
|
||||
/* tasks and subroutines to scan the database */
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
@@ -40,6 +39,7 @@
|
||||
* .09 02-03-94 mrk If scanAdd fails set precord->scan=SCAN_PASSIVE
|
||||
* .10 02-22-94 mrk Make init work if 1st record has 28 char name
|
||||
* .11 05-04-94 mrk Call taskwdRemove only if spawing again
|
||||
* .12 05-02-96 mrk Allow multiple priority event scan
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
@@ -73,66 +73,65 @@
|
||||
extern struct dbBase *pdbbase;
|
||||
|
||||
/* SCAN ONCE */
|
||||
int onceQueueSize = 256;
|
||||
int onceQueueSize = 1000;
|
||||
static SEM_ID onceSem;
|
||||
static RING_ID onceQ;
|
||||
static int onceTaskId;
|
||||
|
||||
/*all other scan types */
|
||||
struct scan_list{
|
||||
typedef struct scan_list{
|
||||
FAST_LOCK lock;
|
||||
ELLLIST list;
|
||||
short modified;/*has list been modified?*/
|
||||
long ticks; /*ticks per period for periodic*/
|
||||
};
|
||||
}scan_list;
|
||||
/*scan_elements are allocated and the address stored in dbCommon.spvt*/
|
||||
struct scan_element{
|
||||
typedef struct scan_element{
|
||||
ELLNODE node;
|
||||
struct scan_list *pscan_list;
|
||||
scan_list *pscan_list;
|
||||
struct dbCommon *precord;
|
||||
};
|
||||
}scan_element;
|
||||
|
||||
int volatile scanRestart=FALSE;
|
||||
|
||||
/* PERIODIC SCANNER */
|
||||
static int nPeriodic=0;
|
||||
static struct scan_list **papPeriodic; /* pointer to array of pointers*/
|
||||
static int *periodicTaskId; /*array of integers after allocation*/
|
||||
static char *priorityName[NUM_CALLBACK_PRIORITIES] = {
|
||||
"Low","Medium","High"};
|
||||
|
||||
/* EVENT */
|
||||
#define MAX_EVENTS 256
|
||||
#define EVENT_QUEUE_SIZE 1000
|
||||
static struct scan_list *papEvent[MAX_EVENTS];/*array of pointers*/
|
||||
static SEM_ID eventSem;
|
||||
static RING_ID eventQ;
|
||||
static int eventTaskId;
|
||||
typedef struct event_scan_list {
|
||||
CALLBACK callback;
|
||||
scan_list scan_list;
|
||||
}event_scan_list;
|
||||
static event_scan_list *pevent_list[NUM_CALLBACK_PRIORITIES][MAX_EVENTS];
|
||||
|
||||
/* IO_EVENT*/
|
||||
struct io_scan_list {
|
||||
typedef struct io_scan_list {
|
||||
CALLBACK callback;
|
||||
struct scan_list scan_list;
|
||||
scan_list scan_list;
|
||||
struct io_scan_list *next;
|
||||
};
|
||||
}io_scan_list;
|
||||
static io_scan_list *iosl_head[NUM_CALLBACK_PRIORITIES]={NULL,NULL,NULL};
|
||||
|
||||
static struct io_scan_list *iosl_head[NUM_CALLBACK_PRIORITIES]={NULL,NULL,NULL};
|
||||
/* PERIODIC SCANNER */
|
||||
static int nPeriodic=0;
|
||||
static scan_list **papPeriodic; /* pointer to array of pointers*/
|
||||
static int *periodicTaskId; /*array of integers after allocation*/
|
||||
|
||||
/* Private routines */
|
||||
static void onceTask(void);
|
||||
static void initOnce(void);
|
||||
static void periodicTask(struct scan_list *psl);
|
||||
static void periodicTask(scan_list *psl);
|
||||
static void initPeriodic(void);
|
||||
static void spawnPeriodic(int ind);
|
||||
static void wdPeriodic(long ind);
|
||||
static void eventTask(void);
|
||||
static void initEvent(void);
|
||||
static void spawnEvent(void);
|
||||
static void wdEvent(void);
|
||||
static void ioeventCallback(struct io_scan_list *piosl);
|
||||
static void printList(struct scan_list *psl,char *message);
|
||||
static void scanList(struct scan_list *psl);
|
||||
static void eventCallback(event_scan_list *pevent_scan_list);
|
||||
static void ioeventCallback(io_scan_list *piosl);
|
||||
static void printList(scan_list *psl,char *message);
|
||||
static void scanList(scan_list *psl);
|
||||
static void buildScanLists(void);
|
||||
static void addToList(struct dbCommon *precord,struct scan_list *psl);
|
||||
static void deleteFromList(struct dbCommon *precord,struct scan_list *psl);
|
||||
static void addToList(struct dbCommon *precord,scan_list *psl);
|
||||
static void deleteFromList(struct dbCommon *precord,scan_list *psl);
|
||||
|
||||
long scanInit()
|
||||
{
|
||||
@@ -143,38 +142,13 @@ long scanInit()
|
||||
initEvent();
|
||||
buildScanLists();
|
||||
for (i=0;i<nPeriodic; i++) spawnPeriodic(i);
|
||||
spawnEvent();
|
||||
return(0);
|
||||
}
|
||||
|
||||
void post_event(int event)
|
||||
{
|
||||
unsigned char evnt;
|
||||
static int newOverflow=TRUE;
|
||||
|
||||
if (!interruptAccept) return; /* not awake yet */
|
||||
if(event<0 || event>=MAX_EVENTS) {
|
||||
errMessage(-1,"illegal event passed to post_event");
|
||||
return;
|
||||
}
|
||||
evnt = (unsigned)event;
|
||||
/*multiple writers can exist. Thus if evnt is ever changed to use*/
|
||||
/*something bigger than a character interrupts will have to be blocked*/
|
||||
if(rngBufPut(eventQ,(void *)&evnt,sizeof(unsigned char))
|
||||
!=sizeof(unsigned char)) {
|
||||
if(newOverflow) errMessage(0,"rngBufPut overflow in post_event");
|
||||
newOverflow = FALSE;
|
||||
} else {
|
||||
newOverflow = TRUE;
|
||||
}
|
||||
semGive(eventSem);
|
||||
}
|
||||
|
||||
|
||||
void scanAdd(struct dbCommon *precord)
|
||||
{
|
||||
short scan;
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
|
||||
/* get the list on which this record belongs */
|
||||
scan = precord->scan;
|
||||
@@ -183,7 +157,9 @@ void scanAdd(struct dbCommon *precord)
|
||||
recGblRecordError(-1,(void *)precord,
|
||||
"scanAdd detected illegal SCAN value");
|
||||
}else if(scan==SCAN_EVENT) {
|
||||
unsigned char evnt;
|
||||
unsigned char evnt;
|
||||
int priority;
|
||||
event_scan_list *pevent_scan_list;
|
||||
|
||||
if(precord->evnt<0 || precord->evnt>=MAX_EVENTS) {
|
||||
recGblRecordError(S_db_badField,(void *)precord,
|
||||
@@ -192,16 +168,25 @@ void scanAdd(struct dbCommon *precord)
|
||||
return;
|
||||
}
|
||||
evnt = (signed)precord->evnt;
|
||||
psl = papEvent[evnt];
|
||||
if(psl==NULL) {
|
||||
psl = dbCalloc(1,sizeof(struct scan_list));
|
||||
papEvent[precord->evnt] = psl;
|
||||
FASTLOCKINIT(&psl->lock);
|
||||
ellInit(&psl->list);
|
||||
priority = precord->prio;
|
||||
if(priority<0 || priority>=NUM_CALLBACK_PRIORITIES) {
|
||||
recGblRecordError(-1,(void *)precord,
|
||||
"scanAdd: illegal prio field");
|
||||
precord->scan = SCAN_PASSIVE;
|
||||
return;
|
||||
}
|
||||
pevent_scan_list = pevent_list[priority][evnt];
|
||||
if(!pevent_scan_list ) {
|
||||
pevent_scan_list = dbCalloc(1,sizeof(event_scan_list));
|
||||
pevent_list[priority][evnt] = pevent_scan_list;
|
||||
pevent_scan_list->callback.callback = eventCallback;
|
||||
pevent_scan_list->callback.priority = priority;
|
||||
ellInit(&pevent_scan_list->scan_list.list);
|
||||
}
|
||||
psl = &pevent_scan_list->scan_list;
|
||||
addToList(precord,psl);
|
||||
} else if(scan==SCAN_IO_EVENT) {
|
||||
struct io_scan_list *piosl=NULL;
|
||||
io_scan_list *piosl=NULL;
|
||||
int priority;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
|
||||
@@ -250,7 +235,7 @@ void scanAdd(struct dbCommon *precord)
|
||||
void scanDelete(struct dbCommon *precord)
|
||||
{
|
||||
short scan;
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
|
||||
/* get the list on which this record belongs */
|
||||
scan = precord->scan;
|
||||
@@ -259,22 +244,33 @@ void scanDelete(struct dbCommon *precord)
|
||||
recGblRecordError(-1,(void *)precord,
|
||||
"scanDelete detected illegal SCAN value");
|
||||
}else if(scan==SCAN_EVENT) {
|
||||
unsigned char evnt;
|
||||
unsigned char evnt;
|
||||
int priority;
|
||||
event_scan_list *pevent_scan_list;
|
||||
|
||||
if(precord->evnt<0 || precord->evnt>=MAX_EVENTS) {
|
||||
recGblRecordError(S_db_badField,(void *)precord,
|
||||
"scanDelete detected illegal EVNT value");
|
||||
"scanAdd detected illegal EVNT value");
|
||||
precord->scan = SCAN_PASSIVE;
|
||||
return;
|
||||
}
|
||||
evnt = (signed)precord->evnt;
|
||||
psl = papEvent[evnt];
|
||||
if(psl==NULL)
|
||||
priority = precord->prio;
|
||||
if(priority<0 || priority>=NUM_CALLBACK_PRIORITIES) {
|
||||
recGblRecordError(-1,(void *)precord,
|
||||
"scanAdd: illegal prio field");
|
||||
precord->scan = SCAN_PASSIVE;
|
||||
return;
|
||||
}
|
||||
pevent_scan_list = pevent_list[priority][evnt];
|
||||
if(pevent_scan_list) psl = &pevent_scan_list->scan_list;
|
||||
if(!pevent_scan_list || !psl)
|
||||
recGblRecordError(-1,(void *)precord,
|
||||
"scanDelete for bad evnt");
|
||||
else
|
||||
else
|
||||
deleteFromList(precord,psl);
|
||||
} else if(scan==SCAN_IO_EVENT) {
|
||||
struct io_scan_list *piosl=NULL;
|
||||
io_scan_list *piosl=NULL;
|
||||
int priority;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
|
||||
@@ -315,7 +311,7 @@ void scanDelete(struct dbCommon *precord)
|
||||
|
||||
int scanppl() /*print periodic list*/
|
||||
{
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
char message[80];
|
||||
double period;
|
||||
int i;
|
||||
@@ -325,7 +321,7 @@ int scanppl() /*print periodic list*/
|
||||
if(psl==NULL) continue;
|
||||
period = psl->ticks;
|
||||
period /= vxTicksPerSecond;
|
||||
sprintf(message,"Scan Period= %f seconds\n",period);
|
||||
sprintf(message,"Scan Period= %f seconds ",period);
|
||||
printList(psl,message);
|
||||
}
|
||||
return(0);
|
||||
@@ -333,22 +329,25 @@ int scanppl() /*print periodic list*/
|
||||
|
||||
int scanpel() /*print event list */
|
||||
{
|
||||
struct scan_list *psl;
|
||||
char message[80];
|
||||
int i;
|
||||
char message[80];
|
||||
int priority,evnt;
|
||||
event_scan_list *pevent_scan_list;
|
||||
|
||||
for (i=0; i<MAX_EVENTS; i++) {
|
||||
psl = papEvent[i];
|
||||
if(psl==NULL) continue;
|
||||
sprintf(message,"Event %d\n",i);
|
||||
printList(psl,message);
|
||||
for(evnt=0; evnt<MAX_EVENTS; evnt++) {
|
||||
for(priority=0; priority<NUM_CALLBACK_PRIORITIES; priority++) {
|
||||
pevent_scan_list = pevent_list[priority][evnt];
|
||||
if(!pevent_scan_list) continue;
|
||||
if(ellCount(&pevent_scan_list->scan_list) ==0) continue;
|
||||
sprintf(message,"Event %d Priority %s",evnt,priorityName[priority]);
|
||||
printList(&pevent_scan_list->scan_list,message);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int scanpiol() /* print io_event list */
|
||||
{
|
||||
struct io_scan_list *piosl;
|
||||
io_scan_list *piosl;
|
||||
int priority;
|
||||
char message[80];
|
||||
|
||||
@@ -364,14 +363,50 @@ int scanpiol() /* print io_event list */
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void eventCallback(event_scan_list *pevent_scan_list)
|
||||
{
|
||||
scanList(&pevent_scan_list->scan_list);
|
||||
}
|
||||
|
||||
static void initEvent(void)
|
||||
{
|
||||
int evnt,priority;
|
||||
|
||||
for(priority=0; priority<NUM_CALLBACK_PRIORITIES; priority++) {
|
||||
for(evnt=0; evnt<MAX_EVENTS; evnt++) {
|
||||
pevent_list[priority][evnt] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void post_event(int event)
|
||||
{
|
||||
unsigned char evnt;
|
||||
int priority;
|
||||
event_scan_list *pevent_scan_list;
|
||||
|
||||
if (!interruptAccept) return; /* not awake yet */
|
||||
if(event<0 || event>=MAX_EVENTS) {
|
||||
errMessage(-1,"illegal event passed to post_event");
|
||||
return;
|
||||
}
|
||||
evnt = (unsigned)event;
|
||||
for(priority=0; priority<NUM_CALLBACK_PRIORITIES; priority++) {
|
||||
pevent_scan_list = pevent_list[priority][evnt];
|
||||
if(!pevent_scan_list) continue;
|
||||
if(ellCount(&pevent_scan_list->scan_list) >0)
|
||||
callbackRequest((void *)pevent_scan_list);
|
||||
}
|
||||
}
|
||||
|
||||
void scanIoInit(IOSCANPVT *ppioscanpvt)
|
||||
{
|
||||
struct io_scan_list *piosl;
|
||||
io_scan_list *piosl;
|
||||
int priority;
|
||||
|
||||
/* allocate an array of io_scan_lists. One for each priority */
|
||||
/* IOSCANPVT will hold the address of this array of structures */
|
||||
*ppioscanpvt=dbCalloc(NUM_CALLBACK_PRIORITIES,sizeof(struct io_scan_list));
|
||||
*ppioscanpvt=dbCalloc(NUM_CALLBACK_PRIORITIES,sizeof(io_scan_list));
|
||||
for(priority=0, piosl=*ppioscanpvt;
|
||||
priority<NUM_CALLBACK_PRIORITIES; priority++, piosl++){
|
||||
piosl->callback.callback = ioeventCallback;
|
||||
@@ -387,7 +422,7 @@ void scanIoInit(IOSCANPVT *ppioscanpvt)
|
||||
|
||||
void scanIoRequest(IOSCANPVT pioscanpvt)
|
||||
{
|
||||
struct io_scan_list *piosl;
|
||||
io_scan_list *piosl;
|
||||
int priority;
|
||||
|
||||
if(!interruptAccept) return;
|
||||
@@ -447,7 +482,7 @@ static void initOnce(void)
|
||||
taskwdInsert(onceTaskId,NULL,0L);
|
||||
}
|
||||
|
||||
static void periodicTask(struct scan_list *psl)
|
||||
static void periodicTask(scan_list *psl)
|
||||
{
|
||||
|
||||
unsigned long start_time,end_time;
|
||||
@@ -468,7 +503,7 @@ static void periodicTask(struct scan_list *psl)
|
||||
static void initPeriodic()
|
||||
{
|
||||
dbMenu *pmenu;
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
float temp;
|
||||
int i;
|
||||
|
||||
@@ -478,10 +513,10 @@ static void initPeriodic()
|
||||
return;
|
||||
}
|
||||
nPeriodic = pmenu->nChoice - SCAN_1ST_PERIODIC;
|
||||
papPeriodic = dbCalloc(nPeriodic,sizeof(struct scan_list*));
|
||||
papPeriodic = dbCalloc(nPeriodic,sizeof(scan_list*));
|
||||
periodicTaskId = dbCalloc(nPeriodic,sizeof(int));
|
||||
for(i=0; i<nPeriodic; i++) {
|
||||
psl = dbCalloc(1,sizeof(struct scan_list));
|
||||
psl = dbCalloc(1,sizeof(scan_list));
|
||||
papPeriodic[i] = psl;
|
||||
FASTLOCKINIT(&psl->lock);
|
||||
ellInit(&psl->list);
|
||||
@@ -492,7 +527,7 @@ static void initPeriodic()
|
||||
|
||||
static void spawnPeriodic(int ind)
|
||||
{
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
char taskName[20];
|
||||
|
||||
psl = papPeriodic[ind];
|
||||
@@ -506,7 +541,7 @@ static void spawnPeriodic(int ind)
|
||||
|
||||
static void wdPeriodic(long ind)
|
||||
{
|
||||
struct scan_list *psl;
|
||||
scan_list *psl;
|
||||
|
||||
if(!scanRestart)return;
|
||||
psl = papPeriodic[ind];
|
||||
@@ -516,83 +551,20 @@ static void wdPeriodic(long ind)
|
||||
spawnPeriodic(ind);
|
||||
}
|
||||
|
||||
static void eventTask(void)
|
||||
static void ioeventCallback(io_scan_list *piosl)
|
||||
{
|
||||
unsigned char event;
|
||||
struct scan_list *psl;
|
||||
|
||||
while(TRUE) {
|
||||
if(semTake(eventSem,WAIT_FOREVER)!=OK)
|
||||
errMessage(0,"semTake returned error in eventTask");
|
||||
while (rngNBytes(eventQ)>=sizeof(unsigned char)){
|
||||
if(rngBufGet(eventQ,(void *)&event,sizeof(unsigned char))!=sizeof(unsigned char))
|
||||
errMessage(0,"rngBufGet returned error in eventTask");
|
||||
if(event>MAX_EVENTS-1) {
|
||||
errMessage(-1,"eventTask received an illegal event");
|
||||
continue;
|
||||
}
|
||||
if(papEvent[event]==NULL) continue;
|
||||
psl = papEvent[event];
|
||||
if(psl) scanList(psl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void initEvent(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<MAX_EVENTS; i++) papEvent[i] = 0;
|
||||
eventQ = rngCreate(sizeof(unsigned char) * EVENT_QUEUE_SIZE);
|
||||
if(eventQ==NULL) {
|
||||
errMessage(0,"initEvent failed");
|
||||
exit(1);
|
||||
}
|
||||
if((eventSem=semBCreate(SEM_Q_FIFO,SEM_EMPTY))==NULL)
|
||||
errMessage(0,"semBcreate failed in initEvent");
|
||||
}
|
||||
|
||||
static void spawnEvent(void)
|
||||
{
|
||||
|
||||
eventTaskId = taskSpawn(EVENTSCAN_NAME,EVENTSCAN_PRI,EVENTSCAN_OPT,
|
||||
EVENTSCAN_STACK,(FUNCPTR)eventTask,
|
||||
0,0,0,0,0,0,0,0,0,0);
|
||||
taskwdInsert(eventTaskId,wdEvent,0L);
|
||||
}
|
||||
|
||||
static void wdEvent(void)
|
||||
{
|
||||
int i;
|
||||
struct scan_list *psl;
|
||||
|
||||
if(!scanRestart) return;
|
||||
taskwdRemove(eventTaskId);
|
||||
if(semFlush(eventSem)!=OK)
|
||||
errMessage(0,"semFlush failed while restarting eventTask");
|
||||
rngFlush(eventQ);
|
||||
for (i=0; i<MAX_EVENTS; i++) {
|
||||
psl = papEvent[i];
|
||||
if(psl==NULL) continue;
|
||||
FASTUNLOCK(&psl->lock);
|
||||
}
|
||||
spawnEvent();
|
||||
}
|
||||
|
||||
static void ioeventCallback(struct io_scan_list *piosl)
|
||||
{
|
||||
struct scan_list *psl=&piosl->scan_list;
|
||||
scan_list *psl=&piosl->scan_list;
|
||||
|
||||
scanList(psl);
|
||||
}
|
||||
|
||||
|
||||
static void printList(struct scan_list *psl,char *message)
|
||||
static void printList(scan_list *psl,char *message)
|
||||
{
|
||||
struct scan_element *pse;
|
||||
scan_element *pse;
|
||||
|
||||
FASTLOCK(&psl->lock);
|
||||
pse = (struct scan_element *)ellFirst(&psl->list);
|
||||
pse = (scan_element *)ellFirst(&psl->list);
|
||||
FASTUNLOCK(&psl->lock);
|
||||
if(pse==NULL) return;
|
||||
printf("%s\n",message);
|
||||
@@ -604,23 +576,23 @@ static void printList(struct scan_list *psl,char *message)
|
||||
printf("Returning because list changed while processing.");
|
||||
return;
|
||||
}
|
||||
pse = (struct scan_element *)ellNext((void *)pse);
|
||||
pse = (scan_element *)ellNext((void *)pse);
|
||||
FASTUNLOCK(&psl->lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void scanList(struct scan_list *psl)
|
||||
static void scanList(scan_list *psl)
|
||||
{
|
||||
/*In reading this code remember that the call to dbProcess can result*/
|
||||
/*in the SCAN field being changed in an arbitrary number of records */
|
||||
|
||||
struct scan_element *pse,*prev,*next;
|
||||
scan_element *pse,*prev,*next;
|
||||
|
||||
FASTLOCK(&psl->lock);
|
||||
psl->modified = FALSE;
|
||||
pse = (struct scan_element *)ellFirst(&psl->list);
|
||||
pse = (scan_element *)ellFirst(&psl->list);
|
||||
prev = NULL;
|
||||
next = (struct scan_element *)ellNext((void *)pse);
|
||||
next = (scan_element *)ellNext((void *)pse);
|
||||
FASTUNLOCK(&psl->lock);
|
||||
while(pse!=NULL) {
|
||||
struct dbCommon *precord = pse->precord;
|
||||
@@ -631,27 +603,27 @@ static void scanList(struct scan_list *psl)
|
||||
FASTLOCK(&psl->lock);
|
||||
if(!psl->modified) {
|
||||
prev = pse;
|
||||
pse = (struct scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
|
||||
pse = (scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (scan_element *)ellNext((void *)pse);
|
||||
} else if (pse->pscan_list==psl) {
|
||||
/*This scan element is still in same scan list*/
|
||||
prev = pse;
|
||||
pse = (struct scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (struct scan_element *)ellNext((void *)pse);
|
||||
pse = (scan_element *)ellNext((void *)pse);
|
||||
if(pse!=NULL)next = (scan_element *)ellNext((void *)pse);
|
||||
psl->modified = FALSE;
|
||||
} else if (prev!=NULL && prev->pscan_list==psl) {
|
||||
/*Previous scan element is still in same scan list*/
|
||||
pse = (struct scan_element *)ellNext((void *)prev);
|
||||
pse = (scan_element *)ellNext((void *)prev);
|
||||
if(pse!=NULL) {
|
||||
prev = (struct scan_element *)ellPrevious((void *)pse);
|
||||
next = (struct scan_element *)ellNext((void *)pse);
|
||||
prev = (scan_element *)ellPrevious((void *)pse);
|
||||
next = (scan_element *)ellNext((void *)pse);
|
||||
}
|
||||
psl->modified = FALSE;
|
||||
} else if (next!=NULL && next->pscan_list==psl) {
|
||||
/*Next scan element is still in same scan list*/
|
||||
pse = next;
|
||||
prev = (struct scan_element *)ellPrevious((void *)pse);
|
||||
next = (struct scan_element *)ellNext((void *)pse);
|
||||
prev = (scan_element *)ellPrevious((void *)pse);
|
||||
next = (scan_element *)ellNext((void *)pse);
|
||||
psl->modified = FALSE;
|
||||
} else {
|
||||
/*Too many changes. Just wait till next period*/
|
||||
@@ -681,26 +653,26 @@ static void buildScanLists(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void addToList(struct dbCommon *precord,struct scan_list *psl)
|
||||
static void addToList(struct dbCommon *precord,scan_list *psl)
|
||||
{
|
||||
struct scan_element *pse,*ptemp;
|
||||
scan_element *pse,*ptemp;
|
||||
|
||||
FASTLOCK(&psl->lock);
|
||||
pse = (struct scan_element *)(precord->spvt);
|
||||
pse = (scan_element *)(precord->spvt);
|
||||
if(pse==NULL) {
|
||||
pse = dbCalloc(1,sizeof(struct scan_element));
|
||||
pse = dbCalloc(1,sizeof(scan_element));
|
||||
precord->spvt = (void *)pse;
|
||||
pse->precord = precord;
|
||||
}
|
||||
pse ->pscan_list = psl;
|
||||
ptemp = (struct scan_element *)ellFirst(&psl->list);
|
||||
ptemp = (scan_element *)ellFirst(&psl->list);
|
||||
while(ptemp!=NULL) {
|
||||
if(ptemp->precord->phas>precord->phas) {
|
||||
ellInsert(&psl->list,
|
||||
ellPrevious((void *)ptemp),(void *)pse);
|
||||
break;
|
||||
}
|
||||
ptemp = (struct scan_element *)ellNext((void *)ptemp);
|
||||
ptemp = (scan_element *)ellNext((void *)ptemp);
|
||||
}
|
||||
if(ptemp==NULL) ellAdd(&psl->list,(void *)pse);
|
||||
psl->modified = TRUE;
|
||||
@@ -708,16 +680,16 @@ static void addToList(struct dbCommon *precord,struct scan_list *psl)
|
||||
return;
|
||||
}
|
||||
|
||||
static void deleteFromList(struct dbCommon *precord,struct scan_list *psl)
|
||||
static void deleteFromList(struct dbCommon *precord,scan_list *psl)
|
||||
{
|
||||
struct scan_element *pse;
|
||||
scan_element *pse;
|
||||
|
||||
FASTLOCK(&psl->lock);
|
||||
if(precord->spvt==NULL) {
|
||||
FASTUNLOCK(&psl->lock);
|
||||
return;
|
||||
}
|
||||
pse = (struct scan_element *)(precord->spvt);
|
||||
pse = (scan_element *)(precord->spvt);
|
||||
if(pse==NULL || pse->pscan_list!=psl) {
|
||||
FASTUNLOCK(&psl->lock);
|
||||
errMessage(-1,"deleteFromList failed");
|
||||
|
||||
Reference in New Issue
Block a user