From 056304409764d7605e46d411fb2fa565344d1b0d Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 28 Dec 2009 20:37:09 -0600 Subject: [PATCH 1/9] Marty Kraimer's changes to support process-get operations. --- src/ioc/db/dbCAC.h | 3 +- src/ioc/db/dbCommon.dbd | 8 +- src/ioc/db/dbNotify.c | 534 +++++++++++++++++------------- src/ioc/db/dbNotify.h | 151 ++++++--- src/ioc/db/dbPutNotifyBlocker.cpp | 48 +-- src/ioc/db/dbPutNotifyBlocker.h | 10 +- src/ioc/db/db_access.c | 66 ++-- src/ioc/db/db_test.c | 43 +-- src/ioc/misc/iocInit.c | 2 +- src/ioc/rsrv/camessage.c | 77 +++-- src/std/dev/Makefile | 6 + src/std/dev/devAiSoftCallback.c | 155 +++++++++ src/std/dev/devBiSoftCallback.c | 155 +++++++++ src/std/dev/devLiSoftCallback.c | 155 +++++++++ src/std/dev/devMbbiSoftCallback.c | 155 +++++++++ src/std/dev/devSiSoftCallback.c | 155 +++++++++ src/std/dev/devSoft.dbd | 6 + 17 files changed, 1354 insertions(+), 375 deletions(-) create mode 100644 src/std/dev/devAiSoftCallback.c create mode 100644 src/std/dev/devBiSoftCallback.c create mode 100644 src/std/dev/devLiSoftCallback.c create mode 100644 src/std/dev/devMbbiSoftCallback.c create mode 100644 src/std/dev/devSiSoftCallback.c diff --git a/src/ioc/db/dbCAC.h b/src/ioc/db/dbCAC.h index 3032023dc..744041280 100644 --- a/src/ioc/db/dbCAC.h +++ b/src/ioc/db/dbCAC.h @@ -55,7 +55,8 @@ #include "db_convert.h" #include "resourceLib.h" -extern "C" void putNotifyCompletion ( putNotify *ppn ); +extern "C" int putNotifyPut ( processNotify *ppn, notifyPutType notifyPutType ); +extern "C" void putNotifyCompletion ( processNotify *ppn ); class dbContext; class dbChannelIO; diff --git a/src/ioc/db/dbCommon.dbd b/src/ioc/db/dbCommon.dbd index d940999e7..981e3b01a 100644 --- a/src/ioc/db/dbCommon.dbd +++ b/src/ioc/db/dbCommon.dbd @@ -171,16 +171,16 @@ extra("struct asgMember *asp") } field(PPN,DBF_NOACCESS) { - prompt("addr of PUTNOTIFY") + prompt("pprocessNotify") special(SPC_NOMOD) interest(4) - extra("struct putNotify *ppn") + extra("struct processNotify *ppn") } field(PPNR,DBF_NOACCESS) { - prompt("pputNotifyRecord") + prompt("pprocessNotifyRecord") special(SPC_NOMOD) interest(4) - extra("struct putNotifyRecord *ppnr") + extra("struct processNotifyRecord *ppnr") } field(SPVT,DBF_NOACCESS) { prompt("Scan Private") diff --git a/src/ioc/db/dbNotify.c b/src/ioc/db/dbNotify.c index 7454129dc..c6403d502 100644 --- a/src/ioc/db/dbNotify.c +++ b/src/ioc/db/dbNotify.c @@ -46,39 +46,39 @@ #include "epicsTime.h" #include "cantProceed.h" -/*putNotify.state values */ +/*notify state values */ typedef enum { - putNotifyNotActive, - putNotifyWaitForRestart, - putNotifyRestartCallbackRequested, - putNotifyRestartInProgress, - putNotifyPutInProgress, - putNotifyUserCallbackRequested, - putNotifyUserCallbackActive -}putNotifyState; + notifyNotActive, + notifyWaitForRestart, + notifyRestartCallbackRequested, + notifyRestartInProgress, + notifyProcessInProgress, + notifyUserCallbackRequested, + notifyUserCallbackActive +}notifyState; /*structure attached to ppnr field of each record*/ -typedef struct putNotifyRecord { +typedef struct processNotifyRecord { ellCheckNode waitNode; - ELLLIST restartList; /*list of putNotifys to restart*/ + ELLLIST restartList; /*list of processNotifys to restart*/ dbCommon *precord; -}putNotifyRecord; +}processNotifyRecord; #define MAGIC 0xfedc0123 -typedef struct putNotifyPvt { +typedef struct notifyPvt { ELLNODE node; /*For free list*/ long magic; short state; CALLBACK callback; - ELLLIST waitList; /*list of records for current putNotify*/ + ELLLIST waitList; /*list of records for current processNotify*/ short cancelWait; short userCallbackWait; epicsEventId cancelEvent; epicsEventId userCallbackEvent; -}putNotifyPvt; +}notifyPvt; -/* putNotify groups can span locksets if links are dynamically modified*/ -/* Thus a global lock is taken while putNotify fields are accessed */ +/* processNotify groups can span locksets if links are dynamically modified*/ +/* Thus a global lock is taken while processNotify fields are accessed */ typedef struct notifyGlobal { epicsMutexId lock; ELLLIST freeList; @@ -87,12 +87,11 @@ typedef struct notifyGlobal { static notifyGlobal *pnotifyGlobal = 0; /*Local routines*/ -static void putNotifyInit(putNotify *ppn); -static void putNotifyCleanup(putNotify *ppn); -static void restartCheck(putNotifyRecord *ppnr); -static void callUser(dbCommon *precord,putNotify *ppn); -static void notifyCallback(CALLBACK *pcallback); -static void putNotifyCommon(putNotify *ppn,dbCommon *precord); +static void notifyInit(processNotify *ppn); +static void notifyCleanup(processNotify *ppn); +static void restartCheck(processNotifyRecord *ppnr); +static void callDone(dbCommon *precord,processNotify *ppn); +static void processNotifyCommon(processNotify *ppn,dbCommon *precord); #define ellSafeAdd(list,listnode) \ { \ @@ -108,176 +107,193 @@ static void putNotifyCommon(putNotify *ppn,dbCommon *precord); (listnode)->isOnList=0; \ } -static void putNotifyInit(putNotify *ppn) +static void notifyInit(processNotify *ppn) { - putNotifyPvt *pputNotifyPvt; + notifyPvt *pnotifyPvt; - pputNotifyPvt = (putNotifyPvt *)ellFirst(&pnotifyGlobal->freeList); - if(pputNotifyPvt) { - ellDelete(&pnotifyGlobal->freeList,&pputNotifyPvt->node); + pnotifyPvt = (notifyPvt *)ellFirst(&pnotifyGlobal->freeList); + if(pnotifyPvt) { + ellDelete(&pnotifyGlobal->freeList,&pnotifyPvt->node); } else { - pputNotifyPvt = dbCalloc(1,sizeof(putNotifyPvt)); - pputNotifyPvt->cancelEvent = epicsEventCreate(epicsEventEmpty); - pputNotifyPvt->userCallbackEvent = epicsEventCreate(epicsEventEmpty); - pputNotifyPvt->magic = MAGIC; - pputNotifyPvt->state = putNotifyNotActive; + pnotifyPvt = dbCalloc(1,sizeof(notifyPvt)); + pnotifyPvt->cancelEvent = epicsEventCreate(epicsEventEmpty); + pnotifyPvt->userCallbackEvent = epicsEventCreate(epicsEventEmpty); + pnotifyPvt->magic = MAGIC; + pnotifyPvt->state = notifyNotActive; } - pputNotifyPvt->state = putNotifyNotActive; - callbackSetCallback(notifyCallback,&pputNotifyPvt->callback); - callbackSetUser(ppn,&pputNotifyPvt->callback); - callbackSetPriority(priorityLow,&pputNotifyPvt->callback); - ellInit(&pputNotifyPvt->waitList); - ppn->status = 0; - pputNotifyPvt->state = putNotifyNotActive; - pputNotifyPvt->cancelWait = pputNotifyPvt->userCallbackWait = 0; - ppn->pputNotifyPvt = pputNotifyPvt; + pnotifyPvt->state = notifyNotActive; + callbackSetCallback(notifyCallback,&pnotifyPvt->callback); + callbackSetUser(ppn,&pnotifyPvt->callback); + callbackSetPriority(priorityLow,&pnotifyPvt->callback); + ellInit(&pnotifyPvt->waitList); + ppn->status = notifyOK; + ppn->wasProcessed = 0; + pnotifyPvt->state = notifyNotActive; + pnotifyPvt->cancelWait = pnotifyPvt->userCallbackWait = 0; + ppn->pnotifyPvt = pnotifyPvt; } -static void putNotifyCleanup(putNotify *ppn) +static void notifyCleanup(processNotify *ppn) { - putNotifyPvt *pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; + notifyPvt *pnotifyPvt = (notifyPvt *)ppn->pnotifyPvt; - pputNotifyPvt->state = putNotifyNotActive; - ellAdd(&pnotifyGlobal->freeList,&pputNotifyPvt->node); - ppn->pputNotifyPvt = 0; + pnotifyPvt->state = notifyNotActive; + ellAdd(&pnotifyGlobal->freeList,&pnotifyPvt->node); + ppn->pnotifyPvt = 0; } -static void restartCheck(putNotifyRecord *ppnr) +static void restartCheck(processNotifyRecord *ppnr) { dbCommon *precord = ppnr->precord; - putNotify *pfirst; - putNotifyPvt *pputNotifyPvt; + processNotify *pfirst; + notifyPvt *pnotifyPvt; assert(precord->ppn); - pfirst = (putNotify *)ellFirst(&ppnr->restartList); + pfirst = (processNotify *)ellFirst(&ppnr->restartList); if(!pfirst) { precord->ppn = 0; return; } - pputNotifyPvt = (putNotifyPvt *)pfirst->pputNotifyPvt; - assert(pputNotifyPvt->state==putNotifyWaitForRestart); + pnotifyPvt = (notifyPvt *)pfirst->pnotifyPvt; + assert(pnotifyPvt->state==notifyWaitForRestart); /* remove pfirst from restartList */ ellSafeDelete(&ppnr->restartList,&pfirst->restartNode); /*make pfirst owner of the record*/ precord->ppn = pfirst; /* request callback for pfirst */ - pputNotifyPvt->state = putNotifyRestartCallbackRequested; - callbackRequest(&pputNotifyPvt->callback); + pnotifyPvt->state = notifyRestartCallbackRequested; + callbackRequest(&pnotifyPvt->callback); } -static void callUser(dbCommon *precord,putNotify *ppn) +static void callDone(dbCommon *precord,processNotify *ppn) { - putNotifyPvt *pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; + notifyPvt *pnotifyPvt = (notifyPvt *)ppn->pnotifyPvt; epicsMutexUnlock(pnotifyGlobal->lock); - dbScanUnlock(precord); - (*ppn->userCallback)(ppn); - epicsMutexMustLock(pnotifyGlobal->lock); - if(pputNotifyPvt->cancelWait && pputNotifyPvt->userCallbackWait) { - errlogPrintf("%s putNotify: both cancelWait and userCallbackWait true." - "This is illegal\n",precord->name); - pputNotifyPvt->cancelWait = pputNotifyPvt->userCallbackWait = 0; + if (ppn->requestType == processGetRequest || + ppn->requestType == putProcessGetRequest) { + ppn->getCallback(ppn, getFieldType); } - if(!pputNotifyPvt->cancelWait && !pputNotifyPvt->userCallbackWait) { - putNotifyCleanup(ppn); + dbScanUnlock(precord); + ppn->doneCallback(ppn); + epicsMutexMustLock(pnotifyGlobal->lock); + if (pnotifyPvt->cancelWait && pnotifyPvt->userCallbackWait) { + errlogPrintf("%s processNotify: both cancelWait and userCallbackWait true." + "This is illegal\n",precord->name); + pnotifyPvt->cancelWait = pnotifyPvt->userCallbackWait = 0; + } + if (!pnotifyPvt->cancelWait && !pnotifyPvt->userCallbackWait) { + notifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); return; } - if(pputNotifyPvt->cancelWait) { - pputNotifyPvt->cancelWait = 0; - epicsEventSignal(pputNotifyPvt->cancelEvent); + if (pnotifyPvt->cancelWait) { + pnotifyPvt->cancelWait = 0; + epicsEventSignal(pnotifyPvt->cancelEvent); epicsMutexUnlock(pnotifyGlobal->lock); return; } - assert(pputNotifyPvt->userCallbackWait); - pputNotifyPvt->userCallbackWait = 0; - epicsEventSignal(pputNotifyPvt->userCallbackEvent); + assert(pnotifyPvt->userCallbackWait); + pnotifyPvt->userCallbackWait = 0; + epicsEventSignal(pnotifyPvt->userCallbackEvent); epicsMutexUnlock(pnotifyGlobal->lock); return; } -static void putNotifyCommon(putNotify *ppn,dbCommon *precord) +static void processNotifyCommon(processNotify *ppn,dbCommon *precord) { - long status=0; - dbFldDes *pfldDes = ppn->paddr->pfldDes; - putNotifyPvt *pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; + dbFldDes *pfldDes=(dbFldDes *)(ppn->paddr->pfldDes); + notifyPvt *pnotifyPvt = (notifyPvt *)ppn->pnotifyPvt; + int didPut = 0; + int doProcess = 0; - if(precord->ppn && pputNotifyPvt->state!=putNotifyRestartCallbackRequested) - { /*another putNotify owns the record */ - pputNotifyPvt->state = putNotifyWaitForRestart; + if (precord->ppn && pnotifyPvt->state!=notifyRestartCallbackRequested) { + /*another processNotify owns the record */ + pnotifyPvt->state = notifyWaitForRestart; ellSafeAdd(&precord->ppnr->restartList,&ppn->restartNode); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; - } else if(precord->ppn){ - assert(precord->ppn==ppn); - assert(pputNotifyPvt->state==putNotifyRestartCallbackRequested); + } else if (precord->ppn) { + assert(precord->ppn == ppn); + assert(pnotifyPvt->state == notifyRestartCallbackRequested); } - if(precord->pact) { + if (precord->pact) { precord->ppn = ppn; - ellSafeAdd(&pputNotifyPvt->waitList,&precord->ppnr->waitNode); - pputNotifyPvt->state = putNotifyRestartInProgress; + ellSafeAdd(&pnotifyPvt->waitList,&precord->ppnr->waitNode); + pnotifyPvt->state = notifyRestartInProgress; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } - status=dbPut(ppn->paddr,ppn->dbrType,ppn->pbuffer,ppn->nRequest); - ppn->status = (status==0) ? putNotifyOK : putNotifyError; + if (ppn->requestType == putProcessRequest || + ppn->requestType == putProcessGetRequest) { + /*check for putField disabled*/ + if (precord->disp && ((void *)&precord->disp != ppn->paddr->pfield)) { + ppn->putCallback(ppn, putDisabledType); + } else { + didPut = ppn->putCallback(ppn, putType); + } + } /* Check to see if dbProcess should not be called */ - if(!status /*dont process if dbPut returned error */ - &&((ppn->paddr->pfield==(void *)&precord->proc) /*If PROC call dbProcess*/ - || (pfldDes->process_passive && precord->scan==0))) { + if (didPut && ((ppn->paddr->pfield == (void *)&precord->proc) + || (pfldDes->process_passive && precord->scan==0))) doProcess = 1; + if (!doProcess && ppn->requestType == processGetRequest) { + if (precord->scan == 0) doProcess = 1; + } + if (doProcess) { + ppn->wasProcessed = 1; precord->ppn = ppn; - ellSafeAdd(&pputNotifyPvt->waitList,&precord->ppnr->waitNode); - pputNotifyPvt->state = putNotifyPutInProgress; + ellSafeAdd(&pnotifyPvt->waitList, &precord->ppnr->waitNode); + pnotifyPvt->state = notifyProcessInProgress; epicsMutexUnlock(pnotifyGlobal->lock); dbProcess(precord); dbScanUnlock(precord); return; } - if(pputNotifyPvt->state==putNotifyRestartCallbackRequested) { + if (pnotifyPvt->state == notifyRestartCallbackRequested) { restartCheck(precord->ppnr); } - pputNotifyPvt->state = putNotifyUserCallbackActive; + pnotifyPvt->state = notifyUserCallbackActive; assert(precord->ppn!=ppn); - callUser(precord,ppn); + callDone(precord, ppn); } static void notifyCallback(CALLBACK *pcallback) { - putNotify *ppn=NULL; - dbCommon *precord; - putNotifyPvt *pputNotifyPvt; + processNotify *ppn=NULL; + dbCommon *precord; + notifyPvt *pnotifyPvt; callbackGetUser(ppn,pcallback); - pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; + pnotifyPvt = (notifyPvt *)ppn->pnotifyPvt; precord = ppn->paddr->precord; dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); assert(precord->ppnr); - assert(pputNotifyPvt->state==putNotifyRestartCallbackRequested - || pputNotifyPvt->state==putNotifyUserCallbackRequested); - assert(ellCount(&pputNotifyPvt->waitList)==0); - if(pputNotifyPvt->cancelWait) { - if(pputNotifyPvt->state==putNotifyRestartCallbackRequested) { + assert(pnotifyPvt->state==notifyRestartCallbackRequested + || pnotifyPvt->state==notifyUserCallbackRequested); + assert(ellCount(&pnotifyPvt->waitList)==0); + if (pnotifyPvt->cancelWait) { + if (pnotifyPvt->state == notifyRestartCallbackRequested) { restartCheck(precord->ppnr); } - epicsEventSignal(pputNotifyPvt->cancelEvent); + epicsEventSignal(pnotifyPvt->cancelEvent); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } - if(pputNotifyPvt->state==putNotifyRestartCallbackRequested) { - putNotifyCommon(ppn,precord); + if(pnotifyPvt->state == notifyRestartCallbackRequested) { + processNotifyCommon(ppn,precord); return; } /* All done. Clean up and call userCallback */ - pputNotifyPvt->state = putNotifyUserCallbackActive; + pnotifyPvt->state = notifyUserCallbackActive; assert(precord->ppn!=ppn); - callUser(precord,ppn); + callDone(precord, ppn); } -void epicsShareAPI dbPutNotifyInit(void) +void epicsShareAPI dbProcessNotifyInit(void) { if(pnotifyGlobal) return; pnotifyGlobal = dbCalloc(1,sizeof(notifyGlobal)); @@ -285,104 +301,111 @@ void epicsShareAPI dbPutNotifyInit(void) ellInit(&pnotifyGlobal->freeList); } -void epicsShareAPI dbPutNotify(putNotify *ppn) +void epicsShareAPI dbProcessNotify(processNotify *ppn) { dbCommon *precord = ppn->paddr->precord; short dbfType = ppn->paddr->field_type; - long status=0; - putNotifyPvt *pputNotifyPvt; + notifyPvt *pnotifyPvt; assert(precord); - /*check for putField disabled*/ - if(precord->disp) { - if((void *)(&precord->disp) != ppn->paddr->pfield) { - ppn->status = putNotifyPutDisabled; - (*ppn->userCallback)(ppn); - return; - } - } /* Must handle DBF_XXXLINKs as special case. * Only dbPutField will change link fields. * Also the record is not processed as a result */ - if(dbfType>=DBF_INLINK && dbfType<=DBF_FWDLINK) { - status=dbPutField(ppn->paddr,ppn->dbrType,ppn->pbuffer,ppn->nRequest); - ppn->status = (status==0) ? putNotifyOK : putNotifyError; - (*ppn->userCallback)(ppn); + ppn->status = notifyOK; + ppn->wasProcessed = 0; + if (dbfType>=DBF_INLINK && dbfType<=DBF_FWDLINK) { + if (ppn->requestType == putProcessRequest || + ppn->requestType == putProcessGetRequest) { + /*check for putField disabled*/ + if (precord->disp &&((void *)(&precord->disp) != ppn->paddr->pfield)) { + ppn->putCallback(ppn, putDisabledType); + } else { + ppn->putCallback(ppn, putFieldType); + } + } + if (ppn->requestType == processGetRequest || + ppn->requestType == putProcessGetRequest) { + ppn->getCallback(ppn, getFieldType); + + } + ppn->doneCallback(ppn); return; } dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); - pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; - if(pputNotifyPvt && (pputNotifyPvt->magic!=MAGIC)) { - printf("dbPutNotify:pputNotifyPvt was not initialized\n"); - pputNotifyPvt = 0; + pnotifyPvt = (notifyPvt *)ppn->pnotifyPvt; + if (pnotifyPvt && (pnotifyPvt->magic!=MAGIC)) { + printf("dbPutNotify:pnotifyPvt was not initialized\n"); + pnotifyPvt = 0; } - if(pputNotifyPvt) { - assert(pputNotifyPvt->state==putNotifyUserCallbackActive); - pputNotifyPvt->userCallbackWait = 1; + if (pnotifyPvt) { + assert(pnotifyPvt->state==notifyUserCallbackActive); + pnotifyPvt->userCallbackWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); - epicsEventWait(pputNotifyPvt->userCallbackEvent); + epicsEventWait(pnotifyPvt->userCallbackEvent); dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); - putNotifyCleanup(ppn); + notifyCleanup(ppn); } - pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; - assert(!pputNotifyPvt); - putNotifyInit(ppn); - pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; - if(!precord->ppnr) {/* make sure record has a putNotifyRecord*/ - precord->ppnr = dbCalloc(1,sizeof(putNotifyRecord)); + pnotifyPvt = (notifyPvt *)ppn->pnotifyPvt; + assert(!pnotifyPvt); + notifyInit(ppn); + pnotifyPvt = (notifyPvt *)ppn->pnotifyPvt; + if (!precord->ppnr) { + /* make sure record has a processNotifyRecord*/ + precord->ppnr = dbCalloc(1,sizeof(processNotifyRecord)); precord->ppnr->precord = precord; ellInit(&precord->ppnr->restartList); } - putNotifyCommon(ppn,precord); + processNotifyCommon(ppn, precord); } -void epicsShareAPI dbNotifyCancel(putNotify *ppn) +void epicsShareAPI dbNotifyCancel(processNotify *ppn) { dbCommon *precord = ppn->paddr->precord; - putNotifyState state; - putNotifyPvt *pputNotifyPvt; + notifyState state; + notifyPvt *pnotifyPvt; assert(precord); dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); - pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; - if(!pputNotifyPvt || pputNotifyPvt->state==putNotifyNotActive) { + ppn->status = notifyCanceled; + pnotifyPvt = (notifyPvt *)ppn->pnotifyPvt; + if(!pnotifyPvt || pnotifyPvt->state==notifyNotActive) { epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } - state = pputNotifyPvt->state; + state = pnotifyPvt->state; /*If callback is scheduled or active wait for it to complete*/ - if(state==putNotifyUserCallbackRequested - || state==putNotifyRestartCallbackRequested - || state==putNotifyUserCallbackActive) { - pputNotifyPvt->cancelWait = 1; + if(state==notifyUserCallbackRequested + || state==notifyRestartCallbackRequested + || state==notifyUserCallbackActive) { + pnotifyPvt->cancelWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); - epicsEventWait(pputNotifyPvt->cancelEvent); + epicsEventWait(pnotifyPvt->cancelEvent); epicsMutexMustLock(pnotifyGlobal->lock); - putNotifyCleanup(ppn); + notifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); return; } switch(state) { - case putNotifyNotActive: break; - case putNotifyWaitForRestart: + case notifyNotActive: break; + case notifyWaitForRestart: assert(precord->ppn); assert(precord->ppn!=ppn); ellSafeDelete(&precord->ppnr->restartList,&ppn->restartNode); break; - case putNotifyRestartInProgress: - case putNotifyPutInProgress: + case notifyRestartInProgress: + case notifyProcessInProgress: { /*Take all records out of wait list */ - putNotifyRecord *ppnrWait; + processNotifyRecord *ppnrWait; - while((ppnrWait = (putNotifyRecord *)ellFirst(&pputNotifyPvt->waitList))){ - ellSafeDelete(&pputNotifyPvt->waitList,&ppnrWait->waitNode); + while((ppnrWait = (processNotifyRecord *)ellFirst(&pnotifyPvt->waitList))){ + ellSafeDelete(&pnotifyPvt->waitList,&ppnrWait->waitNode); restartCheck(ppnrWait); } } @@ -391,36 +414,36 @@ void epicsShareAPI dbNotifyCancel(putNotify *ppn) default: printf("dbNotify: illegal state for notifyCallback\n"); } - pputNotifyPvt->state = putNotifyNotActive; - putNotifyCleanup(ppn); + pnotifyPvt->state = notifyNotActive; + notifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); } void epicsShareAPI dbNotifyCompletion(dbCommon *precord) { - putNotify *ppn = precord->ppn; - putNotifyPvt *pputNotifyPvt; + processNotify *ppn = precord->ppn; + notifyPvt *pnotifyPvt; epicsMutexMustLock(pnotifyGlobal->lock); assert(ppn); assert(precord->ppnr); - pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; - if(pputNotifyPvt->state!=putNotifyRestartInProgress - && pputNotifyPvt->state!=putNotifyPutInProgress) { + pnotifyPvt = (notifyPvt *)ppn->pnotifyPvt; + if(pnotifyPvt->state!=notifyRestartInProgress + && pnotifyPvt->state!=notifyProcessInProgress) { epicsMutexUnlock(pnotifyGlobal->lock); return; } - ellSafeDelete(&pputNotifyPvt->waitList,&precord->ppnr->waitNode); - if((ellCount(&pputNotifyPvt->waitList)!=0)) { + ellSafeDelete(&pnotifyPvt->waitList,&precord->ppnr->waitNode); + if((ellCount(&pnotifyPvt->waitList)!=0)) { restartCheck(precord->ppnr); - } else if(pputNotifyPvt->state == putNotifyPutInProgress) { - pputNotifyPvt->state = putNotifyUserCallbackRequested; + } else if(pnotifyPvt->state == notifyProcessInProgress) { + pnotifyPvt->state = notifyUserCallbackRequested; restartCheck(precord->ppnr); - callbackRequest(&pputNotifyPvt->callback); - } else if(pputNotifyPvt->state == putNotifyRestartInProgress) { - pputNotifyPvt->state = putNotifyRestartCallbackRequested; - callbackRequest(&pputNotifyPvt->callback); + callbackRequest(&pnotifyPvt->callback); + } else if(pnotifyPvt->state == notifyRestartInProgress) { + pnotifyPvt->state = notifyRestartCallbackRequested; + callbackRequest(&pnotifyPvt->callback); } else { cantProceed("dbNotifyCompletion illegal state"); } @@ -429,52 +452,103 @@ void epicsShareAPI dbNotifyCompletion(dbCommon *precord) void epicsShareAPI dbNotifyAdd(dbCommon *pfrom, dbCommon *pto) { - putNotify *ppn = pfrom->ppn; - putNotifyPvt *pputNotifyPvt; + processNotify *ppn = pfrom->ppn; + notifyPvt *pnotifyPvt; if(pto->pact) return; /*if active it will not be processed*/ epicsMutexMustLock(pnotifyGlobal->lock); - if(!pto->ppnr) {/* make sure record has a putNotifyRecord*/ - pto->ppnr = dbCalloc(1,sizeof(putNotifyRecord)); + if(!pto->ppnr) {/* make sure record has a processNotifyRecord*/ + pto->ppnr = dbCalloc(1,sizeof(processNotifyRecord)); pto->ppnr->precord = pto; ellInit(&pto->ppnr->restartList); } assert(ppn); - pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; + pnotifyPvt = (notifyPvt *)ppn->pnotifyPvt; if(!(pto->ppn) - && (pputNotifyPvt->state==putNotifyPutInProgress) + && (pnotifyPvt->state==notifyProcessInProgress) && (pto!=ppn->paddr->precord)) { - putNotifyPvt *pputNotifyPvt; + notifyPvt *pnotifyPvt; pto->ppn = pfrom->ppn; - pputNotifyPvt = (putNotifyPvt *)pfrom->ppn->pputNotifyPvt; - ellSafeAdd(&pputNotifyPvt->waitList,&pto->ppnr->waitNode); + pnotifyPvt = (notifyPvt *)pfrom->ppn->pnotifyPvt; + ellSafeAdd(&pnotifyPvt->waitList,&pto->ppnr->waitNode); } epicsMutexUnlock(pnotifyGlobal->lock); } typedef struct tpnInfo { epicsEventId callbackDone; - putNotify *ppn; + processNotify *ppn; + char *psavevalue; }tpnInfo; -static void dbtpnCallback(putNotify *ppn) +static int putCallback(processNotify *ppn,notifyPutType type) { + tpnInfo *ptpnInfo = (tpnInfo *)ppn->usrPvt; + int status = 0; + + if(ppn->status==notifyCanceled) return 0; + ppn->status = notifyOK; + switch(type) { + case putDisabledType: + ppn->status = notifyError; + return 0; + case putFieldType: + status = dbPutField(ppn->paddr,DBR_STRING,ptpnInfo->psavevalue,1); + break; + case putType: + status = dbPut(ppn->paddr,DBR_STRING,ptpnInfo->psavevalue,1); + break; + } + if(status!=0) ppn->status = notifyError; + return 1; +} + +static void getCallback(processNotify *ppn,notifyGetType type) { - putNotifyStatus status = ppn->status; + tpnInfo *ptpnInfo = (tpnInfo *)ppn->usrPvt; + int status = 0; + long no_elements = 1; + long options = 0; + + if(ppn->status==notifyCanceled) { + printf("dbtpn:getCallback notifyCanceled\n"); + return; + } + switch(type) { + case getFieldType: + status = dbGetField(ppn->paddr,DBR_STRING,ptpnInfo->psavevalue, + &options,&no_elements,0); + break; + case getType: + status = dbGet(ppn->paddr,DBR_STRING,ptpnInfo->psavevalue, + &options,&no_elements,0); + break; + } + if(status!=0) { + ppn->status = notifyError; + printf("dbtpn:getCallback error\n"); + } else { + printf("dbtpn:getCallback value %s\n",ptpnInfo->psavevalue); + } +} + +static void doneCallback(processNotify *ppn) +{ + notifyStatus status = ppn->status; tpnInfo *ptpnInfo = (tpnInfo *)ppn->usrPvt; if(status==0) printf("dbtpnCallback: success record=%s\n",ppn->paddr->precord->name); else - printf("%s dbtpnCallback putNotify.status %d\n",ppn->paddr->precord->name,(int)status); + printf("%s dbtpnCallback processNotify.status %d\n",ppn->paddr->precord->name,(int)status); epicsEventSignal(ptpnInfo->callbackDone); } static void tpnThread(void *pvt) { tpnInfo *ptpnInfo = (tpnInfo *)pvt; - putNotify *ppn = (putNotify *)ptpnInfo->ppn; + processNotify *ppn = (processNotify *)ptpnInfo->ppn; - dbPutNotify(ppn); + dbProcessNotify(ppn); epicsEventWait(ptpnInfo->callbackDone); dbNotifyCancel(ppn); epicsEventDestroy(ptpnInfo->callbackDone); @@ -488,30 +562,35 @@ long epicsShareAPI dbtpn(char *pname,char *pvalue) long status; tpnInfo *ptpnInfo; DBADDR *pdbaddr=NULL; - putNotify *ppn=NULL; + processNotify *ppn=NULL; char *psavevalue; - int len; + int len = 80; - len = strlen(pvalue); + if(pvalue) len = strlen(pvalue); /*allocate space for value immediately following DBADDR*/ pdbaddr = dbCalloc(1,sizeof(DBADDR) + len+1); psavevalue = (char *)(pdbaddr + 1); - strcpy(psavevalue,pvalue); + if(pvalue) strcpy(psavevalue,pvalue); status = dbNameToAddr(pname,pdbaddr); if(status) { errMessage(status, "dbtpn: dbNameToAddr"); free((void *)pdbaddr); return(-1); } - ppn = dbCalloc(1,sizeof(putNotify)); + ppn = dbCalloc(1,sizeof(processNotify)); + if(pvalue) { + ppn->requestType = putProcessRequest; + } else { + ppn->requestType = processGetRequest; + } ppn->paddr = pdbaddr; - ppn->pbuffer = psavevalue; - ppn->nRequest = 1; - ppn->dbrType = DBR_STRING; - ppn->userCallback = dbtpnCallback; + ppn->putCallback = putCallback; + ppn->getCallback = getCallback; + ppn->doneCallback = doneCallback; ptpnInfo = dbCalloc(1,sizeof(tpnInfo)); ptpnInfo->ppn = ppn; ptpnInfo->callbackDone = epicsEventCreate(epicsEventEmpty); + ptpnInfo->psavevalue = psavevalue; ppn->usrPvt = ptpnInfo; epicsThreadCreate("dbtpn",epicsThreadPriorityHigh, epicsThreadGetStackSize(epicsThreadStackMedium), @@ -525,49 +604,50 @@ int epicsShareAPI dbNotifyDump(void) dbRecordType *pdbRecordType; dbRecordNode *pdbRecordNode; dbCommon *precord; - putNotify *ppn; - putNotify *ppnRestart; - putNotifyRecord *ppnrWait; + processNotify *ppn; + processNotify *ppnRestart; + processNotifyRecord *ppnr; int itry; - - - for(itry=0; itry<100; itry++) { + + for (itry=0; itry<100; itry++) { lockStatus = epicsMutexTryLock(pnotifyGlobal->lock); if(lockStatus==epicsMutexLockOK) break; epicsThreadSleep(.05); } - for(pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); + for (pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); pdbRecordType; pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { for (pdbRecordNode=(dbRecordNode *)ellFirst(&pdbRecordType->recList); pdbRecordNode; pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) { - putNotifyPvt *pputNotifyPvt; + notifyPvt *pnotifyPvt; precord = pdbRecordNode->precord; - if (!precord->name[0] || - pdbRecordNode->flags & DBRN_FLAGS_ISALIAS) - continue; - if(!precord->ppn) continue; - if(!precord->ppnr) continue; - if(precord->ppn->paddr->precord != precord) continue; ppn = precord->ppn; - pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; - printf("%s state %d ppn %p\n waitList\n", - precord->name,pputNotifyPvt->state,(void*)ppn); - ppnrWait = (putNotifyRecord *)ellFirst(&pputNotifyPvt->waitList); - while(ppnrWait) { - printf(" %s pact %d\n", - ppnrWait->precord->name,ppnrWait->precord->pact); - ppnrWait = (putNotifyRecord *)ellNext(&ppnrWait->waitNode.node); + if (ppn) { + pnotifyPvt = (notifyPvt *)ppn->pnotifyPvt; + printf("%s state %d ppn %p\n waitList\n", + precord->name,pnotifyPvt->state,(void*)ppn); + ppnr = (processNotifyRecord *)ellFirst(&pnotifyPvt->waitList); + while (ppnr) { + printf(" %s pact %d\n", + ppnr->precord->name,ppnr->precord->pact); + ppnr = (processNotifyRecord *)ellNext( + &ppnr->waitNode.node); + } } - printf(" restartList\n"); - ppnRestart = (putNotify *)ellFirst(&precord->ppnr->restartList); - while(ppnRestart) { - printf(" %p\n", (void *)ppnRestart); - ppnRestart = (putNotify *)ellNext(&ppnRestart->restartNode.node); + ppnr = precord->ppnr; + if (ppnr) { + ppnRestart = (processNotify *)ellFirst( + &precord->ppnr->restartList); + if (ppnRestart) printf("%s restartList\n",precord->name); + while (ppnRestart) { + printf(" %s\n",ppnRestart->paddr->precord->name); + ppnRestart = (processNotify *)ellNext( + &ppnRestart->restartNode.node); + } } } } if(lockStatus==epicsMutexLockOK) epicsMutexUnlock(pnotifyGlobal->lock); - return(0); + return 0; } diff --git a/src/ioc/db/dbNotify.h b/src/ioc/db/dbNotify.h index 5c57c0d90..4812368b5 100644 --- a/src/ioc/db/dbNotify.h +++ b/src/ioc/db/dbNotify.h @@ -20,7 +20,7 @@ #ifdef __cplusplus /* for brain dead C++ compilers */ struct dbCommon; - struct putNotify; + struct processNotify; extern "C" { #endif @@ -30,36 +30,54 @@ typedef struct ellCheckNode{ }ellCheckNode; typedef enum { - putNotifyOK, - putNotifyCanceled, - putNotifyError, - putNotifyPutDisabled -}putNotifyStatus; + processRequest, + putProcessRequest, + processGetRequest, + putProcessGetRequest +}notifyRequestType; -typedef struct putNotify{ + +typedef enum { + putDisabledType, + putFieldType, + putType +}notifyPutType; + +typedef enum { + getFieldType, + getType +}notifyGetType; + +typedef enum { + notifyOK, + notifyCanceled, + notifyError, + notifyPutDisabled +}notifyStatus; + +typedef struct processNotify { + /* following fields are for private use by dbNotify implementation */ ellCheckNode restartNode; - /*The following members MUST be set by user*/ - void (*userCallback)(struct putNotify *); + void *pnotifyPvt; /*for private use of dbNotify*/ + /* The following fields are set by dbNotify. */ + notifyStatus status; + int wasProcessed; /* (0,1) => (no,yes) */ + /*The following members are set by user*/ + notifyRequestType requestType; struct dbAddr *paddr; /*dbAddr set by dbNameToAddr*/ - void *pbuffer; /*address of data*/ - long nRequest; /*number of elements to be written*/ - short dbrType; /*database request type*/ - void *usrPvt; /*for private use of user*/ - /*The following is status of request. Set by dbNotify */ - putNotifyStatus status; - void *pputNotifyPvt; /*for private use of putNotify*/ -}putNotify; + int (*putCallback)(struct processNotify *,notifyPutType type); + void (*getCallback)(struct processNotify *,notifyGetType type); + void (*doneCallback)(struct processNotify *); + void *usrPvt; /*for private use of user*/ +}processNotify; -/* dbPutNotify and dbNotifyCancel are the routines called by user*/ -/* The user is normally channel access client or server */ -epicsShareFunc void epicsShareAPI dbPutNotify(putNotify *pputNotify); -epicsShareFunc void epicsShareAPI dbNotifyCancel(putNotify *pputNotify); -/*dbPutNotifyMapType convience function for old database access*/ -epicsShareFunc int epicsShareAPI dbPutNotifyMapType (putNotify *ppn, short oldtype); +/* dbProcessNotify and dbNotifyCancel are called by user*/ +epicsShareFunc void epicsShareAPI dbProcessNotify(processNotify *pprocessNotify); +epicsShareFunc void epicsShareAPI dbNotifyCancel(processNotify *pprocessNotify); -/* dbPutNotifyInit called by iocInit */ -epicsShareFunc void epicsShareAPI dbPutNotifyInit(void); +/* dbProcessNotifyInit called by iocInit */ +epicsShareFunc void epicsShareAPI dbProcessNotifyInit(void); /*dbNotifyAdd called by dbScanPassive and dbScanLink*/ epicsShareFunc void epicsShareAPI dbNotifyAdd( @@ -67,29 +85,61 @@ epicsShareFunc void epicsShareAPI dbNotifyAdd( /*dbNotifyCompletion called by recGblFwdLink or dbAccess*/ epicsShareFunc void epicsShareAPI dbNotifyCompletion(struct dbCommon *precord); -/* dbtpn is test routine for put notify */ +/* db_put_process defined here since it requires dbNotify. + * src_type is the old DBR type + * This is called by a dbNotify putCallback that uses oldDbr types + */ +epicsShareFunc int epicsShareAPI db_put_process( + processNotify *processNotify,notifyPutType type, + int src_type,const void *psrc, int no_elements); + +/* dbtpn is test routine for dbNotify putProcessRequest */ epicsShareFunc long epicsShareAPI dbtpn(char *recordname,char *value); + /* dbNotifyDump is an INVASIVE debug utility. Dont use this needlessly*/ epicsShareFunc int epicsShareAPI dbNotifyDump(void); -/* This module provides code to handle put notify. If a put causes a record to - * be processed, then a user supplied callback is called when that record - * and all records processed because of that record complete processing. - * For asynchronous records completion means completion of the asyn phase. +/* This module provides code to handle process notify. + * client code semantics are: + * 1) The client code allocates storage for a processNotify structure. + * This structure can be used for multiple calls to dbProcessNotify. + * The client is responsible for setting the following fields : + * requestType - The type of request. + * paddr - This is typically set via a call to dbNameToAddr. + * putCallback - If requestType is putProcessRequest or putProcessGetRequest + * getCallback - If request is processGetRequest or putProcessGetRequest + * doneCallback - Must be set + * usrPvt - For exclusive use of client. dbNotify does not access this field + * 2) The client calls dbProcessNotify. + * 3) putCallback is called after dbNotify has claimed the record instance + * but before a potential process is requested. + * The putCallback MUST issue the correct put request + * specified by notifyPutType + * 4) getCallback is called after a possible process is complete + * (including asynchronous completion) but before dbNotify has + * released the record. + * The getCallback MUST issue the correct get request + * specified by notifyGetType + * 5) doneCallback is called when dbNotify has released the record. + * The client can issue a new dbProcessNotify request from + * doneCallback or anytime after doneCallback returns. + * 6) The client can call dbNotifyCancel at any time. + * If a dbProcessNotify is active, dbNotifyCancel will not return until + * the dbNotifyRequest is actually canceled. The client must be prepared + * for a callback to be called while dbNotifyCancel is active. * - * User code calls putNotifyInit, putNotifyCleanup, - * dbPutNotify, and dbNotifyCancel. + * dbProcessNotify handles the semantics of record locking and deciding + * if a process request is issued and also calls the client callbacks. * - * The use must allocate storage for "struct putNotify" - * The user MUST set pputNotifyPvt=0 before the first call to dbPutNotify - * and should never modify it again. + * A process request is issued if any of the following is true. + * 1) The requester has issued a processs request and record is passive. + * 2) The requester is doing a put, the record is passive, and either + * a) The field description is process passive. + * b) The field is PROC. + * 3) The requester has requested processGet and the record is passive. * - * After dbPutNotify is called it may not called for the same putNotify - * until the putCallback is complete. The use can call dbNotifyCancel - * to cancel the operation. - * - * The user callback is called when the operation is completed. + * iocInit calls processNotifyInit. * * The other global routines (dbNotifyAdd and dbNotifyCompletion) are called by: * @@ -101,19 +151,16 @@ epicsShareFunc int epicsShareAPI dbNotifyDump(void); * Unless pact is already true. * recGbl * recGblFwdLink calls dbNotifyCompletion - */ - -/* Two fields in dbCommon are used for put notify. - * ppn pointer to putNotify - * If a record is part of a put notify group, - * This field is the address of the associated putNotify. - * As soon as a record completes processing the field is set NULL - * ppnr pointer to putNotifyRecord - * Address of a putNotifyRecord for 1) list node for records - * put notify is waiting to complete, and 2) a list of records - * to restart. * - * See the Application Developer's Guide for implementation rules + * Two fields in dbCommon are used for put notify. + * ppn pointer to processNotify + * If a record is part of a put notify group, + * This field is the address of the associated processNotify. + * As soon as a record completes processing the field is set NULL + * ppnr pointer to processNotifyRecord, which is a private structure + * owned by dbNotify. + * dbNotify is reponsible for this structure. + * */ #ifdef __cplusplus } diff --git a/src/ioc/db/dbPutNotifyBlocker.cpp b/src/ioc/db/dbPutNotifyBlocker.cpp index e91234b67..c47f1da99 100644 --- a/src/ioc/db/dbPutNotifyBlocker.cpp +++ b/src/ioc/db/dbPutNotifyBlocker.cpp @@ -52,7 +52,7 @@ dbPutNotifyBlocker::dbPutNotifyBlocker ( epicsMutex & mutexIn ) : { memset ( & this->pn, '\0', sizeof ( this->pn ) ); memset ( & this->dbrScalarValue, '\0', sizeof ( this->dbrScalarValue ) ); - this->pn.pbuffer = & this->dbrScalarValue; + this->pbuffer = & this->dbrScalarValue; } dbPutNotifyBlocker::~dbPutNotifyBlocker () @@ -64,7 +64,7 @@ void dbPutNotifyBlocker::destructor ( epicsGuard < epicsMutex > & guard ) guard.assertIdenticalMutex ( this->mutex ); this->cancel ( guard ); if ( this->maxValueSize > sizeof ( this->dbrScalarValue ) ) { - char * pBuf = static_cast < char * > ( this->pn.pbuffer ); + char * pBuf = static_cast < char * > ( this->pbuffer ); delete [] pBuf; } this->~dbPutNotifyBlocker (); @@ -88,17 +88,29 @@ void dbPutNotifyBlocker::expandValueBuf ( guard.assertIdenticalMutex ( this->mutex ); if ( this->maxValueSize < newSize ) { if ( this->maxValueSize > sizeof ( this->dbrScalarValue ) ) { - char * pBuf = static_cast < char * > ( this->pn.pbuffer ); + char * pBuf = static_cast < char * > ( this->pbuffer ); delete [] pBuf; this->maxValueSize = sizeof ( this->dbrScalarValue ); - this->pn.pbuffer = & this->dbrScalarValue; + this->pbuffer = & this->dbrScalarValue; } - this->pn.pbuffer = new char [newSize]; + this->pbuffer = new char [newSize]; this->maxValueSize = newSize; } } -extern "C" void putNotifyCompletion ( putNotify *ppn ) +extern "C" int putNotifyPut ( processNotify *ppn, notifyPutType type ) +{ + if(ppn->status==notifyCanceled) return 0; +/* + * No locking in this method because only a dbNotifyCancel could interrupt + * and it does not return until cancel is done. + */ + dbPutNotifyBlocker * pBlocker = static_cast < dbPutNotifyBlocker * > ( ppn->usrPvt ); + return db_put_process(ppn,type, + pBlocker->dbrType,pBlocker->pbuffer,pBlocker->nRequest); +} + +extern "C" void putNotifyCompletion ( processNotify *ppn ) { dbPutNotifyBlocker * const pBlocker = static_cast < dbPutNotifyBlocker * > ( ppn->usrPvt ); @@ -112,11 +124,11 @@ extern "C" void putNotifyCompletion ( putNotify *ppn ) // unavoidable because its possible that the use callback // might destroy this object. pBlocker->block.signal (); - if ( pBlocker->pn.status != putNotifyOK ) { + if ( pBlocker->pn.status != notifyOK ) { pNtfy->exception ( guard, ECA_PUTFAIL, "put notify unsuccessful", - static_cast < unsigned > (pBlocker->pn.dbrType), - static_cast < unsigned > (pBlocker->pn.nRequest) ); + static_cast < unsigned > (pBlocker->dbrType), + static_cast < unsigned > (pBlocker->nRequest) ); } else { pNtfy->completion ( guard ); @@ -163,25 +175,21 @@ void dbPutNotifyBlocker::initiatePutNotify ( throw cacChannel::badType(); } - int status = dbPutNotifyMapType ( - &this->pn, static_cast ( type ) ); - if ( status ) { - this->pNotify = 0; - throw cacChannel::badType(); - } - - this->pn.nRequest = static_cast < unsigned > ( count ); + this->dbrType = type; + this->nRequest = static_cast < unsigned > ( count ); + this->pn.requestType = putProcessRequest; this->pn.paddr = &addr; - this->pn.userCallback = putNotifyCompletion; + this->pn.putCallback = putNotifyPut; + this->pn.doneCallback = putNotifyCompletion; this->pn.usrPvt = this; unsigned long size = dbr_size_n ( type, count ); this->expandValueBuf ( guard, size ); - memcpy ( this->pn.pbuffer, pValue, size ); + memcpy ( this->pbuffer, pValue, size ); { epicsGuardRelease < epicsMutex > autoRelease ( guard ); - ::dbPutNotify ( &this->pn ); + ::dbProcessNotify ( &this->pn ); } } diff --git a/src/ioc/db/dbPutNotifyBlocker.h b/src/ioc/db/dbPutNotifyBlocker.h index da2cc9fcb..1512977a3 100644 --- a/src/ioc/db/dbPutNotifyBlocker.h +++ b/src/ioc/db/dbPutNotifyBlocker.h @@ -54,7 +54,7 @@ public: epicsPlacementDeleteOperator (( void *, tsFreeList < dbPutNotifyBlocker, 64, epicsMutexNOOP > & )) private: - putNotify pn; + processNotify pn; // // Include a union of all scalar types // including fixed length strings so @@ -75,10 +75,16 @@ private: epicsMutex & mutex; cacWriteNotify * pNotify; unsigned long maxValueSize; + // arguments for db_put_field + void *pbuffer; + long nRequest; + short dbrType; + // end arguments for db_put_field dbSubscriptionIO * isSubscription (); void expandValueBuf ( epicsGuard < epicsMutex > &, unsigned long newSize ); - friend void putNotifyCompletion ( putNotify * ppn ); + friend void putNotifyCompletion ( processNotify * ppn ); + friend int putNotifyPut ( processNotify *ppn, notifyPutType type ); dbPutNotifyBlocker ( const dbPutNotifyBlocker & ); dbPutNotifyBlocker & operator = ( const dbPutNotifyBlocker & ); virtual ~dbPutNotifyBlocker (); diff --git a/src/ioc/db/db_access.c b/src/ioc/db/db_access.c index 5596f1a0e..af7a9b31b 100644 --- a/src/ioc/db/db_access.c +++ b/src/ioc/db/db_access.c @@ -994,39 +994,61 @@ int epicsShareAPI db_put_field(struct dbAddr *paddr, int src_type, } -epicsShareFunc int epicsShareAPI dbPutNotifyMapType (putNotify *ppn, short oldtype) +static int mapOldType (short oldtype) { - switch(oldtype) { - case(oldDBR_STRING): - ppn->dbrType = DBR_STRING; + int dbrType = -1; + + switch (oldtype) { + case oldDBR_STRING: + dbrType = DBR_STRING; break; -/* case(oldDBR_INT): */ - case(oldDBR_SHORT): - ppn->dbrType = DBR_SHORT; +/* case oldDBR_INT: */ + case oldDBR_SHORT: + dbrType = DBR_SHORT; break; - case(oldDBR_FLOAT): - ppn->dbrType = DBR_FLOAT; + case oldDBR_FLOAT: + dbrType = DBR_FLOAT; break; - case(oldDBR_ENUM): - ppn->dbrType = DBR_ENUM; + case oldDBR_ENUM: + dbrType = DBR_ENUM; break; - case(oldDBR_CHAR): - ppn->dbrType = DBR_UCHAR; + case oldDBR_CHAR: + dbrType = DBR_UCHAR; break; - case(oldDBR_LONG): - ppn->dbrType = DBR_LONG; + case oldDBR_LONG: + dbrType = DBR_LONG; break; - case(oldDBR_DOUBLE): - ppn->dbrType = DBR_DOUBLE; + case oldDBR_DOUBLE: + dbrType = DBR_DOUBLE; break; - case(oldDBR_PUT_ACKT): - ppn->dbrType = DBR_PUT_ACKT; + case oldDBR_PUT_ACKT: + dbrType = DBR_PUT_ACKT; break; - case(oldDBR_PUT_ACKS): - ppn->dbrType = DBR_PUT_ACKS; + case oldDBR_PUT_ACKS: + dbrType = DBR_PUT_ACKS; break; default: return -1; } - return 0; + return dbrType; +} + +int epicsShareAPI db_put_process(processNotify *ppn, notifyPutType type, + int src_type, const void *psrc, int no_elements) +{ + int status = 0; + int dbrType = mapOldType(src_type); + switch(type) { + case putDisabledType: + ppn->status = notifyError; + return 0; + case putFieldType: + status = dbPutField(ppn->paddr,dbrType,psrc,no_elements); + break; + case putType: + status = dbPut(ppn->paddr,dbrType,psrc,no_elements); + break; + } + if (status) ppn->status = notifyError; + return 1; } diff --git a/src/ioc/db/db_test.c b/src/ioc/db/db_test.c index 5f44e28ca..8ea2cd66c 100644 --- a/src/ioc/db/db_test.c +++ b/src/ioc/db/db_test.c @@ -637,29 +637,36 @@ static void print_returned(type,count,pbuffer) typedef struct tpnInfo { epicsEventId callbackDone; - putNotify *ppn; + processNotify *ppn; + char *psavevalue; }tpnInfo; -static void tpnCallback(putNotify *ppn) + +static int putCallback(processNotify *ppn,notifyPutType type) { + tpnInfo *ptpnInfo = (tpnInfo *)ppn->usrPvt; + + return db_put_process(ppn,type,DBR_STRING,ptpnInfo->psavevalue,1); +} + +static void doneCallback(processNotify *ppn) { - struct dbAddr *pdbaddr = (struct dbAddr *)ppn->paddr; + notifyStatus status = ppn->status; tpnInfo *ptpnInfo = (tpnInfo *)ppn->usrPvt; - putNotifyStatus status = ppn->status; - char *pname = pdbaddr->precord->name; + char *pname = ppn->paddr->precord->name; if(status==0) - printf("tpnCallback: success record=%s\n",pname); + printf("tpnCallback: success record=%s\n",pname); else - printf("%s tpnCallback status = %d\n",pname,status); + printf("%s tpnCallback processNotify.status %d\n",pname,(int)status); epicsEventSignal(ptpnInfo->callbackDone); } static void tpnThread(void *pvt) { tpnInfo *ptpnInfo = (tpnInfo *)pvt; - putNotify *ppn = (putNotify *)ptpnInfo->ppn; + processNotify *ppn = (processNotify *)ptpnInfo->ppn; - dbPutNotify(ppn); + dbProcessNotify(ppn); epicsEventWait(ptpnInfo->callbackDone); dbNotifyCancel(ppn); epicsEventDestroy(ptpnInfo->callbackDone); @@ -674,7 +681,7 @@ int epicsShareAPI tpn(char *pname,char *pvalue) long status; tpnInfo *ptpnInfo; struct dbAddr *pdbaddr=NULL; - putNotify *ppn=NULL; + processNotify *ppn=NULL; char *psavevalue; int len; @@ -699,20 +706,15 @@ int epicsShareAPI tpn(char *pname,char *pvalue) free((void *)pdbaddr); return(-1); } - ppn = calloc(1,sizeof(putNotify)); - if(!pdbaddr) { + ppn = calloc(1,sizeof(processNotify)); + if(!ppn) { printf("calloc failed\n"); return(-1); } + ppn->requestType = putProcessRequest; ppn->paddr = pdbaddr; - ppn->pbuffer = psavevalue; - ppn->nRequest = 1; - if(dbPutNotifyMapType(ppn,DBR_STRING)) { - printf("dbPutNotifyMapType failed\n"); - printf("calloc failed\n"); - return(-1); - } - ppn->userCallback = tpnCallback; + ppn->putCallback = putCallback; + ppn->doneCallback = doneCallback; ptpnInfo = calloc(1,sizeof(tpnInfo)); if(!ptpnInfo) { printf("calloc failed\n"); @@ -720,6 +722,7 @@ int epicsShareAPI tpn(char *pname,char *pvalue) } ptpnInfo->ppn = ppn; ptpnInfo->callbackDone = epicsEventCreate(epicsEventEmpty); + ptpnInfo->psavevalue = psavevalue; ppn->usrPvt = ptpnInfo; epicsThreadCreate("tpn",epicsThreadPriorityHigh, epicsThreadGetStackSize(epicsThreadStackMedium), diff --git a/src/ioc/misc/iocInit.c b/src/ioc/misc/iocInit.c index 9f9c1a385..b394bec50 100644 --- a/src/ioc/misc/iocInit.c +++ b/src/ioc/misc/iocInit.c @@ -140,7 +140,7 @@ int iocBuild(void) errlogPrintf("iocBuild: asInit Failed.\n"); return -1; } - dbPutNotifyInit(); + dbProcessNotifyInit(); epicsThreadSleep(.5); initHookAnnounce(initHookAfterScanInit); diff --git a/src/ioc/rsrv/camessage.c b/src/ioc/rsrv/camessage.c index 09015f667..02ed285a1 100644 --- a/src/ioc/rsrv/camessage.c +++ b/src/ioc/rsrv/camessage.c @@ -57,7 +57,7 @@ logBadIdWithFileAndLineno(CLIENT, MP, PPL, __FILE__, __LINE__) */ typedef struct rsrv_put_notify { ELLNODE node; - putNotify dbPutNotify; + processNotify dbPutNotify; caHdrLargeArray msg; /* * Include a union of all scalar types @@ -77,8 +77,13 @@ typedef struct rsrv_put_notify { dbr_long_t longval; dbr_double_t doubleval; } dbrScalarValue; + /* arguments for db_put_field */ + void *pbuffer; + long nRequest; + short dbrType; + /* end arguments for db_put_field */ void * asWritePvt; - unsigned valueSize; /* size of block pointed to by dbPutNotify */ + unsigned valueSize; /* size of block pointed to by pbuffer */ char busy; /* put notify in progress */ char onExtraLaborQueue; } RSRVPUTNOTIFY; @@ -1390,11 +1395,33 @@ static int claim_ciu_action ( caHdrLargeArray *mp, } /* - * write_notify_call_back() - * - * (called by the db call back thread) - */ -static void write_notify_call_back(putNotify *ppn) + * write_notify_put_callback() + * + * (called by the db call back thread) + */ + LOCAL int write_notify_put_callback(processNotify *ppn,notifyPutType type) + { + struct channel_in_use * pciu = (struct channel_in_use *) ppn->usrPvt; + struct rsrv_put_notify *pNotify; + + if(ppn->status==notifyCanceled) return 0; + /* + * No locking in this method because only a dbNotifyCancel could interrupt + * and it does not return until cancel is done. + */ + assert(pciu); + assert(pciu->pPutNotify); + pNotify = pciu->pPutNotify; + return db_put_process(ppn,type, + pNotify->dbrType,pNotify->pbuffer,pNotify->nRequest); + } + + /* + * write_notify_done_callback() + * + * (called by the db call back thread) + */ + LOCAL void write_notify_done_callback(processNotify *ppn) { struct channel_in_use * pciu = (struct channel_in_use *) ppn->usrPvt; struct client * pClient; @@ -1460,7 +1487,7 @@ static void write_notify_reply ( struct client * pClient ) * Map from DB status to CA status * */ - if ( ppnb->dbPutNotify.status != putNotifyOK ) { + if ( ppnb->dbPutNotify.status != notifyOK ) { status = ECA_PUTFAIL; } else{ @@ -1593,14 +1620,17 @@ static struct rsrv_put_notify * pNotify = (RSRVPUTNOTIFY *) freeListCalloc ( rsrvPutNotifyFreeList ); if ( pNotify ) { - pNotify->dbPutNotify.pbuffer = + pNotify->pbuffer = &pNotify->dbrScalarValue; pNotify->valueSize = sizeof (pNotify->dbrScalarValue); pNotify->dbPutNotify.usrPvt = pciu; pNotify->dbPutNotify.paddr = &pciu->addr; - pNotify->dbPutNotify.userCallback = - write_notify_call_back; + pNotify->dbPutNotify.putCallback = + write_notify_put_callback; + pNotify->dbPutNotify.doneCallback = + write_notify_done_callback; + pNotify->dbPutNotify.requestType = putProcessRequest; } } else { @@ -1622,10 +1652,10 @@ static int rsrvExpandPutNotify ( */ if ( pNotify->valueSize > sizeof (pNotify->dbrScalarValue) ) { - free ( pNotify->dbPutNotify.pbuffer ); + free ( pNotify->pbuffer ); } - pNotify->dbPutNotify.pbuffer = casCalloc(1,sizeNeeded); - if ( pNotify->dbPutNotify.pbuffer ) { + pNotify->pbuffer = casCalloc(1,sizeNeeded); + if ( pNotify->pbuffer ) { pNotify->valueSize = sizeNeeded; booleanStatus = TRUE; } @@ -1633,7 +1663,7 @@ static int rsrvExpandPutNotify ( /* * revert back to the embedded union */ - pNotify->dbPutNotify.pbuffer = + pNotify->pbuffer = &pNotify->dbrScalarValue; pNotify->valueSize = sizeof (pNotify->dbrScalarValue); @@ -1694,7 +1724,7 @@ void rsrvFreePutNotify ( client *pClient, if ( pNotify->valueSize > sizeof(pNotify->dbrScalarValue) ) { - free ( pNotify->dbPutNotify.pbuffer ); + free ( pNotify->pbuffer ); } freeListFree ( rsrvPutNotifyFreeList, pNotify ); } @@ -1768,7 +1798,7 @@ static int write_notify_action ( caHdrLargeArray *mp, void *pPayload, if ( busyTmp ) { log_header("put call back time out", client, - &pciu->pPutNotify->msg, pciu->pPutNotify->dbPutNotify.pbuffer, 0); + &pciu->pPutNotify->msg, pciu->pPutNotify->pbuffer, 0); asTrapWriteAfter ( asWritePvtTmp ); putNotifyErrorReply (client, &pciu->pPutNotify->msg, ECA_PUTCBINPROG); } @@ -1801,10 +1831,10 @@ static int write_notify_action ( caHdrLargeArray *mp, void *pPayload, pciu->pPutNotify->busy = TRUE; pciu->pPutNotify->onExtraLaborQueue = FALSE; pciu->pPutNotify->msg = *mp; - pciu->pPutNotify->dbPutNotify.nRequest = mp->m_count; + pciu->pPutNotify->nRequest = mp->m_count; status = caNetConvert ( - mp->m_dataType, pPayload, pciu->pPutNotify->dbPutNotify.pbuffer, + mp->m_dataType, pPayload, pciu->pPutNotify->pbuffer, FALSE /* net -> host format */, mp->m_count ); if ( status != ECA_NORMAL ) { log_header ("invalid data type", client, mp, pPayload, 0); @@ -1812,12 +1842,7 @@ static int write_notify_action ( caHdrLargeArray *mp, void *pPayload, return RSRV_ERROR; } - status = dbPutNotifyMapType(&pciu->pPutNotify->dbPutNotify, mp->m_dataType); - if(status){ - putNotifyErrorReply (client, mp, ECA_PUTFAIL); - pciu->pPutNotify->busy = FALSE; - return RSRV_OK; - } + pciu->pPutNotify->dbrType = mp->m_dataType; pciu->pPutNotify->asWritePvt = asTrapWriteBefore ( pciu->asClientPVT, @@ -1825,7 +1850,7 @@ static int write_notify_action ( caHdrLargeArray *mp, void *pPayload, pciu->client->pHostName ? pciu->client->pHostName : "", (void *) &pciu->addr ); - dbPutNotify(&pciu->pPutNotify->dbPutNotify); + dbProcessNotify(&pciu->pPutNotify->dbPutNotify); return RSRV_OK; } diff --git a/src/std/dev/Makefile b/src/std/dev/Makefile index a118f7057..0e3fac9e2 100644 --- a/src/std/dev/Makefile +++ b/src/std/dev/Makefile @@ -42,6 +42,12 @@ dbRecStd_SRCS += devSoSoft.c dbRecStd_SRCS += devWfSoft.c dbRecStd_SRCS += devGeneralTime.c +dbRecStd_SRCS += devAiSoftCallback.c +dbRecStd_SRCS += devBiSoftCallback.c +dbRecStd_SRCS += devLiSoftCallback.c +dbRecStd_SRCS += devMbbiSoftCallback.c +dbRecStd_SRCS += devSiSoftCallback.c + dbRecStd_SRCS += devAoSoftCallback.c dbRecStd_SRCS += devBoSoftCallback.c dbRecStd_SRCS += devCalcoutSoftCallback.c diff --git a/src/std/dev/devAiSoftCallback.c b/src/std/dev/devAiSoftCallback.c new file mode 100644 index 000000000..560f518e1 --- /dev/null +++ b/src/std/dev/devAiSoftCallback.c @@ -0,0 +1,155 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* devAiSoftCallback.c */ +/* + * Author: Marty Kraimer + * Date: 23APR2008 + */ + +#include +#include +#include + +#include "alarm.h" +#include "callback.h" +#include "cantProceed.h" +#include "dbDefs.h" +#include "dbAccess.h" +#include "dbNotify.h" +#include "recGbl.h" +#include "recSup.h" +#include "devSup.h" +#include "link.h" +#include "aiRecord.h" +#include "epicsExport.h" + +/* Create the dset for devAiSoftCallback */ +static long init_record(); +static long read_ai(); +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_ai; + DEVSUPFUN special_linconv; +}devAiSoftCallback={ + 6, + NULL, + NULL, + init_record, + NULL, + read_ai, + NULL}; +epicsExportAddress(dset,devAiSoftCallback); + +typedef struct notifyInfo { + processNotify *ppn; + CALLBACK *pcallback; + double value; + int status; +}notifyInfo; + +static void getCallback(processNotify *ppn,notifyGetType type) +{ + struct aiRecord *pai = (struct aiRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)pai->dpvt; + int status = 0; + long no_elements = 1; + long options = 0; + + if(ppn->status==notifyCanceled) { + printf("dbtpn:getCallback notifyCanceled\n"); + return; + } + switch(type) { + case getFieldType: + status = dbGetField(ppn->paddr,DBR_DOUBLE,&pnotifyInfo->value, + &options,&no_elements,0); + break; + case getType: + status = dbGet(ppn->paddr,DBR_DOUBLE,&pnotifyInfo->value, + &options,&no_elements,0); + break; + } + pnotifyInfo->status = status; +} + +static void doneCallback(processNotify *ppn) +{ + struct aiRecord *pai = (struct aiRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)pai->dpvt; + + callbackRequestProcessCallback(pnotifyInfo->pcallback,pai->prio,pai); +} + + +static long init_record(struct aiRecord *pai) +{ + DBLINK *plink = &pai->inp; + struct instio *pinstio; + char *pvname; + DBADDR *pdbaddr=NULL; + long status; + notifyInfo *pnotifyInfo; + CALLBACK *pcallback; + processNotify *ppn=NULL; + + if(plink->type!=INST_IO) { + recGblRecordError(S_db_badField,(void *)pai, + "devAiSoftCallback (init_record) Illegal INP field"); + pai->pact=TRUE; + return(S_db_badField); + } + pinstio=(struct instio*)&(plink->value); + pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), + "devAiSoftCallback::init_record"); + status = dbNameToAddr(pvname,pdbaddr); + if(status) { + recGblRecordError(status,(void *)pai, + "devAiSoftCallback (init_record) linked record not found"); + pai->pact=TRUE; + return(status); + } + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devAiSoftCallback::init_record"); + pcallback = callocMustSucceed(1, sizeof(*pcallback), + "devAiSoftCallback::init_record"); + ppn = callocMustSucceed(1, sizeof(*ppn), + "devAiSoftCallback::init_record"); + pnotifyInfo->ppn = ppn; + pnotifyInfo->pcallback = pcallback; + ppn->usrPvt = pai; + ppn->paddr = pdbaddr; + ppn->getCallback = getCallback; + ppn->doneCallback = doneCallback; + ppn->requestType = processGetRequest; + pai->dpvt = pnotifyInfo; + return 0; +} + +static long read_ai(aiRecord *pai) +{ + notifyInfo *pnotifyInfo = (notifyInfo *)pai->dpvt; + + if(pai->pact) { + if(pnotifyInfo->status) { + recGblSetSevr(pai,READ_ALARM,INVALID_ALARM); + return(2); + } + pai->val = pnotifyInfo->value; + pai->udf = FALSE; + return(2); + } + dbProcessNotify(pnotifyInfo->ppn); + pai->pact = TRUE; + return(0); +} diff --git a/src/std/dev/devBiSoftCallback.c b/src/std/dev/devBiSoftCallback.c new file mode 100644 index 000000000..8e6a67432 --- /dev/null +++ b/src/std/dev/devBiSoftCallback.c @@ -0,0 +1,155 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* devBiSoftCallback.c */ +/* + * Author: Marty Kraimer + * Date: 23APR2008 + */ + +#include +#include +#include + +#include "alarm.h" +#include "callback.h" +#include "cantProceed.h" +#include "dbDefs.h" +#include "dbAccess.h" +#include "dbNotify.h" +#include "recGbl.h" +#include "recSup.h" +#include "devSup.h" +#include "link.h" +#include "biRecord.h" +#include "epicsExport.h" + +/* Create the dset for devBiSoftCallback */ +static long init_record(); +static long read_bi(); +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_bi; + DEVSUPFUN special_linconv; +}devBiSoftCallback={ + 6, + NULL, + NULL, + init_record, + NULL, + read_bi, + NULL}; +epicsExportAddress(dset,devBiSoftCallback); + +typedef struct notifyInfo { + processNotify *ppn; + CALLBACK *pcallback; + unsigned short value; + int status; +}notifyInfo; + +static void getCallback(processNotify *ppn,notifyGetType type) +{ + struct biRecord *pbi = (struct biRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)pbi->dpvt; + int status = 0; + long no_elements = 1; + long options = 0; + + if(ppn->status==notifyCanceled) { + printf("dbtpn:getCallback notifyCanceled\n"); + return; + } + switch(type) { + case getFieldType: + status = dbGetField(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, + &options,&no_elements,0); + break; + case getType: + status = dbGet(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, + &options,&no_elements,0); + break; + } + pnotifyInfo->status = status; +} + +static void doneCallback(processNotify *ppn) +{ + struct biRecord *pbi = (struct biRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)pbi->dpvt; + + callbackRequestProcessCallback(pnotifyInfo->pcallback,pbi->prio,pbi); +} + + +static long init_record(struct biRecord *pbi) +{ + DBLINK *plink = &pbi->inp; + struct instio *pinstio; + char *pvname; + DBADDR *pdbaddr=NULL; + long status; + notifyInfo *pnotifyInfo; + CALLBACK *pcallback; + processNotify *ppn=NULL; + + if(plink->type!=INST_IO) { + recGblRecordError(S_db_badField,(void *)pbi, + "devBiSoftCallback (init_record) linked record not found"); + pbi->pact=TRUE; + return(S_db_badField); + } + pinstio=(struct instio*)&(plink->value); + pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), + "devBiSoftCallback::init_record"); + status = dbNameToAddr(pvname,pdbaddr); + if(status) { + recGblRecordError(status,(void *)pbi, + "devBiSoftCallback (init_record) Illegal INP field"); + pbi->pact=TRUE; + return(status); + } + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devBiSoftCallback::init_record"); + pcallback = callocMustSucceed(1, sizeof(*pcallback), + "devBiSoftCallback::init_record"); + ppn = callocMustSucceed(1, sizeof(*ppn), + "devBiSoftCallback::init_record"); + pnotifyInfo->ppn = ppn; + pnotifyInfo->pcallback = pcallback; + ppn->usrPvt = pbi; + ppn->paddr = pdbaddr; + ppn->getCallback = getCallback; + ppn->doneCallback = doneCallback; + ppn->requestType = processGetRequest; + pbi->dpvt = pnotifyInfo; + return 0; +} + +static long read_bi(biRecord *pbi) +{ + notifyInfo *pnotifyInfo = (notifyInfo *)pbi->dpvt; + + if(pbi->pact) { + if(pnotifyInfo->status) { + recGblSetSevr(pbi,READ_ALARM,INVALID_ALARM); + return(2); + } + pbi->val = pnotifyInfo->value; + pbi->udf = FALSE; + return(2); + } + dbProcessNotify(pnotifyInfo->ppn); + pbi->pact = TRUE; + return(0); +} diff --git a/src/std/dev/devLiSoftCallback.c b/src/std/dev/devLiSoftCallback.c new file mode 100644 index 000000000..1cdf21b2e --- /dev/null +++ b/src/std/dev/devLiSoftCallback.c @@ -0,0 +1,155 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* devLiSoftCallback.c */ +/* + * Author: Marty Kraimer + * Date: 23APR2008 + */ + +#include +#include +#include + +#include "alarm.h" +#include "callback.h" +#include "cantProceed.h" +#include "dbDefs.h" +#include "dbAccess.h" +#include "dbNotify.h" +#include "recGbl.h" +#include "recSup.h" +#include "devSup.h" +#include "link.h" +#include "longinRecord.h" +#include "epicsExport.h" + +/* Create the dset for devLiSoftCallback */ +static long init_record(); +static long read_li(); +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_li; + DEVSUPFUN special_linconv; +}devLiSoftCallback={ + 6, + NULL, + NULL, + init_record, + NULL, + read_li, + NULL}; +epicsExportAddress(dset,devLiSoftCallback); + +typedef struct notifyInfo { + processNotify *ppn; + CALLBACK *pcallback; + long value; + int status; +}notifyInfo; + +static void getCallback(processNotify *ppn,notifyGetType type) +{ + struct longinRecord *pli = (struct longinRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)pli->dpvt; + int status = 0; + long no_elements = 1; + long options = 0; + + if(ppn->status==notifyCanceled) { + printf("dbtpn:getCallback notifyCanceled\n"); + return; + } + switch(type) { + case getFieldType: + status = dbGetField(ppn->paddr,DBR_LONG,&pnotifyInfo->value, + &options,&no_elements,0); + break; + case getType: + status = dbGet(ppn->paddr,DBR_LONG,&pnotifyInfo->value, + &options,&no_elements,0); + break; + } + pnotifyInfo->status = status; +} + +static void doneCallback(processNotify *ppn) +{ + struct longinRecord *pli = (struct longinRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)pli->dpvt; + + callbackRequestProcessCallback(pnotifyInfo->pcallback,pli->prio,pli); +} + + +static long init_record(struct longinRecord *pli) +{ + DBLINK *plink = &pli->inp; + struct instio *pinstio; + char *pvname; + DBADDR *pdbaddr=NULL; + long status; + notifyInfo *pnotifyInfo; + CALLBACK *pcallback; + processNotify *ppn=NULL; + + if(plink->type!=INST_IO) { + recGblRecordError(S_db_badField,(void *)pli, + "devLiSoftCallback (init_record) linked record not found"); + pli->pact=TRUE; + return(S_db_badField); + } + pinstio=(struct instio*)&(plink->value); + pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), + "devLiSoftCallback::init_record"); + status = dbNameToAddr(pvname,pdbaddr); + if(status) { + recGblRecordError(status,(void *)pli, + "devLiSoftCallback (init_record) Illegal INP field"); + pli->pact=TRUE; + return(status); + } + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devLiSoftCallback::init_record"); + pcallback = callocMustSucceed(1, sizeof(*pcallback), + "devLiSoftCallback::init_record"); + ppn = callocMustSucceed(1, sizeof(*ppn), + "devLiSoftCallback::init_record"); + pnotifyInfo->ppn = ppn; + pnotifyInfo->pcallback = pcallback; + ppn->usrPvt = pli; + ppn->paddr = pdbaddr; + ppn->getCallback = getCallback; + ppn->doneCallback = doneCallback; + ppn->requestType = processGetRequest; + pli->dpvt = pnotifyInfo; + return 0; +} + +static long read_li(longinRecord *pli) +{ + notifyInfo *pnotifyInfo = (notifyInfo *)pli->dpvt; + + if(pli->pact) { + if(pnotifyInfo->status) { + recGblSetSevr(pli,READ_ALARM,INVALID_ALARM); + return(pnotifyInfo->status); + } + pli->val = pnotifyInfo->value; + pli->udf = FALSE; + return(0); + } + dbProcessNotify(pnotifyInfo->ppn); + pli->pact = TRUE; + return(0); +} diff --git a/src/std/dev/devMbbiSoftCallback.c b/src/std/dev/devMbbiSoftCallback.c new file mode 100644 index 000000000..b0fb1b7e5 --- /dev/null +++ b/src/std/dev/devMbbiSoftCallback.c @@ -0,0 +1,155 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* devMbbiSoftCallback.c */ +/* + * Author: Marty Kraimer + * Date: 23APR2008 + */ + +#include +#include +#include + +#include "alarm.h" +#include "callback.h" +#include "cantProceed.h" +#include "dbDefs.h" +#include "dbAccess.h" +#include "dbNotify.h" +#include "recGbl.h" +#include "recSup.h" +#include "devSup.h" +#include "link.h" +#include "mbbiRecord.h" +#include "epicsExport.h" + +/* Create the dset for devMbbiSoftCallback */ +static long init_record(); +static long read_mbbi(); +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_mbbi; + DEVSUPFUN special_linconv; +}devMbbiSoftCallback={ + 6, + NULL, + NULL, + init_record, + NULL, + read_mbbi, + NULL}; +epicsExportAddress(dset,devMbbiSoftCallback); + +typedef struct notifyInfo { + processNotify *ppn; + CALLBACK *pcallback; + unsigned short value; + int status; +}notifyInfo; + +static void getCallback(processNotify *ppn,notifyGetType type) +{ + struct mbbiRecord *pmbbi = (struct mbbiRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)pmbbi->dpvt; + int status = 0; + long no_elements = 1; + long options = 0; + + if(ppn->status==notifyCanceled) { + printf("dbtpn:getCallback notifyCanceled\n"); + return; + } + switch(type) { + case getFieldType: + status = dbGetField(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, + &options,&no_elements,0); + break; + case getType: + status = dbGet(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, + &options,&no_elements,0); + break; + } + pnotifyInfo->status = status; +} + +static void doneCallback(processNotify *ppn) +{ + struct mbbiRecord *pmbbi = (struct mbbiRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)pmbbi->dpvt; + + callbackRequestProcessCallback(pnotifyInfo->pcallback,pmbbi->prio,pmbbi); +} + + +static long init_record(struct mbbiRecord *pmbbi) +{ + DBLINK *plink = &pmbbi->inp; + struct instio *pinstio; + char *pvname; + DBADDR *pdbaddr=NULL; + long status; + notifyInfo *pnotifyInfo; + CALLBACK *pcallback; + processNotify *ppn=NULL; + + if(plink->type!=INST_IO) { + recGblRecordError(S_db_badField,(void *)pmbbi, + "devMbbiSoftCallback (init_record) linked record not found"); + pmbbi->pact=TRUE; + return(S_db_badField); + } + pinstio=(struct instio*)&(plink->value); + pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), + "devMbbiSoftCallback::init_record"); + status = dbNameToAddr(pvname,pdbaddr); + if(status) { + recGblRecordError(status,(void *)pmbbi, + "devMbbiSoftCallback (init_record) Illegal INP field"); + pmbbi->pact=TRUE; + return(status); + } + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devMbbiSoftCallback::init_record"); + pcallback = callocMustSucceed(1, sizeof(*pcallback), + "devMbbiSoftCallback::init_record"); + ppn = callocMustSucceed(1, sizeof(*ppn), + "devMbbiSoftCallback::init_record"); + pnotifyInfo->ppn = ppn; + pnotifyInfo->pcallback = pcallback; + ppn->usrPvt = pmbbi; + ppn->paddr = pdbaddr; + ppn->getCallback = getCallback; + ppn->doneCallback = doneCallback; + ppn->requestType = processGetRequest; + pmbbi->dpvt = pnotifyInfo; + return 0; +} + +static long read_mbbi(mbbiRecord *pmbbi) +{ + notifyInfo *pnotifyInfo = (notifyInfo *)pmbbi->dpvt; + + if(pmbbi->pact) { + if(pnotifyInfo->status) { + recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM); + return(2); + } + pmbbi->val = pnotifyInfo->value; + pmbbi->udf = FALSE; + return(2); + } + dbProcessNotify(pnotifyInfo->ppn); + pmbbi->pact = TRUE; + return(0); +} diff --git a/src/std/dev/devSiSoftCallback.c b/src/std/dev/devSiSoftCallback.c new file mode 100644 index 000000000..bb2d88ce5 --- /dev/null +++ b/src/std/dev/devSiSoftCallback.c @@ -0,0 +1,155 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* devSiSoftCallback.c */ +/* + * Author: Marty Kraimer + * Date: 23APR2008 + */ + +#include +#include +#include + +#include "alarm.h" +#include "callback.h" +#include "cantProceed.h" +#include "dbDefs.h" +#include "dbAccess.h" +#include "dbNotify.h" +#include "recGbl.h" +#include "recSup.h" +#include "devSup.h" +#include "link.h" +#include "stringinRecord.h" +#include "epicsExport.h" + +/* Create the dset for devSiSoftCallback */ +static long init_record(); +static long read_stringin(); +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_stringin; + DEVSUPFUN special_linconv; +}devSiSoftCallback={ + 6, + NULL, + NULL, + init_record, + NULL, + read_stringin, + NULL}; +epicsExportAddress(dset,devSiSoftCallback); + +typedef struct notifyInfo { + processNotify *ppn; + CALLBACK *pcallback; + char value[40]; + int status; +}notifyInfo; + +static void getCallback(processNotify *ppn,notifyGetType type) +{ + struct stringinRecord *pstringin = (struct stringinRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)pstringin->dpvt; + int status = 0; + long no_elements = 1; + long options = 0; + + if(ppn->status==notifyCanceled) { + printf("dbtpn:getCallback notifyCanceled\n"); + return; + } + switch(type) { + case getFieldType: + status = dbGetField(ppn->paddr,DBR_STRING,&pnotifyInfo->value, + &options,&no_elements,0); + break; + case getType: + status = dbGet(ppn->paddr,DBR_STRING,&pnotifyInfo->value, + &options,&no_elements,0); + break; + } + pnotifyInfo->status = status; +} + +static void doneCallback(processNotify *ppn) +{ + struct stringinRecord *pstringin = (struct stringinRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)pstringin->dpvt; + + callbackRequestProcessCallback(pnotifyInfo->pcallback,pstringin->prio,pstringin); +} + + +static long init_record(struct stringinRecord *pstringin) +{ + DBLINK *plink = &pstringin->inp; + struct instio *pinstio; + char *pvname; + DBADDR *pdbaddr=NULL; + long status; + notifyInfo *pnotifyInfo; + CALLBACK *pcallback; + processNotify *ppn=NULL; + + if(plink->type!=INST_IO) { + recGblRecordError(S_db_badField,(void *)pstringin, + "devSiSoftCallback (init_record) linked record not found"); + pstringin->pact=TRUE; + return(S_db_badField); + } + pinstio=(struct instio*)&(plink->value); + pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), + "devSiSoftCallback::init_record"); + status = dbNameToAddr(pvname,pdbaddr); + if(status) { + recGblRecordError(status,(void *)pstringin, + "devSiSoftCallback (init_record) Illegal INP field"); + pstringin->pact=TRUE; + return(status); + } + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devSiSoftCallback::init_record"); + pcallback = callocMustSucceed(1, sizeof(*pcallback), + "devSiSoftCallback::init_record"); + ppn = callocMustSucceed(1, sizeof(*ppn), + "devSiSoftCallback::init_record"); + pnotifyInfo->ppn = ppn; + pnotifyInfo->pcallback = pcallback; + ppn->usrPvt = pstringin; + ppn->paddr = pdbaddr; + ppn->getCallback = getCallback; + ppn->doneCallback = doneCallback; + ppn->requestType = processGetRequest; + pstringin->dpvt = pnotifyInfo; + return 0; +} + +static long read_stringin(stringinRecord *pstringin) +{ + notifyInfo *pnotifyInfo = (notifyInfo *)pstringin->dpvt; + + if(pstringin->pact) { + if(pnotifyInfo->status) { + recGblSetSevr(pstringin,READ_ALARM,INVALID_ALARM); + return(pnotifyInfo->status); + } + strcpy(pstringin->val,pnotifyInfo->value); + pstringin->udf = FALSE; + return(0); + } + dbProcessNotify(pnotifyInfo->ppn); + pstringin->pact = TRUE; + return(0); +} diff --git a/src/std/dev/devSoft.dbd b/src/std/dev/devSoft.dbd index 5f90aba86..860a0a500 100644 --- a/src/std/dev/devSoft.dbd +++ b/src/std/dev/devSoft.dbd @@ -27,6 +27,12 @@ device(mbbiDirect,CONSTANT,devMbbiDirectSoftRaw,"Raw Soft Channel") device(mbbo,CONSTANT,devMbboSoftRaw,"Raw Soft Channel") device(mbboDirect,CONSTANT,devMbboDirectSoftRaw,"Raw Soft Channel") +device(ai,INST_IO,devAiSoftCallback,"Async Soft Channel") +device(bi,INST_IO,devBiSoftCallback,"Async Soft Channel") +device(mbbi,INST_IO,devMbbiSoftCallback,"Async Soft Channel") +device(longin,INST_IO,devLiSoftCallback,"Async Soft Channel") +device(stringin,INST_IO,devSiSoftCallback,"Async Soft Channel") + device(ao,CONSTANT,devAoSoftCallback,"Async Soft Channel") device(bo,CONSTANT,devBoSoftCallback,"Async Soft Channel") device(calcout,CONSTANT,devCalcoutSoftCallback,"Async Soft Channel") From 57cc033b52de69ad678fe3ab94a69a897f6dd63c Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 28 Dec 2009 22:05:21 -0600 Subject: [PATCH 2/9] Correct error messages. --- src/std/dev/devBiSoftCallback.c | 4 ++-- src/std/dev/devLiSoftCallback.c | 4 ++-- src/std/dev/devMbbiSoftCallback.c | 4 ++-- src/std/dev/devSiSoftCallback.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/std/dev/devBiSoftCallback.c b/src/std/dev/devBiSoftCallback.c index 8e6a67432..bcd110bf7 100644 --- a/src/std/dev/devBiSoftCallback.c +++ b/src/std/dev/devBiSoftCallback.c @@ -104,7 +104,7 @@ static long init_record(struct biRecord *pbi) if(plink->type!=INST_IO) { recGblRecordError(S_db_badField,(void *)pbi, - "devBiSoftCallback (init_record) linked record not found"); + "devBiSoftCallback (init_record) Illegal INP field"); pbi->pact=TRUE; return(S_db_badField); } @@ -115,7 +115,7 @@ static long init_record(struct biRecord *pbi) status = dbNameToAddr(pvname,pdbaddr); if(status) { recGblRecordError(status,(void *)pbi, - "devBiSoftCallback (init_record) Illegal INP field"); + "devBiSoftCallback (init_record) linked record not found"); pbi->pact=TRUE; return(status); } diff --git a/src/std/dev/devLiSoftCallback.c b/src/std/dev/devLiSoftCallback.c index 1cdf21b2e..350fa258f 100644 --- a/src/std/dev/devLiSoftCallback.c +++ b/src/std/dev/devLiSoftCallback.c @@ -104,7 +104,7 @@ static long init_record(struct longinRecord *pli) if(plink->type!=INST_IO) { recGblRecordError(S_db_badField,(void *)pli, - "devLiSoftCallback (init_record) linked record not found"); + "devLiSoftCallback (init_record) Illegal INP field"); pli->pact=TRUE; return(S_db_badField); } @@ -115,7 +115,7 @@ static long init_record(struct longinRecord *pli) status = dbNameToAddr(pvname,pdbaddr); if(status) { recGblRecordError(status,(void *)pli, - "devLiSoftCallback (init_record) Illegal INP field"); + "devLiSoftCallback (init_record) linked record not found"); pli->pact=TRUE; return(status); } diff --git a/src/std/dev/devMbbiSoftCallback.c b/src/std/dev/devMbbiSoftCallback.c index b0fb1b7e5..e23113672 100644 --- a/src/std/dev/devMbbiSoftCallback.c +++ b/src/std/dev/devMbbiSoftCallback.c @@ -104,7 +104,7 @@ static long init_record(struct mbbiRecord *pmbbi) if(plink->type!=INST_IO) { recGblRecordError(S_db_badField,(void *)pmbbi, - "devMbbiSoftCallback (init_record) linked record not found"); + "devMbbiSoftCallback (init_record) Illegal INP field"); pmbbi->pact=TRUE; return(S_db_badField); } @@ -115,7 +115,7 @@ static long init_record(struct mbbiRecord *pmbbi) status = dbNameToAddr(pvname,pdbaddr); if(status) { recGblRecordError(status,(void *)pmbbi, - "devMbbiSoftCallback (init_record) Illegal INP field"); + "devMbbiSoftCallback (init_record) linked record not found"); pmbbi->pact=TRUE; return(status); } diff --git a/src/std/dev/devSiSoftCallback.c b/src/std/dev/devSiSoftCallback.c index bb2d88ce5..46b2e92f9 100644 --- a/src/std/dev/devSiSoftCallback.c +++ b/src/std/dev/devSiSoftCallback.c @@ -104,7 +104,7 @@ static long init_record(struct stringinRecord *pstringin) if(plink->type!=INST_IO) { recGblRecordError(S_db_badField,(void *)pstringin, - "devSiSoftCallback (init_record) linked record not found"); + "devSiSoftCallback (init_record) Illegal INP field"); pstringin->pact=TRUE; return(S_db_badField); } @@ -115,7 +115,7 @@ static long init_record(struct stringinRecord *pstringin) status = dbNameToAddr(pvname,pdbaddr); if(status) { recGblRecordError(status,(void *)pstringin, - "devSiSoftCallback (init_record) Illegal INP field"); + "devSiSoftCallback (init_record) linked record not found"); pstringin->pact=TRUE; return(status); } From 02b90344570c0bd1926080e3b68a61955f15bc6b Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 30 Dec 2009 00:06:19 -0600 Subject: [PATCH 3/9] Added async soft channel support for mbbiDirect records --- src/std/dev/Makefile | 1 + src/std/dev/devMbbiDirectSoftCallback.c | 155 ++++++++++++++++++++++++ src/std/dev/devSoft.dbd | 1 + 3 files changed, 157 insertions(+) create mode 100644 src/std/dev/devMbbiDirectSoftCallback.c diff --git a/src/std/dev/Makefile b/src/std/dev/Makefile index 0e3fac9e2..3d291e05a 100644 --- a/src/std/dev/Makefile +++ b/src/std/dev/Makefile @@ -45,6 +45,7 @@ dbRecStd_SRCS += devGeneralTime.c dbRecStd_SRCS += devAiSoftCallback.c dbRecStd_SRCS += devBiSoftCallback.c dbRecStd_SRCS += devLiSoftCallback.c +dbRecStd_SRCS += devMbbiDirectSoftCallback.c dbRecStd_SRCS += devMbbiSoftCallback.c dbRecStd_SRCS += devSiSoftCallback.c diff --git a/src/std/dev/devMbbiDirectSoftCallback.c b/src/std/dev/devMbbiDirectSoftCallback.c new file mode 100644 index 000000000..e56ef6e16 --- /dev/null +++ b/src/std/dev/devMbbiDirectSoftCallback.c @@ -0,0 +1,155 @@ +/*************************************************************************\ +* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* devMbbiDirectSoftCallback.c */ +/* + * Author: Marty Kraimer + * Date: 23APR2008 + */ + +#include +#include +#include + +#include "alarm.h" +#include "callback.h" +#include "cantProceed.h" +#include "dbDefs.h" +#include "dbAccess.h" +#include "dbNotify.h" +#include "recGbl.h" +#include "recSup.h" +#include "devSup.h" +#include "link.h" +#include "mbbiDirectRecord.h" +#include "epicsExport.h" + +/* Create the dset for devMbbiDirectSoftCallback */ +static long init_record(); +static long read_mbbiDirect(); +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_mbbiDirect; + DEVSUPFUN special_linconv; +} devMbbiDirectSoftCallback = { + 6, + NULL, + NULL, + init_record, + NULL, + read_mbbiDirect, + NULL}; +epicsExportAddress(dset, devMbbiDirectSoftCallback); + +typedef struct notifyInfo { + processNotify *ppn; + CALLBACK *pcallback; + unsigned short value; + int status; +} notifyInfo; + +static void getCallback(processNotify *ppn, notifyGetType type) +{ + struct mbbiDirectRecord *prec = (struct mbbiDirectRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + int status = 0; + long no_elements = 1; + long options = 0; + + if (ppn->status==notifyCanceled) { + printf("dbtpn:getCallback notifyCanceled\n"); + return; + } + switch (type) { + case getFieldType: + status = dbGetField(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, + &options,&no_elements,0); + break; + case getType: + status = dbGet(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, + &options,&no_elements,0); + break; + } + pnotifyInfo->status = status; +} + +static void doneCallback(processNotify *ppn) +{ + struct mbbiDirectRecord *prec = (struct mbbiDirectRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + + callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); +} + + +static long init_record(struct mbbiDirectRecord *prec) +{ + DBLINK *plink = &prec->inp; + struct instio *pinstio; + char *pvname; + DBADDR *pdbaddr=NULL; + long status; + notifyInfo *pnotifyInfo; + CALLBACK *pcallback; + processNotify *ppn=NULL; + + if (plink->type!=INST_IO) { + recGblRecordError(S_db_badField,(void *)prec, + "devMbbiDirectSoftCallback (init_record) Illegal INP field"); + prec->pact=TRUE; + return S_db_badField; + } + pinstio=(struct instio*)&(plink->value); + pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), + "devMbbiDirectSoftCallback::init_record"); + status = dbNameToAddr(pvname,pdbaddr); + if (status) { + recGblRecordError(status,(void *)prec, + "devMbbiDirectSoftCallback (init_record) linked record not found"); + prec->pact=TRUE; + return status; + } + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devMbbiDirectSoftCallback::init_record"); + pcallback = callocMustSucceed(1, sizeof(*pcallback), + "devMbbiDirectSoftCallback::init_record"); + ppn = callocMustSucceed(1, sizeof(*ppn), + "devMbbiDirectSoftCallback::init_record"); + pnotifyInfo->ppn = ppn; + pnotifyInfo->pcallback = pcallback; + ppn->usrPvt = prec; + ppn->paddr = pdbaddr; + ppn->getCallback = getCallback; + ppn->doneCallback = doneCallback; + ppn->requestType = processGetRequest; + prec->dpvt = pnotifyInfo; + return 0; +} + +static long read_mbbiDirect(mbbiDirectRecord *prec) +{ + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + + if (prec->pact) { + if (pnotifyInfo->status) { + recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); + return 2; + } + prec->val = pnotifyInfo->value; + prec->udf = FALSE; + return 2; + } + dbProcessNotify(pnotifyInfo->ppn); + prec->pact = TRUE; + return 0; +} diff --git a/src/std/dev/devSoft.dbd b/src/std/dev/devSoft.dbd index 860a0a500..f6a93241d 100644 --- a/src/std/dev/devSoft.dbd +++ b/src/std/dev/devSoft.dbd @@ -30,6 +30,7 @@ device(mbboDirect,CONSTANT,devMbboDirectSoftRaw,"Raw Soft Channel") device(ai,INST_IO,devAiSoftCallback,"Async Soft Channel") device(bi,INST_IO,devBiSoftCallback,"Async Soft Channel") device(mbbi,INST_IO,devMbbiSoftCallback,"Async Soft Channel") +device(mbbiDirect,INST_IO,devMbbiDirectSoftCallback,"Async Soft Channel") device(longin,INST_IO,devLiSoftCallback,"Async Soft Channel") device(stringin,INST_IO,devSiSoftCallback,"Async Soft Channel") From c6da34286e86373ecf8fbeb7de07b36a8833c906 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 30 Dec 2009 00:14:06 -0600 Subject: [PATCH 4/9] Use prec for record pointers, to match other supports --- src/std/dev/devAiSoftCallback.c | 40 +++++++++++++++---------------- src/std/dev/devBiSoftCallback.c | 40 +++++++++++++++---------------- src/std/dev/devLiSoftCallback.c | 40 +++++++++++++++---------------- src/std/dev/devMbbiSoftCallback.c | 40 +++++++++++++++---------------- src/std/dev/devSiSoftCallback.c | 40 +++++++++++++++---------------- 5 files changed, 100 insertions(+), 100 deletions(-) diff --git a/src/std/dev/devAiSoftCallback.c b/src/std/dev/devAiSoftCallback.c index 560f518e1..89c59016e 100644 --- a/src/std/dev/devAiSoftCallback.c +++ b/src/std/dev/devAiSoftCallback.c @@ -59,8 +59,8 @@ typedef struct notifyInfo { static void getCallback(processNotify *ppn,notifyGetType type) { - struct aiRecord *pai = (struct aiRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)pai->dpvt; + struct aiRecord *prec = (struct aiRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; int status = 0; long no_elements = 1; long options = 0; @@ -84,16 +84,16 @@ static void getCallback(processNotify *ppn,notifyGetType type) static void doneCallback(processNotify *ppn) { - struct aiRecord *pai = (struct aiRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)pai->dpvt; + struct aiRecord *prec = (struct aiRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback,pai->prio,pai); + callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); } -static long init_record(struct aiRecord *pai) +static long init_record(struct aiRecord *prec) { - DBLINK *plink = &pai->inp; + DBLINK *plink = &prec->inp; struct instio *pinstio; char *pvname; DBADDR *pdbaddr=NULL; @@ -103,9 +103,9 @@ static long init_record(struct aiRecord *pai) processNotify *ppn=NULL; if(plink->type!=INST_IO) { - recGblRecordError(S_db_badField,(void *)pai, + recGblRecordError(S_db_badField,(void *)prec, "devAiSoftCallback (init_record) Illegal INP field"); - pai->pact=TRUE; + prec->pact=TRUE; return(S_db_badField); } pinstio=(struct instio*)&(plink->value); @@ -114,9 +114,9 @@ static long init_record(struct aiRecord *pai) "devAiSoftCallback::init_record"); status = dbNameToAddr(pvname,pdbaddr); if(status) { - recGblRecordError(status,(void *)pai, + recGblRecordError(status,(void *)prec, "devAiSoftCallback (init_record) linked record not found"); - pai->pact=TRUE; + prec->pact=TRUE; return(status); } pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), @@ -127,29 +127,29 @@ static long init_record(struct aiRecord *pai) "devAiSoftCallback::init_record"); pnotifyInfo->ppn = ppn; pnotifyInfo->pcallback = pcallback; - ppn->usrPvt = pai; + ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pai->dpvt = pnotifyInfo; + prec->dpvt = pnotifyInfo; return 0; } -static long read_ai(aiRecord *pai) +static long read_ai(aiRecord *prec) { - notifyInfo *pnotifyInfo = (notifyInfo *)pai->dpvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - if(pai->pact) { + if(prec->pact) { if(pnotifyInfo->status) { - recGblSetSevr(pai,READ_ALARM,INVALID_ALARM); + recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); return(2); } - pai->val = pnotifyInfo->value; - pai->udf = FALSE; + prec->val = pnotifyInfo->value; + prec->udf = FALSE; return(2); } dbProcessNotify(pnotifyInfo->ppn); - pai->pact = TRUE; + prec->pact = TRUE; return(0); } diff --git a/src/std/dev/devBiSoftCallback.c b/src/std/dev/devBiSoftCallback.c index bcd110bf7..8a9c97c8f 100644 --- a/src/std/dev/devBiSoftCallback.c +++ b/src/std/dev/devBiSoftCallback.c @@ -59,8 +59,8 @@ typedef struct notifyInfo { static void getCallback(processNotify *ppn,notifyGetType type) { - struct biRecord *pbi = (struct biRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)pbi->dpvt; + struct biRecord *prec = (struct biRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; int status = 0; long no_elements = 1; long options = 0; @@ -84,16 +84,16 @@ static void getCallback(processNotify *ppn,notifyGetType type) static void doneCallback(processNotify *ppn) { - struct biRecord *pbi = (struct biRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)pbi->dpvt; + struct biRecord *prec = (struct biRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback,pbi->prio,pbi); + callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); } -static long init_record(struct biRecord *pbi) +static long init_record(struct biRecord *prec) { - DBLINK *plink = &pbi->inp; + DBLINK *plink = &prec->inp; struct instio *pinstio; char *pvname; DBADDR *pdbaddr=NULL; @@ -103,9 +103,9 @@ static long init_record(struct biRecord *pbi) processNotify *ppn=NULL; if(plink->type!=INST_IO) { - recGblRecordError(S_db_badField,(void *)pbi, + recGblRecordError(S_db_badField,(void *)prec, "devBiSoftCallback (init_record) Illegal INP field"); - pbi->pact=TRUE; + prec->pact=TRUE; return(S_db_badField); } pinstio=(struct instio*)&(plink->value); @@ -114,9 +114,9 @@ static long init_record(struct biRecord *pbi) "devBiSoftCallback::init_record"); status = dbNameToAddr(pvname,pdbaddr); if(status) { - recGblRecordError(status,(void *)pbi, + recGblRecordError(status,(void *)prec, "devBiSoftCallback (init_record) linked record not found"); - pbi->pact=TRUE; + prec->pact=TRUE; return(status); } pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), @@ -127,29 +127,29 @@ static long init_record(struct biRecord *pbi) "devBiSoftCallback::init_record"); pnotifyInfo->ppn = ppn; pnotifyInfo->pcallback = pcallback; - ppn->usrPvt = pbi; + ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pbi->dpvt = pnotifyInfo; + prec->dpvt = pnotifyInfo; return 0; } -static long read_bi(biRecord *pbi) +static long read_bi(biRecord *prec) { - notifyInfo *pnotifyInfo = (notifyInfo *)pbi->dpvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - if(pbi->pact) { + if(prec->pact) { if(pnotifyInfo->status) { - recGblSetSevr(pbi,READ_ALARM,INVALID_ALARM); + recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); return(2); } - pbi->val = pnotifyInfo->value; - pbi->udf = FALSE; + prec->val = pnotifyInfo->value; + prec->udf = FALSE; return(2); } dbProcessNotify(pnotifyInfo->ppn); - pbi->pact = TRUE; + prec->pact = TRUE; return(0); } diff --git a/src/std/dev/devLiSoftCallback.c b/src/std/dev/devLiSoftCallback.c index 350fa258f..de87dbc06 100644 --- a/src/std/dev/devLiSoftCallback.c +++ b/src/std/dev/devLiSoftCallback.c @@ -59,8 +59,8 @@ typedef struct notifyInfo { static void getCallback(processNotify *ppn,notifyGetType type) { - struct longinRecord *pli = (struct longinRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)pli->dpvt; + struct longinRecord *prec = (struct longinRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; int status = 0; long no_elements = 1; long options = 0; @@ -84,16 +84,16 @@ static void getCallback(processNotify *ppn,notifyGetType type) static void doneCallback(processNotify *ppn) { - struct longinRecord *pli = (struct longinRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)pli->dpvt; + struct longinRecord *prec = (struct longinRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback,pli->prio,pli); + callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); } -static long init_record(struct longinRecord *pli) +static long init_record(struct longinRecord *prec) { - DBLINK *plink = &pli->inp; + DBLINK *plink = &prec->inp; struct instio *pinstio; char *pvname; DBADDR *pdbaddr=NULL; @@ -103,9 +103,9 @@ static long init_record(struct longinRecord *pli) processNotify *ppn=NULL; if(plink->type!=INST_IO) { - recGblRecordError(S_db_badField,(void *)pli, + recGblRecordError(S_db_badField,(void *)prec, "devLiSoftCallback (init_record) Illegal INP field"); - pli->pact=TRUE; + prec->pact=TRUE; return(S_db_badField); } pinstio=(struct instio*)&(plink->value); @@ -114,9 +114,9 @@ static long init_record(struct longinRecord *pli) "devLiSoftCallback::init_record"); status = dbNameToAddr(pvname,pdbaddr); if(status) { - recGblRecordError(status,(void *)pli, + recGblRecordError(status,(void *)prec, "devLiSoftCallback (init_record) linked record not found"); - pli->pact=TRUE; + prec->pact=TRUE; return(status); } pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), @@ -127,29 +127,29 @@ static long init_record(struct longinRecord *pli) "devLiSoftCallback::init_record"); pnotifyInfo->ppn = ppn; pnotifyInfo->pcallback = pcallback; - ppn->usrPvt = pli; + ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pli->dpvt = pnotifyInfo; + prec->dpvt = pnotifyInfo; return 0; } -static long read_li(longinRecord *pli) +static long read_li(longinRecord *prec) { - notifyInfo *pnotifyInfo = (notifyInfo *)pli->dpvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - if(pli->pact) { + if(prec->pact) { if(pnotifyInfo->status) { - recGblSetSevr(pli,READ_ALARM,INVALID_ALARM); + recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); return(pnotifyInfo->status); } - pli->val = pnotifyInfo->value; - pli->udf = FALSE; + prec->val = pnotifyInfo->value; + prec->udf = FALSE; return(0); } dbProcessNotify(pnotifyInfo->ppn); - pli->pact = TRUE; + prec->pact = TRUE; return(0); } diff --git a/src/std/dev/devMbbiSoftCallback.c b/src/std/dev/devMbbiSoftCallback.c index e23113672..71afe482a 100644 --- a/src/std/dev/devMbbiSoftCallback.c +++ b/src/std/dev/devMbbiSoftCallback.c @@ -59,8 +59,8 @@ typedef struct notifyInfo { static void getCallback(processNotify *ppn,notifyGetType type) { - struct mbbiRecord *pmbbi = (struct mbbiRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)pmbbi->dpvt; + struct mbbiRecord *prec = (struct mbbiRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; int status = 0; long no_elements = 1; long options = 0; @@ -84,16 +84,16 @@ static void getCallback(processNotify *ppn,notifyGetType type) static void doneCallback(processNotify *ppn) { - struct mbbiRecord *pmbbi = (struct mbbiRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)pmbbi->dpvt; + struct mbbiRecord *prec = (struct mbbiRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback,pmbbi->prio,pmbbi); + callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); } -static long init_record(struct mbbiRecord *pmbbi) +static long init_record(struct mbbiRecord *prec) { - DBLINK *plink = &pmbbi->inp; + DBLINK *plink = &prec->inp; struct instio *pinstio; char *pvname; DBADDR *pdbaddr=NULL; @@ -103,9 +103,9 @@ static long init_record(struct mbbiRecord *pmbbi) processNotify *ppn=NULL; if(plink->type!=INST_IO) { - recGblRecordError(S_db_badField,(void *)pmbbi, + recGblRecordError(S_db_badField,(void *)prec, "devMbbiSoftCallback (init_record) Illegal INP field"); - pmbbi->pact=TRUE; + prec->pact=TRUE; return(S_db_badField); } pinstio=(struct instio*)&(plink->value); @@ -114,9 +114,9 @@ static long init_record(struct mbbiRecord *pmbbi) "devMbbiSoftCallback::init_record"); status = dbNameToAddr(pvname,pdbaddr); if(status) { - recGblRecordError(status,(void *)pmbbi, + recGblRecordError(status,(void *)prec, "devMbbiSoftCallback (init_record) linked record not found"); - pmbbi->pact=TRUE; + prec->pact=TRUE; return(status); } pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), @@ -127,29 +127,29 @@ static long init_record(struct mbbiRecord *pmbbi) "devMbbiSoftCallback::init_record"); pnotifyInfo->ppn = ppn; pnotifyInfo->pcallback = pcallback; - ppn->usrPvt = pmbbi; + ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pmbbi->dpvt = pnotifyInfo; + prec->dpvt = pnotifyInfo; return 0; } -static long read_mbbi(mbbiRecord *pmbbi) +static long read_mbbi(mbbiRecord *prec) { - notifyInfo *pnotifyInfo = (notifyInfo *)pmbbi->dpvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - if(pmbbi->pact) { + if(prec->pact) { if(pnotifyInfo->status) { - recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM); + recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); return(2); } - pmbbi->val = pnotifyInfo->value; - pmbbi->udf = FALSE; + prec->val = pnotifyInfo->value; + prec->udf = FALSE; return(2); } dbProcessNotify(pnotifyInfo->ppn); - pmbbi->pact = TRUE; + prec->pact = TRUE; return(0); } diff --git a/src/std/dev/devSiSoftCallback.c b/src/std/dev/devSiSoftCallback.c index 46b2e92f9..c5ac85d48 100644 --- a/src/std/dev/devSiSoftCallback.c +++ b/src/std/dev/devSiSoftCallback.c @@ -59,8 +59,8 @@ typedef struct notifyInfo { static void getCallback(processNotify *ppn,notifyGetType type) { - struct stringinRecord *pstringin = (struct stringinRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)pstringin->dpvt; + struct stringinRecord *prec = (struct stringinRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; int status = 0; long no_elements = 1; long options = 0; @@ -84,16 +84,16 @@ static void getCallback(processNotify *ppn,notifyGetType type) static void doneCallback(processNotify *ppn) { - struct stringinRecord *pstringin = (struct stringinRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)pstringin->dpvt; + struct stringinRecord *prec = (struct stringinRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback,pstringin->prio,pstringin); + callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); } -static long init_record(struct stringinRecord *pstringin) +static long init_record(struct stringinRecord *prec) { - DBLINK *plink = &pstringin->inp; + DBLINK *plink = &prec->inp; struct instio *pinstio; char *pvname; DBADDR *pdbaddr=NULL; @@ -103,9 +103,9 @@ static long init_record(struct stringinRecord *pstringin) processNotify *ppn=NULL; if(plink->type!=INST_IO) { - recGblRecordError(S_db_badField,(void *)pstringin, + recGblRecordError(S_db_badField,(void *)prec, "devSiSoftCallback (init_record) Illegal INP field"); - pstringin->pact=TRUE; + prec->pact=TRUE; return(S_db_badField); } pinstio=(struct instio*)&(plink->value); @@ -114,9 +114,9 @@ static long init_record(struct stringinRecord *pstringin) "devSiSoftCallback::init_record"); status = dbNameToAddr(pvname,pdbaddr); if(status) { - recGblRecordError(status,(void *)pstringin, + recGblRecordError(status,(void *)prec, "devSiSoftCallback (init_record) linked record not found"); - pstringin->pact=TRUE; + prec->pact=TRUE; return(status); } pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), @@ -127,29 +127,29 @@ static long init_record(struct stringinRecord *pstringin) "devSiSoftCallback::init_record"); pnotifyInfo->ppn = ppn; pnotifyInfo->pcallback = pcallback; - ppn->usrPvt = pstringin; + ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pstringin->dpvt = pnotifyInfo; + prec->dpvt = pnotifyInfo; return 0; } -static long read_stringin(stringinRecord *pstringin) +static long read_stringin(stringinRecord *prec) { - notifyInfo *pnotifyInfo = (notifyInfo *)pstringin->dpvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - if(pstringin->pact) { + if(prec->pact) { if(pnotifyInfo->status) { - recGblSetSevr(pstringin,READ_ALARM,INVALID_ALARM); + recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); return(pnotifyInfo->status); } - strcpy(pstringin->val,pnotifyInfo->value); - pstringin->udf = FALSE; + strcpy(prec->val,pnotifyInfo->value); + prec->udf = FALSE; return(0); } dbProcessNotify(pnotifyInfo->ppn); - pstringin->pact = TRUE; + prec->pact = TRUE; return(0); } From f7d02cc2a8bd654594d2cf3b49a86514ec00b8e5 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 7 Jan 2010 23:48:49 -0600 Subject: [PATCH 5/9] Convert INST_IO links to regular PV_LINK types, for VDCT support. Added new PN_LINK type in link.h, make dbStaticLib display it. Made all device support extended so links can be changed at runtime. Modified startup so add_record() always called before regular link processing. Incomplete, stilll need to add MS/MSS/MSI support, currently disabled. --- src/ioc/db/dbAccess.c | 4 +- src/ioc/db/dbNotify.h | 2 +- src/ioc/dbStatic/dbStaticLib.c | 11 +- src/ioc/dbStatic/link.h | 4 +- src/ioc/misc/iocInit.c | 21 ++- src/std/dev/devAiSoftCallback.c | 218 +++++++++++++++--------- src/std/dev/devBiSoftCallback.c | 205 +++++++++++++--------- src/std/dev/devLiSoftCallback.c | 205 +++++++++++++--------- src/std/dev/devMbbiDirectSoftCallback.c | 193 +++++++++++++-------- src/std/dev/devMbbiSoftCallback.c | 209 ++++++++++++++--------- src/std/dev/devSiSoftCallback.c | 204 +++++++++++++--------- src/std/dev/devSoft.dbd | 13 +- 12 files changed, 812 insertions(+), 477 deletions(-) diff --git a/src/ioc/db/dbAccess.c b/src/ioc/db/dbAccess.c index d1ea856ec..ba0865461 100644 --- a/src/ioc/db/dbAccess.c +++ b/src/ioc/db/dbAccess.c @@ -1216,10 +1216,10 @@ static long dbPutFieldLink(DBADDR *paddr, plink->value.pv_link.lastGetdbrType = 0; break; + case PV_LINK: case CONSTANT: break; /* do nothing */ - case PV_LINK: case MACRO_LINK: break; /* should never get here */ @@ -1292,7 +1292,7 @@ static long dbPutFieldLink(DBADDR *paddr, break; case CONSTANT: - break; + break; /* do nothing */ case DB_LINK: case CA_LINK: diff --git a/src/ioc/db/dbNotify.h b/src/ioc/db/dbNotify.h index 4812368b5..7d93080b9 100644 --- a/src/ioc/db/dbNotify.h +++ b/src/ioc/db/dbNotify.h @@ -45,7 +45,7 @@ typedef enum { typedef enum { getFieldType, - getType + getType /* FIXME: Never used? */ }notifyGetType; typedef enum { diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c index 8841e1aeb..e5b3bdd89 100644 --- a/src/ioc/dbStatic/dbStaticLib.c +++ b/src/ioc/dbStatic/dbStaticLib.c @@ -59,6 +59,7 @@ epicsShareDef maplinkType pamaplinkType[LINK_NTYPES] = { {"GPIB_IO",GPIB_IO}, {"BITBUS_IO",BITBUS_IO}, {"MACRO_LINK",MACRO_LINK}, + {"PN_LINK",PN_LINK}, {"DB_LINK",DB_LINK}, {"CA_LINK",CA_LINK}, {"INST_IO",INST_IO}, @@ -291,7 +292,8 @@ static long setLinkType(DBENTRY *pdbentry) } type = plink->type; - if ((type == CONSTANT || type == PV_LINK || type == DB_LINK || type == CA_LINK) && + if ((type == CONSTANT || type == PV_LINK || + type == PN_LINK || type == DB_LINK || type == CA_LINK) && (link_type == CONSTANT || link_type == PV_LINK)) goto done; dbFreeLinkContents(plink); @@ -2015,6 +2017,12 @@ char * epicsShareAPI dbGetString(DBENTRY *pdbentry) strcpy(message,""); } break; + case PN_LINK: + if(plink->value.pv_link.pvname) + strcpy(message,plink->value.pv_link.pvname); + else + strcpy(message,""); + break; case PV_LINK: case CA_LINK: case DB_LINK: { @@ -3706,6 +3714,7 @@ int epicsShareAPI dbGetLinkType(DBENTRY *pdbentry) case CONSTANT: return(DCT_LINK_CONSTANT); case PV_LINK: + case PN_LINK: case DB_LINK: case CA_LINK: return(DCT_LINK_PV); diff --git a/src/ioc/dbStatic/link.h b/src/ioc/dbStatic/link.h index c9818f6f0..4b9948dbf 100644 --- a/src/ioc/dbStatic/link.h +++ b/src/ioc/dbStatic/link.h @@ -35,13 +35,15 @@ extern "C" { #define GPIB_IO 5 #define BITBUS_IO 6 #define MACRO_LINK 7 + +#define PN_LINK 9 #define DB_LINK 10 #define CA_LINK 11 #define INST_IO 12 /* instrument */ #define BBGPIB_IO 13 /* bitbus -> gpib */ #define RF_IO 14 #define VXI_IO 15 -#define LINK_NTYPES 14 +#define LINK_NTYPES 15 typedef struct maplinkType{ char *strvalue; int value; diff --git a/src/ioc/misc/iocInit.c b/src/ioc/misc/iocInit.c index b394bec50..5e271766a 100644 --- a/src/ioc/misc/iocInit.c +++ b/src/ioc/misc/iocInit.c @@ -426,7 +426,6 @@ static void doInitRecord0(dbRecordType *pdbRecordType, dbCommon *precord, static void doResolveLinks(dbRecordType *pdbRecordType, dbCommon *precord, void *user) { - devSup *pdevSup; int j; /* Convert all PV_LINKs to DB_LINKs or CA_LINKs */ @@ -435,6 +434,19 @@ static void doResolveLinks(dbRecordType *pdbRecordType, dbCommon *precord, dbFldDes *pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->link_ind[j]]; DBLINK *plink = (DBLINK *)((char *)precord + pdbFldDes->offset); + int isDevLink = ellCount(&precord->rdes->devList) > 0 && + (strcmp(pdbFldDes->name, "INP") == 0 || strcmp(pdbFldDes->name, "OUT") == 0); + + if (isDevLink) { + devSup *pdevSup = dbDTYPtoDevSup(pdbRecordType, precord->dtyp); + + if (pdevSup) { + struct dsxt *pdsxt = pdevSup->pdsxt; + if (pdsxt && pdsxt->add_record) { + pdsxt->add_record(precord); + } + } + } if (plink->type == PV_LINK) { DBADDR dbaddr; @@ -469,13 +481,6 @@ static void doResolveLinks(dbRecordType *pdbRecordType, dbCommon *precord, } } } - pdevSup = dbDTYPtoDevSup(pdbRecordType, precord->dtyp); - if (pdevSup) { - struct dsxt *pdsxt = pdevSup->pdsxt; - if (pdsxt && pdsxt->add_record) { - pdsxt->add_record(precord); - } - } } static void doInitRecord1(dbRecordType *pdbRecordType, dbCommon *precord, diff --git a/src/std/dev/devAiSoftCallback.c b/src/std/dev/devAiSoftCallback.c index 89c59016e..24b933d88 100644 --- a/src/std/dev/devAiSoftCallback.c +++ b/src/std/dev/devAiSoftCallback.c @@ -1,5 +1,5 @@ /*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. @@ -8,17 +8,20 @@ \*************************************************************************/ /* devAiSoftCallback.c */ /* - * Author: Marty Kraimer - * Date: 23APR2008 + * Authors: Marty Kraimer & Andrew Johnson + */ + +/* TODO: + * Support MS/MSS/MSI link flags */ #include #include -#include #include "alarm.h" #include "callback.h" #include "cantProceed.h" +#include "dbCommon.h" #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" @@ -29,54 +32,35 @@ #include "aiRecord.h" #include "epicsExport.h" -/* Create the dset for devAiSoftCallback */ -static long init_record(); -static long read_ai(); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv; -}devAiSoftCallback={ - 6, - NULL, - NULL, - init_record, - NULL, - read_ai, - NULL}; -epicsExportAddress(dset,devAiSoftCallback); - typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; double value; - int status; -}notifyInfo; + int status; + int smooth; +} notifyInfo; -static void getCallback(processNotify *ppn,notifyGetType type) +static void getCallback(processNotify *ppn, notifyGetType type) { - struct aiRecord *prec = (struct aiRecord *)ppn->usrPvt; + aiRecord *prec = (aiRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; int status = 0; long no_elements = 1; long options = 0; - if(ppn->status==notifyCanceled) { - printf("dbtpn:getCallback notifyCanceled\n"); + if (ppn->status == notifyCanceled) { + printf("devAiSoftCallback::getCallback notifyCanceled\n"); return; } - switch(type) { + + switch (type) { case getFieldType: - status = dbGetField(ppn->paddr,DBR_DOUBLE,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGetField(ppn->paddr, DBR_DOUBLE, &pnotifyInfo->value, + &options, &no_elements, 0); break; case getType: - status = dbGet(ppn->paddr,DBR_DOUBLE,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGet(ppn->paddr, DBR_DOUBLE, &pnotifyInfo->value, + &options, &no_elements, 0); break; } pnotifyInfo->status = status; @@ -84,72 +68,152 @@ static void getCallback(processNotify *ppn,notifyGetType type) static void doneCallback(processNotify *ppn) { - struct aiRecord *prec = (struct aiRecord *)ppn->usrPvt; + aiRecord *prec = (aiRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); + callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); } - -static long init_record(struct aiRecord *prec) +static long add_record(dbCommon *pcommon) { + aiRecord *prec = (aiRecord *)pcommon; DBLINK *plink = &prec->inp; - struct instio *pinstio; - char *pvname; - DBADDR *pdbaddr=NULL; + DBADDR *pdbaddr; long status; notifyInfo *pnotifyInfo; - CALLBACK *pcallback; - processNotify *ppn=NULL; + processNotify *ppn; - if(plink->type!=INST_IO) { - recGblRecordError(S_db_badField,(void *)prec, - "devAiSoftCallback (init_record) Illegal INP field"); - prec->pact=TRUE; - return(S_db_badField); + if (plink->type == CONSTANT) return 0; + + if (plink->type != PV_LINK) { + recGblRecordError(S_db_badField, (void *)prec, + "devAiSoftCallback (add_record) Illegal INP field"); + return S_db_badField; } - pinstio=(struct instio*)&(plink->value); - pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devAiSoftCallback::init_record"); - status = dbNameToAddr(pvname,pdbaddr); - if(status) { - recGblRecordError(status,(void *)prec, - "devAiSoftCallback (init_record) linked record not found"); - prec->pact=TRUE; - return(status); + "devAiSoftCallback::add_record"); + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); + if (status) { + free(pdbaddr); + recGblRecordError(status, (void *)prec, + "devAiSoftCallback (add_record) link target not found"); + return status; } - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), - "devAiSoftCallback::init_record"); - pcallback = callocMustSucceed(1, sizeof(*pcallback), - "devAiSoftCallback::init_record"); + + plink->type = PN_LINK; + plink->value.pv_link.precord = pcommon; + plink->value.pv_link.pvt = pdbaddr; + plink->value.pv_link.pvlMask = 0; + ppn = callocMustSucceed(1, sizeof(*ppn), - "devAiSoftCallback::init_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->pcallback = pcallback; + "devAiSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; + + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devAiSoftCallback::add_record"); + pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + "devAiSoftCallback::add_record"); + pnotifyInfo->ppn = ppn; + prec->dpvt = pnotifyInfo; return 0; } +static long del_record(dbCommon *pcommon) { + aiRecord *prec = (aiRecord *)pcommon; + DBLINK *plink = &prec->inp; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + + if (plink->type == CONSTANT) return 0; + assert (plink->type == PN_LINK); + + dbNotifyCancel(pnotifyInfo->ppn); + free(pnotifyInfo->ppn); + free(pnotifyInfo->pcallback); + free(pnotifyInfo); + free(plink->value.pv_link.pvt); + + plink->type = PV_LINK; + plink->value.pv_link.pvt = NULL; + return 0; +} + +static struct dsxt dsxtSoftCallback = { + add_record, del_record +}; + +static long init(int pass) +{ + if (pass == 0) devExtend(&dsxtSoftCallback); + return 0; +} + +static long init_record(aiRecord *prec) +{ + /* INP must be CONSTANT or PN_LINK */ + switch (prec->inp.type) { + case CONSTANT: + if (recGblInitConstantLink(&prec->inp, DBF_DOUBLE, &prec->val)) + prec->udf = FALSE; + break; + case PN_LINK: + /* Handled by add_record */ + break; + default: + recGblRecordError(S_db_badField, (void *)prec, + "devAiSoftCallback (init_record) Illegal INP field"); + prec->pact = TRUE; + return S_db_badField; + } + return 0; +} + static long read_ai(aiRecord *prec) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - if(prec->pact) { - if(pnotifyInfo->status) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); - } - prec->val = pnotifyInfo->value; - prec->udf = FALSE; - return(2); + if (!prec->dpvt) + return 2; + + if (!prec->pact) { + dbProcessNotify(pnotifyInfo->ppn); + prec->pact = TRUE; + return 0; } - dbProcessNotify(pnotifyInfo->ppn); - prec->pact = TRUE; - return(0); + + if (pnotifyInfo->status) { + recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); + pnotifyInfo->smooth = FALSE; + return 2; + } + + /* Apply smoothing algorithm */ + if (prec->smoo != 0.0 && pnotifyInfo->smooth) + prec->val = pnotifyInfo->value * (1.0 - prec->smoo) + prec->val * prec->smoo; + else + prec->val = pnotifyInfo->value; + prec->udf = FALSE; + pnotifyInfo->smooth = TRUE; + + if (prec->tsel.type == CONSTANT && + prec->tse == epicsTimeEventDeviceTime) + prec->time = prec->inp.value.pv_link.precord->time; + return 2; } + +/* Create the dset for devAiSoftCallback */ +struct { + dset common; + DEVSUPFUN read_ai; + DEVSUPFUN special_linconv; +} devAiSoftCallback = { + {6, NULL, init, init_record, NULL}, + read_ai, + NULL +}; +epicsExportAddress(dset, devAiSoftCallback); diff --git a/src/std/dev/devBiSoftCallback.c b/src/std/dev/devBiSoftCallback.c index 8a9c97c8f..a19609ee6 100644 --- a/src/std/dev/devBiSoftCallback.c +++ b/src/std/dev/devBiSoftCallback.c @@ -1,5 +1,5 @@ /*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. @@ -8,17 +8,16 @@ \*************************************************************************/ /* devBiSoftCallback.c */ /* - * Author: Marty Kraimer - * Date: 23APR2008 + * Authors: Marty Kraimer & Andrew Johnson */ #include #include -#include #include "alarm.h" #include "callback.h" #include "cantProceed.h" +#include "dbCommon.h" #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" @@ -29,54 +28,34 @@ #include "biRecord.h" #include "epicsExport.h" -/* Create the dset for devBiSoftCallback */ -static long init_record(); -static long read_bi(); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_bi; - DEVSUPFUN special_linconv; -}devBiSoftCallback={ - 6, - NULL, - NULL, - init_record, - NULL, - read_bi, - NULL}; -epicsExportAddress(dset,devBiSoftCallback); - typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; - unsigned short value; - int status; -}notifyInfo; + epicsEnum16 value; + int status; +} notifyInfo; static void getCallback(processNotify *ppn,notifyGetType type) { - struct biRecord *prec = (struct biRecord *)ppn->usrPvt; + biRecord *prec = (biRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; int status = 0; long no_elements = 1; long options = 0; - if(ppn->status==notifyCanceled) { - printf("dbtpn:getCallback notifyCanceled\n"); + if (ppn->status == notifyCanceled) { + printf("devBiSoftCallback::getCallback notifyCanceled\n"); return; } - switch(type) { + + switch (type) { case getFieldType: - status = dbGetField(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGetField(ppn->paddr, DBR_ENUM, &pnotifyInfo->value, + &options, &no_elements, 0); break; case getType: - status = dbGet(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGet(ppn->paddr, DBR_ENUM, &pnotifyInfo->value, + &options, &no_elements, 0); break; } pnotifyInfo->status = status; @@ -84,72 +63,144 @@ static void getCallback(processNotify *ppn,notifyGetType type) static void doneCallback(processNotify *ppn) { - struct biRecord *prec = (struct biRecord *)ppn->usrPvt; + biRecord *prec = (biRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); + callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); } - -static long init_record(struct biRecord *prec) +static long add_record(dbCommon *pcommon) { + biRecord *prec = (biRecord *)pcommon; DBLINK *plink = &prec->inp; - struct instio *pinstio; - char *pvname; - DBADDR *pdbaddr=NULL; + DBADDR *pdbaddr; long status; notifyInfo *pnotifyInfo; - CALLBACK *pcallback; - processNotify *ppn=NULL; + processNotify *ppn; - if(plink->type!=INST_IO) { - recGblRecordError(S_db_badField,(void *)prec, - "devBiSoftCallback (init_record) Illegal INP field"); - prec->pact=TRUE; - return(S_db_badField); + if (plink->type == CONSTANT) return 0; + + if (plink->type != PV_LINK) { + recGblRecordError(S_db_badField, (void *)prec, + "devBiSoftCallback (add_record) Illegal INP field"); + return S_db_badField; } - pinstio=(struct instio*)&(plink->value); - pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devBiSoftCallback::init_record"); - status = dbNameToAddr(pvname,pdbaddr); - if(status) { - recGblRecordError(status,(void *)prec, - "devBiSoftCallback (init_record) linked record not found"); - prec->pact=TRUE; - return(status); + "devBiSoftCallback::add_record"); + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); + if (status) { + free(pdbaddr); + recGblRecordError(status, (void *)prec, + "devBiSoftCallback (add_record) link target not found"); + return status; } - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), - "devBiSoftCallback::init_record"); - pcallback = callocMustSucceed(1, sizeof(*pcallback), - "devBiSoftCallback::init_record"); + + plink->type = PN_LINK; + plink->value.pv_link.precord = pcommon; + plink->value.pv_link.pvt = pdbaddr; + plink->value.pv_link.pvlMask = 0; + ppn = callocMustSucceed(1, sizeof(*ppn), - "devBiSoftCallback::init_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->pcallback = pcallback; + "devBiSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; + + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devBiSoftCallback::add_record"); + pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + "devBiSoftCallback::add_record"); + pnotifyInfo->ppn = ppn; + prec->dpvt = pnotifyInfo; return 0; } +static long del_record(dbCommon *pcommon) { + biRecord *prec = (biRecord *)pcommon; + DBLINK *plink = &prec->inp; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + + if (plink->type == CONSTANT) return 0; + assert (plink->type == PN_LINK); + + dbNotifyCancel(pnotifyInfo->ppn); + free(pnotifyInfo->ppn); + free(pnotifyInfo->pcallback); + free(pnotifyInfo); + free(plink->value.pv_link.pvt); + + plink->type = PV_LINK; + plink->value.pv_link.pvt = NULL; + return 0; +} + +static struct dsxt dsxtSoftCallback = { + add_record, del_record +}; + +static long init(int pass) +{ + if (pass == 0) devExtend(&dsxtSoftCallback); + return 0; +} + +static long init_record(biRecord *prec) +{ + /* INP must be CONSTANT or PN_LINK */ + switch (prec->inp.type) { + case CONSTANT: + if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val)) + prec->udf = FALSE; + break; + case PN_LINK: + /* Handled by add_record */ + break; + default: + recGblRecordError(S_db_badField, (void *)prec, + "devBiSoftCallback (init_record) Illegal INP field"); + prec->pact = TRUE; + return S_db_badField; + } + return 0; +} + static long read_bi(biRecord *prec) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - if(prec->pact) { - if(pnotifyInfo->status) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); - } - prec->val = pnotifyInfo->value; - prec->udf = FALSE; - return(2); + if (!prec->dpvt) + return 2; + + if (!prec->pact) { + dbProcessNotify(pnotifyInfo->ppn); + prec->pact = TRUE; + return 0; } - dbProcessNotify(pnotifyInfo->ppn); - prec->pact = TRUE; - return(0); + + if (pnotifyInfo->status) { + recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); + return 2; + } + + prec->val = pnotifyInfo->value; + prec->udf = FALSE; + + if (prec->tsel.type == CONSTANT && + prec->tse == epicsTimeEventDeviceTime) + prec->time = prec->inp.value.pv_link.precord->time; + return 2; } + +/* Create the dset for devBiSoftCallback */ +struct { + dset common; + DEVSUPFUN read_bi; +} devBiSoftCallback = { + {5, NULL, init, init_record, NULL}, + read_bi +}; +epicsExportAddress(dset, devBiSoftCallback); diff --git a/src/std/dev/devLiSoftCallback.c b/src/std/dev/devLiSoftCallback.c index de87dbc06..fe710d579 100644 --- a/src/std/dev/devLiSoftCallback.c +++ b/src/std/dev/devLiSoftCallback.c @@ -1,5 +1,5 @@ /*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. @@ -8,17 +8,16 @@ \*************************************************************************/ /* devLiSoftCallback.c */ /* - * Author: Marty Kraimer - * Date: 23APR2008 + * Authors: Marty Kraimer & Andrew Johnson */ #include #include -#include #include "alarm.h" #include "callback.h" #include "cantProceed.h" +#include "dbCommon.h" #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" @@ -29,54 +28,34 @@ #include "longinRecord.h" #include "epicsExport.h" -/* Create the dset for devLiSoftCallback */ -static long init_record(); -static long read_li(); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_li; - DEVSUPFUN special_linconv; -}devLiSoftCallback={ - 6, - NULL, - NULL, - init_record, - NULL, - read_li, - NULL}; -epicsExportAddress(dset,devLiSoftCallback); - typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; - long value; - int status; -}notifyInfo; + epicsInt32 value; + int status; +} notifyInfo; -static void getCallback(processNotify *ppn,notifyGetType type) +static void getCallback(processNotify *ppn, notifyGetType type) { - struct longinRecord *prec = (struct longinRecord *)ppn->usrPvt; + longinRecord *prec = (longinRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; int status = 0; long no_elements = 1; long options = 0; - if(ppn->status==notifyCanceled) { - printf("dbtpn:getCallback notifyCanceled\n"); + if (ppn->status == notifyCanceled) { + printf("devLiSoftCallback::getCallback notifyCanceled\n"); return; } - switch(type) { + + switch (type) { case getFieldType: - status = dbGetField(ppn->paddr,DBR_LONG,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGetField(ppn->paddr, DBR_LONG, &pnotifyInfo->value, + &options, &no_elements, 0); break; case getType: - status = dbGet(ppn->paddr,DBR_LONG,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGet(ppn->paddr, DBR_LONG, &pnotifyInfo->value, + &options, &no_elements, 0); break; } pnotifyInfo->status = status; @@ -84,72 +63,144 @@ static void getCallback(processNotify *ppn,notifyGetType type) static void doneCallback(processNotify *ppn) { - struct longinRecord *prec = (struct longinRecord *)ppn->usrPvt; + longinRecord *prec = (longinRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); + callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); } - -static long init_record(struct longinRecord *prec) +static long add_record(dbCommon *pcommon) { + longinRecord *prec = (longinRecord *)pcommon; DBLINK *plink = &prec->inp; - struct instio *pinstio; - char *pvname; - DBADDR *pdbaddr=NULL; + DBADDR *pdbaddr; long status; notifyInfo *pnotifyInfo; - CALLBACK *pcallback; - processNotify *ppn=NULL; + processNotify *ppn; - if(plink->type!=INST_IO) { - recGblRecordError(S_db_badField,(void *)prec, - "devLiSoftCallback (init_record) Illegal INP field"); - prec->pact=TRUE; - return(S_db_badField); + if (plink->type == CONSTANT) return 0; + + if (plink->type != PV_LINK) { + recGblRecordError(S_db_badField, (void *)prec, + "devLiSoftCallback (add_record) Illegal INP field"); + return S_db_badField; } - pinstio=(struct instio*)&(plink->value); - pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devLiSoftCallback::init_record"); - status = dbNameToAddr(pvname,pdbaddr); - if(status) { - recGblRecordError(status,(void *)prec, + "devLiSoftCallback::add_record"); + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); + if (status) { + free(pdbaddr); + recGblRecordError(status, (void *)prec, "devLiSoftCallback (init_record) linked record not found"); - prec->pact=TRUE; - return(status); + return status; } - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), - "devLiSoftCallback::init_record"); - pcallback = callocMustSucceed(1, sizeof(*pcallback), - "devLiSoftCallback::init_record"); + + plink->type = PN_LINK; + plink->value.pv_link.precord = pcommon; + plink->value.pv_link.pvt = pdbaddr; + plink->value.pv_link.pvlMask = 0; + ppn = callocMustSucceed(1, sizeof(*ppn), - "devLiSoftCallback::init_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->pcallback = pcallback; + "devLiSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; + + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devLiSoftCallback::add_record"); + pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + "devLiSoftCallback::add_record"); + pnotifyInfo->ppn = ppn; + prec->dpvt = pnotifyInfo; return 0; } +static long del_record(dbCommon *pcommon) { + longinRecord *prec = (longinRecord *)pcommon; + DBLINK *plink = &prec->inp; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + + if (plink->type == CONSTANT) return 0; + assert (plink->type == PN_LINK); + + dbNotifyCancel(pnotifyInfo->ppn); + free(pnotifyInfo->ppn); + free(pnotifyInfo->pcallback); + free(pnotifyInfo); + free(plink->value.pv_link.pvt); + + plink->type = PV_LINK; + plink->value.pv_link.pvt = NULL; + return 0; +} + +static struct dsxt dsxtSoftCallback = { + add_record, del_record +}; + +static long init(int pass) +{ + if (pass == 0) devExtend(&dsxtSoftCallback); + return 0; +} + +static long init_record(longinRecord *prec) +{ + /* INP must be CONSTANT or PN_LINK */ + switch (prec->inp.type) { + case CONSTANT: + if (recGblInitConstantLink(&prec->inp, DBR_LONG, &prec->val)) + prec->udf = FALSE; + break; + case PN_LINK: + /* Handled by add_record */ + break; + default: + recGblRecordError(S_db_badField, (void *)prec, + "devLiSoftCallback (init_record) Illegal INP field"); + prec->pact = TRUE; + return S_db_badField; + } + return 0; +} + static long read_li(longinRecord *prec) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - if(prec->pact) { - if(pnotifyInfo->status) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(pnotifyInfo->status); - } - prec->val = pnotifyInfo->value; - prec->udf = FALSE; - return(0); + if (!prec->dpvt) + return 0; + + if (!prec->pact) { + dbProcessNotify(pnotifyInfo->ppn); + prec->pact = TRUE; + return 0; } - dbProcessNotify(pnotifyInfo->ppn); - prec->pact = TRUE; - return(0); + + if (pnotifyInfo->status) { + recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); + return pnotifyInfo->status; + } + + prec->val = pnotifyInfo->value; + prec->udf = FALSE; + + if (prec->tsel.type == CONSTANT && + prec->tse == epicsTimeEventDeviceTime) + prec->time = prec->inp.value.pv_link.precord->time; + return 0; } + +/* Create the dset for devLiSoftCallback */ +struct { + dset common; + DEVSUPFUN read_li; +} devLiSoftCallback = { + {5, NULL, init, init_record, NULL}, + read_li +}; +epicsExportAddress(dset, devLiSoftCallback); diff --git a/src/std/dev/devMbbiDirectSoftCallback.c b/src/std/dev/devMbbiDirectSoftCallback.c index e56ef6e16..96c8b7cea 100644 --- a/src/std/dev/devMbbiDirectSoftCallback.c +++ b/src/std/dev/devMbbiDirectSoftCallback.c @@ -1,5 +1,5 @@ /*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne +* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. @@ -8,17 +8,16 @@ \*************************************************************************/ /* devMbbiDirectSoftCallback.c */ /* - * Author: Marty Kraimer - * Date: 23APR2008 + * Authors: Marty Kraimer & Andrew Johnson */ #include #include -#include #include "alarm.h" #include "callback.h" #include "cantProceed.h" +#include "dbCommon.h" #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" @@ -29,54 +28,34 @@ #include "mbbiDirectRecord.h" #include "epicsExport.h" -/* Create the dset for devMbbiDirectSoftCallback */ -static long init_record(); -static long read_mbbiDirect(); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_mbbiDirect; - DEVSUPFUN special_linconv; -} devMbbiDirectSoftCallback = { - 6, - NULL, - NULL, - init_record, - NULL, - read_mbbiDirect, - NULL}; -epicsExportAddress(dset, devMbbiDirectSoftCallback); - typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; - unsigned short value; - int status; + epicsUInt16 value; + int status; } notifyInfo; static void getCallback(processNotify *ppn, notifyGetType type) { - struct mbbiDirectRecord *prec = (struct mbbiDirectRecord *)ppn->usrPvt; + mbbiDirectRecord *prec = (mbbiDirectRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; int status = 0; long no_elements = 1; long options = 0; - if (ppn->status==notifyCanceled) { - printf("dbtpn:getCallback notifyCanceled\n"); + if (ppn->status == notifyCanceled) { + printf("devMbbiDirectSoftCallback::getCallback notifyCanceled\n"); return; } + switch (type) { case getFieldType: - status = dbGetField(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGetField(ppn->paddr, DBR_USHORT, &pnotifyInfo->value, + &options, &no_elements, 0); break; case getType: - status = dbGet(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGet(ppn->paddr, DBR_USHORT, &pnotifyInfo->value, + &options, &no_elements, 0); break; } pnotifyInfo->status = status; @@ -84,72 +63,144 @@ static void getCallback(processNotify *ppn, notifyGetType type) static void doneCallback(processNotify *ppn) { - struct mbbiDirectRecord *prec = (struct mbbiDirectRecord *)ppn->usrPvt; + mbbiDirectRecord *prec = (mbbiDirectRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); + callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); } - -static long init_record(struct mbbiDirectRecord *prec) +static long add_record(dbCommon *pcommon) { + mbbiDirectRecord *prec = (mbbiDirectRecord *)pcommon; DBLINK *plink = &prec->inp; - struct instio *pinstio; - char *pvname; - DBADDR *pdbaddr=NULL; - long status; + DBADDR *pdbaddr; + long status; notifyInfo *pnotifyInfo; - CALLBACK *pcallback; - processNotify *ppn=NULL; + processNotify *ppn; - if (plink->type!=INST_IO) { - recGblRecordError(S_db_badField,(void *)prec, - "devMbbiDirectSoftCallback (init_record) Illegal INP field"); - prec->pact=TRUE; + if (plink->type == CONSTANT) return 0; + + if (plink->type != PV_LINK) { + recGblRecordError(S_db_badField, (void *)prec, + "devMbbiDirectSoftCallback (add_record) Illegal INP field"); return S_db_badField; } - pinstio=(struct instio*)&(plink->value); - pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devMbbiDirectSoftCallback::init_record"); - status = dbNameToAddr(pvname,pdbaddr); + "devMbbiDirectSoftCallback::add_record"); + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); if (status) { + free(pdbaddr); recGblRecordError(status,(void *)prec, - "devMbbiDirectSoftCallback (init_record) linked record not found"); - prec->pact=TRUE; + "devMbbiDirectSoftCallback (add_record) linked record not found"); return status; } - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), - "devMbbiDirectSoftCallback::init_record"); - pcallback = callocMustSucceed(1, sizeof(*pcallback), - "devMbbiDirectSoftCallback::init_record"); + + plink->type = PN_LINK; + plink->value.pv_link.precord = pcommon; + plink->value.pv_link.pvt = pdbaddr; + plink->value.pv_link.pvlMask = 0; + ppn = callocMustSucceed(1, sizeof(*ppn), - "devMbbiDirectSoftCallback::init_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->pcallback = pcallback; + "devMbbiDirectSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; + + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devMbbiDirectSoftCallback::add_record"); + pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + "devMbbiDirectSoftCallback::add_record"); + pnotifyInfo->ppn = ppn; + prec->dpvt = pnotifyInfo; return 0; } +static long del_record(dbCommon *pcommon) { + mbbiDirectRecord *prec = (mbbiDirectRecord *)pcommon; + DBLINK *plink = &prec->inp; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + + if (plink->type == CONSTANT) return 0; + assert (plink->type == PN_LINK); + + dbNotifyCancel(pnotifyInfo->ppn); + free(pnotifyInfo->ppn); + free(pnotifyInfo->pcallback); + free(pnotifyInfo); + free(plink->value.pv_link.pvt); + + plink->type = PV_LINK; + plink->value.pv_link.pvt = NULL; + return 0; +} + +static struct dsxt dsxtSoftCallback = { + add_record, del_record +}; + +static long init(int pass) +{ + if (pass == 0) devExtend(&dsxtSoftCallback); + return 0; +} + +static long init_record(mbbiDirectRecord *prec) +{ + /* INP must be CONSTANT or PN_LINK */ + switch (prec->inp.type) { + case CONSTANT: + if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val)) + prec->udf = FALSE; + break; + case PN_LINK: + /* Handled by add_record */ + break; + default: + recGblRecordError(S_db_badField, (void *)prec, + "devMbbiSoftCallback (init_record) Illegal INP field"); + prec->pact = TRUE; + return S_db_badField; + } + return 0; +} + static long read_mbbiDirect(mbbiDirectRecord *prec) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - if (prec->pact) { - if (pnotifyInfo->status) { - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - return 2; - } - prec->val = pnotifyInfo->value; - prec->udf = FALSE; + if (!prec->dpvt) + return 2; + + if (!prec->pact) { + dbProcessNotify(pnotifyInfo->ppn); + prec->pact = TRUE; + return 0; + } + + if (pnotifyInfo->status) { + recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); return 2; } - dbProcessNotify(pnotifyInfo->ppn); - prec->pact = TRUE; - return 0; + + prec->val = pnotifyInfo->value; + prec->udf = FALSE; + + if (prec->tsel.type == CONSTANT && + prec->tse == epicsTimeEventDeviceTime) + prec->time = prec->inp.value.pv_link.precord->time; + return 2; } + +/* Create the dset for devMbbiDirectSoftCallback */ +struct { + dset common; + DEVSUPFUN read_mbbiDirect; +} devMbbiDirectSoftCallback = { + {5, NULL, init, init_record, NULL}, + read_mbbiDirect +}; +epicsExportAddress(dset, devMbbiDirectSoftCallback); diff --git a/src/std/dev/devMbbiSoftCallback.c b/src/std/dev/devMbbiSoftCallback.c index 71afe482a..fbac4f6f7 100644 --- a/src/std/dev/devMbbiSoftCallback.c +++ b/src/std/dev/devMbbiSoftCallback.c @@ -1,5 +1,5 @@ /*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. @@ -8,17 +8,16 @@ \*************************************************************************/ /* devMbbiSoftCallback.c */ /* - * Author: Marty Kraimer - * Date: 23APR2008 + * Authors: Marty Kraimer & Andrew Johnson */ #include #include -#include #include "alarm.h" #include "callback.h" #include "cantProceed.h" +#include "dbCommon.h" #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" @@ -29,54 +28,34 @@ #include "mbbiRecord.h" #include "epicsExport.h" -/* Create the dset for devMbbiSoftCallback */ -static long init_record(); -static long read_mbbi(); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_mbbi; - DEVSUPFUN special_linconv; -}devMbbiSoftCallback={ - 6, - NULL, - NULL, - init_record, - NULL, - read_mbbi, - NULL}; -epicsExportAddress(dset,devMbbiSoftCallback); - typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; - unsigned short value; - int status; -}notifyInfo; + epicsEnum16 value; + int status; +} notifyInfo; -static void getCallback(processNotify *ppn,notifyGetType type) +static void getCallback(processNotify *ppn, notifyGetType type) { - struct mbbiRecord *prec = (struct mbbiRecord *)ppn->usrPvt; + mbbiRecord *prec = (mbbiRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; int status = 0; long no_elements = 1; long options = 0; - if(ppn->status==notifyCanceled) { - printf("dbtpn:getCallback notifyCanceled\n"); + if (ppn->status == notifyCanceled) { + printf("devMbbiSoftCallback::getCallback notifyCanceled\n"); return; } - switch(type) { + + switch (type) { case getFieldType: - status = dbGetField(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGetField(ppn->paddr, DBR_ENUM, &pnotifyInfo->value, + &options, &no_elements,0); break; case getType: - status = dbGet(ppn->paddr,DBR_USHORT,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGet(ppn->paddr,DBR_ENUM, &pnotifyInfo->value, + &options, &no_elements, 0); break; } pnotifyInfo->status = status; @@ -84,72 +63,144 @@ static void getCallback(processNotify *ppn,notifyGetType type) static void doneCallback(processNotify *ppn) { - struct mbbiRecord *prec = (struct mbbiRecord *)ppn->usrPvt; + mbbiRecord *prec = (mbbiRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); + callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); } - -static long init_record(struct mbbiRecord *prec) +static long add_record(dbCommon *pcommon) { + mbbiRecord *prec = (mbbiRecord *)pcommon; DBLINK *plink = &prec->inp; - struct instio *pinstio; - char *pvname; - DBADDR *pdbaddr=NULL; - long status; + DBADDR *pdbaddr; + long status; notifyInfo *pnotifyInfo; - CALLBACK *pcallback; - processNotify *ppn=NULL; + processNotify *ppn; - if(plink->type!=INST_IO) { - recGblRecordError(S_db_badField,(void *)prec, - "devMbbiSoftCallback (init_record) Illegal INP field"); - prec->pact=TRUE; - return(S_db_badField); + if (plink->type == CONSTANT) return 0; + + if (plink->type != PV_LINK) { + recGblRecordError(S_db_badField, (void *)prec, + "devMbbiSoftCallback (add_record) Illegal INP field"); + return S_db_badField; } - pinstio=(struct instio*)&(plink->value); - pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devMbbiSoftCallback::init_record"); - status = dbNameToAddr(pvname,pdbaddr); - if(status) { - recGblRecordError(status,(void *)prec, - "devMbbiSoftCallback (init_record) linked record not found"); - prec->pact=TRUE; - return(status); + "devMbbiSoftCallback::add_record"); + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); + if (status) { + free(pdbaddr); + recGblRecordError(status, (void *)prec, + "devMbbiSoftCallback (add_record) linked record not found"); + return status; } - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), - "devMbbiSoftCallback::init_record"); - pcallback = callocMustSucceed(1, sizeof(*pcallback), - "devMbbiSoftCallback::init_record"); + + plink->type = PN_LINK; + plink->value.pv_link.precord = pcommon; + plink->value.pv_link.pvt = pdbaddr; + plink->value.pv_link.pvlMask = 0; + ppn = callocMustSucceed(1, sizeof(*ppn), - "devMbbiSoftCallback::init_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->pcallback = pcallback; + "devMbbiSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; + + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devMbbiSoftCallback::add_record"); + pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + "devMbbiSoftCallback::add_record"); + pnotifyInfo->ppn = ppn; + prec->dpvt = pnotifyInfo; return 0; } +static long del_record(dbCommon *pcommon) { + mbbiRecord *prec = (mbbiRecord *)pcommon; + DBLINK *plink = &prec->inp; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + + if (plink->type == CONSTANT) return 0; + assert (plink->type == PN_LINK); + + dbNotifyCancel(pnotifyInfo->ppn); + free(pnotifyInfo->ppn); + free(pnotifyInfo->pcallback); + free(pnotifyInfo); + free(plink->value.pv_link.pvt); + + plink->type = PV_LINK; + plink->value.pv_link.pvt = NULL; + return 0; +} + +static struct dsxt dsxtSoftCallback = { + add_record, del_record +}; + +static long init(int pass) +{ + if (pass == 0) devExtend(&dsxtSoftCallback); + return 0; +} + +static long init_record(mbbiRecord *prec) +{ + /* INP must be CONSTANT or PN_LINK */ + switch (prec->inp.type) { + case CONSTANT: + if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val)) + prec->udf = FALSE; + break; + case PN_LINK: + /* Handled by add_record */ + break; + default: + recGblRecordError(S_db_badField, (void *)prec, + "devMbbiSoftCallback (init_record) Illegal INP field"); + prec->pact = TRUE; + return S_db_badField; + } + return 0; +} + static long read_mbbi(mbbiRecord *prec) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - if(prec->pact) { - if(pnotifyInfo->status) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(2); - } - prec->val = pnotifyInfo->value; - prec->udf = FALSE; - return(2); + if (!prec->dpvt) + return 2; + + if (!prec->pact) { + dbProcessNotify(pnotifyInfo->ppn); + prec->pact = TRUE; + return 0; } - dbProcessNotify(pnotifyInfo->ppn); - prec->pact = TRUE; - return(0); + + if (pnotifyInfo->status) { + recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); + return 2; + } + + prec->val = pnotifyInfo->value; + prec->udf = FALSE; + + if (prec->tsel.type == CONSTANT && + prec->tse == epicsTimeEventDeviceTime) + prec->time = prec->inp.value.pv_link.precord->time; + return 2; } + +/* Create the dset for devMbbiSoftCallback */ +struct { + dset common; + DEVSUPFUN read_mbbi; +} devMbbiSoftCallback = { + {5, NULL, init, init_record, NULL}, + read_mbbi +}; +epicsExportAddress(dset,devMbbiSoftCallback); diff --git a/src/std/dev/devSiSoftCallback.c b/src/std/dev/devSiSoftCallback.c index c5ac85d48..85f7efc3f 100644 --- a/src/std/dev/devSiSoftCallback.c +++ b/src/std/dev/devSiSoftCallback.c @@ -1,5 +1,5 @@ /*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. @@ -8,8 +8,7 @@ \*************************************************************************/ /* devSiSoftCallback.c */ /* - * Author: Marty Kraimer - * Date: 23APR2008 + * Authors: Marty Kraimer & Andrew Johnson */ #include @@ -19,6 +18,7 @@ #include "alarm.h" #include "callback.h" #include "cantProceed.h" +#include "dbCommon.h" #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" @@ -29,54 +29,34 @@ #include "stringinRecord.h" #include "epicsExport.h" -/* Create the dset for devSiSoftCallback */ -static long init_record(); -static long read_stringin(); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_stringin; - DEVSUPFUN special_linconv; -}devSiSoftCallback={ - 6, - NULL, - NULL, - init_record, - NULL, - read_stringin, - NULL}; -epicsExportAddress(dset,devSiSoftCallback); - typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; - char value[40]; - int status; -}notifyInfo; + char value[MAX_STRING_SIZE]; + int status; +} notifyInfo; -static void getCallback(processNotify *ppn,notifyGetType type) +static void getCallback(processNotify *ppn, notifyGetType type) { - struct stringinRecord *prec = (struct stringinRecord *)ppn->usrPvt; + stringinRecord *prec = (stringinRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; int status = 0; long no_elements = 1; long options = 0; - if(ppn->status==notifyCanceled) { - printf("dbtpn:getCallback notifyCanceled\n"); + if (ppn->status==notifyCanceled) { + printf("devSiSoftCallback::getCallback notifyCanceled\n"); return; } + switch(type) { case getFieldType: - status = dbGetField(ppn->paddr,DBR_STRING,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGetField(ppn->paddr, DBR_STRING, &pnotifyInfo->value, + &options, &no_elements, 0); break; case getType: - status = dbGet(ppn->paddr,DBR_STRING,&pnotifyInfo->value, - &options,&no_elements,0); + status = dbGet(ppn->paddr, DBR_STRING, &pnotifyInfo->value, + &options, &no_elements, 0); break; } pnotifyInfo->status = status; @@ -84,72 +64,144 @@ static void getCallback(processNotify *ppn,notifyGetType type) static void doneCallback(processNotify *ppn) { - struct stringinRecord *prec = (struct stringinRecord *)ppn->usrPvt; + stringinRecord *prec = (stringinRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); + callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); } -static long init_record(struct stringinRecord *prec) +static long add_record(dbCommon *pcommon) { + stringinRecord *prec = (stringinRecord *)pcommon; DBLINK *plink = &prec->inp; - struct instio *pinstio; - char *pvname; - DBADDR *pdbaddr=NULL; + DBADDR *pdbaddr; long status; notifyInfo *pnotifyInfo; - CALLBACK *pcallback; - processNotify *ppn=NULL; + processNotify *ppn; - if(plink->type!=INST_IO) { - recGblRecordError(S_db_badField,(void *)prec, - "devSiSoftCallback (init_record) Illegal INP field"); - prec->pact=TRUE; - return(S_db_badField); + if (plink->type == CONSTANT) return 0; + + if (plink->type != PV_LINK) { + recGblRecordError(S_db_badField, (void *)prec, + "devSiSoftCallback (add_record) Illegal INP field"); + return S_db_badField; } - pinstio=(struct instio*)&(plink->value); - pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devSiSoftCallback::init_record"); - status = dbNameToAddr(pvname,pdbaddr); - if(status) { - recGblRecordError(status,(void *)prec, - "devSiSoftCallback (init_record) linked record not found"); - prec->pact=TRUE; - return(status); + "devSiSoftCallback::add_record"); + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); + if (status) { + free(pdbaddr); + recGblRecordError(status, (void *)prec, + "devSiSoftCallback (add_record) linked record not found"); + return status; } - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), - "devSiSoftCallback::init_record"); - pcallback = callocMustSucceed(1, sizeof(*pcallback), - "devSiSoftCallback::init_record"); + + plink->type = PN_LINK; + plink->value.pv_link.precord = pcommon; + plink->value.pv_link.pvt = pdbaddr; + plink->value.pv_link.pvlMask = 0; + ppn = callocMustSucceed(1, sizeof(*ppn), - "devSiSoftCallback::init_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->pcallback = pcallback; + "devSiSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; + + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devSiSoftCallback::add_record"); + pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + "devSiSoftCallback::add_record"); + pnotifyInfo->ppn = ppn; + prec->dpvt = pnotifyInfo; return 0; } -static long read_stringin(stringinRecord *prec) +static long del_record(dbCommon *pcommon) { + stringinRecord *prec = (stringinRecord *)pcommon; + DBLINK *plink = &prec->inp; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + + if (plink->type == CONSTANT) return 0; + assert (plink->type == PN_LINK); + + dbNotifyCancel(pnotifyInfo->ppn); + free(pnotifyInfo->ppn); + free(pnotifyInfo->pcallback); + free(pnotifyInfo); + free(plink->value.pv_link.pvt); + + plink->type = PV_LINK; + plink->value.pv_link.pvt = NULL; + return 0; +} + +static struct dsxt dsxtSoftCallback = { + add_record, del_record +}; + +static long init(int pass) +{ + if (pass == 0) devExtend(&dsxtSoftCallback); + return 0; +} + +static long init_record(stringinRecord *prec) +{ + /* INP must be CONSTANT or PN_LINK */ + switch (prec->inp.type) { + case CONSTANT: + if (recGblInitConstantLink(&prec->inp, DBR_STRING, &prec->val)) + prec->udf = FALSE; + break; + case PN_LINK: + /* Handled by add_record */ + break; + default: + recGblRecordError(S_db_badField, (void *)prec, + "devSiSoftCallback (init_record) Illegal INP field"); + prec->pact = TRUE; + return S_db_badField; + } + return 0; +} + +static long read_si(stringinRecord *prec) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - if(prec->pact) { - if(pnotifyInfo->status) { - recGblSetSevr(prec,READ_ALARM,INVALID_ALARM); - return(pnotifyInfo->status); - } - strcpy(prec->val,pnotifyInfo->value); - prec->udf = FALSE; - return(0); + if (!prec->dpvt) + return 0; + + if (!prec->pact) { + dbProcessNotify(pnotifyInfo->ppn); + prec->pact = TRUE; + return 0; } - dbProcessNotify(pnotifyInfo->ppn); - prec->pact = TRUE; - return(0); + + if (pnotifyInfo->status) { + recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); + return pnotifyInfo->status; + } + strncpy(prec->val, pnotifyInfo->value, MAX_STRING_SIZE); + prec->udf = FALSE; + + if (prec->tsel.type == CONSTANT && + prec->tse == epicsTimeEventDeviceTime) + prec->time = prec->inp.value.pv_link.precord->time; + return 0; } + +/* Create the dset for devSiSoftCallback */ +struct { + dset common; + DEVSUPFUN read_li; +} devSiSoftCallback = { + {5, NULL, init, init_record, NULL}, + read_si +}; +epicsExportAddress(dset,devSiSoftCallback); diff --git a/src/std/dev/devSoft.dbd b/src/std/dev/devSoft.dbd index f6a93241d..3df80c52d 100644 --- a/src/std/dev/devSoft.dbd +++ b/src/std/dev/devSoft.dbd @@ -27,19 +27,18 @@ device(mbbiDirect,CONSTANT,devMbbiDirectSoftRaw,"Raw Soft Channel") device(mbbo,CONSTANT,devMbboSoftRaw,"Raw Soft Channel") device(mbboDirect,CONSTANT,devMbboDirectSoftRaw,"Raw Soft Channel") -device(ai,INST_IO,devAiSoftCallback,"Async Soft Channel") -device(bi,INST_IO,devBiSoftCallback,"Async Soft Channel") -device(mbbi,INST_IO,devMbbiSoftCallback,"Async Soft Channel") -device(mbbiDirect,INST_IO,devMbbiDirectSoftCallback,"Async Soft Channel") -device(longin,INST_IO,devLiSoftCallback,"Async Soft Channel") -device(stringin,INST_IO,devSiSoftCallback,"Async Soft Channel") - +device(ai,CONSTANT,devAiSoftCallback,"Async Soft Channel") device(ao,CONSTANT,devAoSoftCallback,"Async Soft Channel") +device(bi,CONSTANT,devBiSoftCallback,"Async Soft Channel") device(bo,CONSTANT,devBoSoftCallback,"Async Soft Channel") device(calcout,CONSTANT,devCalcoutSoftCallback,"Async Soft Channel") +device(longin,CONSTANT,devLiSoftCallback,"Async Soft Channel") device(longout,CONSTANT,devLoSoftCallback,"Async Soft Channel") +device(mbbi,CONSTANT,devMbbiSoftCallback,"Async Soft Channel") +device(mbbiDirect,CONSTANT,devMbbiDirectSoftCallback,"Async Soft Channel") device(mbbo,CONSTANT,devMbboSoftCallback,"Async Soft Channel") device(mbboDirect,CONSTANT,devMbboDirectSoftCallback,"Async Soft Channel") +device(stringin,CONSTANT,devSiSoftCallback,"Async Soft Channel") device(stringout,CONSTANT,devSoSoftCallback,"Async Soft Channel") device(ai, INST_IO,devTimestampAI,"Soft Timestamp") From 75bdfc185e81ec9069de98d6eef965ceef3d91fe Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 8 Jan 2010 17:15:03 -0600 Subject: [PATCH 6/9] Honor MS/MSS/MSI flags and fetches timestamps properly too. --- src/ioc/dbStatic/dbStaticLib.c | 12 ++--- src/std/dev/devAiSoftCallback.c | 60 +++++++++++++++---------- src/std/dev/devBiSoftCallback.c | 53 ++++++++++++++-------- src/std/dev/devLiSoftCallback.c | 53 ++++++++++++++-------- src/std/dev/devMbbiDirectSoftCallback.c | 53 ++++++++++++++-------- src/std/dev/devMbbiSoftCallback.c | 53 ++++++++++++++-------- src/std/dev/devSiSoftCallback.c | 54 ++++++++++++++-------- 7 files changed, 220 insertions(+), 118 deletions(-) diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c index e5b3bdd89..0ca4988a2 100644 --- a/src/ioc/dbStatic/dbStaticLib.c +++ b/src/ioc/dbStatic/dbStaticLib.c @@ -2018,11 +2018,13 @@ char * epicsShareAPI dbGetString(DBENTRY *pdbentry) } break; case PN_LINK: - if(plink->value.pv_link.pvname) - strcpy(message,plink->value.pv_link.pvname); - else - strcpy(message,""); - break; + if(plink->value.pv_link.pvname) + strcpy(message,plink->value.pv_link.pvname); + else + strcpy(message,""); + strcat(message," "); + strcat(message,msstring[plink->value.pv_link.pvlMask&pvlOptMsMode]); + break; case PV_LINK: case CA_LINK: case DB_LINK: { diff --git a/src/std/dev/devAiSoftCallback.c b/src/std/dev/devAiSoftCallback.c index 24b933d88..8dfae71ea 100644 --- a/src/std/dev/devAiSoftCallback.c +++ b/src/std/dev/devAiSoftCallback.c @@ -11,10 +11,6 @@ * Authors: Marty Kraimer & Andrew Johnson */ -/* TODO: - * Support MS/MSS/MSI link flags - */ - #include #include @@ -25,6 +21,7 @@ #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" +#include "epicsAssert.h" #include "recGbl.h" #include "recSup.h" #include "devSup.h" @@ -32,38 +29,37 @@ #include "aiRecord.h" #include "epicsExport.h" + +#define GET_OPTIONS (DBR_STATUS | DBR_TIME) + typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; - double value; + long options; int status; int smooth; + struct { + DBRstatus + DBRtime + epicsFloat64 value; + } buffer; } notifyInfo; + static void getCallback(processNotify *ppn, notifyGetType type) { aiRecord *prec = (aiRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - int status = 0; long no_elements = 1; - long options = 0; if (ppn->status == notifyCanceled) { printf("devAiSoftCallback::getCallback notifyCanceled\n"); return; } - switch (type) { - case getFieldType: - status = dbGetField(ppn->paddr, DBR_DOUBLE, &pnotifyInfo->value, - &options, &no_elements, 0); - break; - case getType: - status = dbGet(ppn->paddr, DBR_DOUBLE, &pnotifyInfo->value, - &options, &no_elements, 0); - break; - } - pnotifyInfo->status = status; + assert(type == getFieldType); + pnotifyInfo->status = dbGetField(ppn->paddr, DBR_DOUBLE, + &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) @@ -104,7 +100,7 @@ static long add_record(dbCommon *pcommon) plink->type = PN_LINK; plink->value.pv_link.precord = pcommon; plink->value.pv_link.pvt = pdbaddr; - plink->value.pv_link.pvlMask = 0; + plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ ppn = callocMustSucceed(1, sizeof(*ppn), "devAiSoftCallback::add_record"); @@ -119,6 +115,7 @@ static long add_record(dbCommon *pcommon) pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devAiSoftCallback::add_record"); pnotifyInfo->ppn = ppn; + pnotifyInfo->options = GET_OPTIONS; prec->dpvt = pnotifyInfo; return 0; @@ -130,7 +127,7 @@ static long del_record(dbCommon *pcommon) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; if (plink->type == CONSTANT) return 0; - assert (plink->type == PN_LINK); + assert(plink->type == PN_LINK); dbNotifyCancel(pnotifyInfo->ppn); free(pnotifyInfo->ppn); @@ -194,15 +191,32 @@ static long read_ai(aiRecord *prec) /* Apply smoothing algorithm */ if (prec->smoo != 0.0 && pnotifyInfo->smooth) - prec->val = pnotifyInfo->value * (1.0 - prec->smoo) + prec->val * prec->smoo; + prec->val = prec->val * prec->smoo + + pnotifyInfo->buffer.value * (1.0 - prec->smoo); else - prec->val = pnotifyInfo->value; + prec->val = pnotifyInfo->buffer.value; prec->udf = FALSE; pnotifyInfo->smooth = TRUE; + switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { + case pvlOptNMS: + break; + case pvlOptMSI: + if (pnotifyInfo->buffer.severity < INVALID_ALARM) + break; + /* else fall through */ + case pvlOptMS: + recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + break; + case pvlOptMSS: + recGblSetSevr(prec, pnotifyInfo->buffer.status, + pnotifyInfo->buffer.severity); + break; + } + if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = prec->inp.value.pv_link.precord->time; + prec->time = pnotifyInfo->buffer.time; return 2; } diff --git a/src/std/dev/devBiSoftCallback.c b/src/std/dev/devBiSoftCallback.c index a19609ee6..7c6dc6bbc 100644 --- a/src/std/dev/devBiSoftCallback.c +++ b/src/std/dev/devBiSoftCallback.c @@ -21,6 +21,7 @@ #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" +#include "epicsAssert.h" #include "recGbl.h" #include "recSup.h" #include "devSup.h" @@ -28,37 +29,36 @@ #include "biRecord.h" #include "epicsExport.h" + +#define GET_OPTIONS (DBR_STATUS | DBR_TIME) + typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; - epicsEnum16 value; + long options; int status; + struct { + DBRstatus + DBRtime + epicsEnum16 value; + } buffer; } notifyInfo; + static void getCallback(processNotify *ppn,notifyGetType type) { biRecord *prec = (biRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - int status = 0; long no_elements = 1; - long options = 0; if (ppn->status == notifyCanceled) { printf("devBiSoftCallback::getCallback notifyCanceled\n"); return; } - switch (type) { - case getFieldType: - status = dbGetField(ppn->paddr, DBR_ENUM, &pnotifyInfo->value, - &options, &no_elements, 0); - break; - case getType: - status = dbGet(ppn->paddr, DBR_ENUM, &pnotifyInfo->value, - &options, &no_elements, 0); - break; - } - pnotifyInfo->status = status; + assert(type == getFieldType); + pnotifyInfo->status = dbGetField(ppn->paddr, DBR_ENUM, + &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) @@ -99,7 +99,7 @@ static long add_record(dbCommon *pcommon) plink->type = PN_LINK; plink->value.pv_link.precord = pcommon; plink->value.pv_link.pvt = pdbaddr; - plink->value.pv_link.pvlMask = 0; + plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ ppn = callocMustSucceed(1, sizeof(*ppn), "devBiSoftCallback::add_record"); @@ -114,6 +114,7 @@ static long add_record(dbCommon *pcommon) pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devBiSoftCallback::add_record"); pnotifyInfo->ppn = ppn; + pnotifyInfo->options = GET_OPTIONS; prec->dpvt = pnotifyInfo; return 0; @@ -125,7 +126,7 @@ static long del_record(dbCommon *pcommon) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; if (plink->type == CONSTANT) return 0; - assert (plink->type == PN_LINK); + assert(plink->type == PN_LINK); dbNotifyCancel(pnotifyInfo->ppn); free(pnotifyInfo->ppn); @@ -186,12 +187,28 @@ static long read_bi(biRecord *prec) return 2; } - prec->val = pnotifyInfo->value; + prec->val = pnotifyInfo->buffer.value; prec->udf = FALSE; + switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { + case pvlOptNMS: + break; + case pvlOptMSI: + if (pnotifyInfo->buffer.severity < INVALID_ALARM) + break; + /* else fall through */ + case pvlOptMS: + recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + break; + case pvlOptMSS: + recGblSetSevr(prec, pnotifyInfo->buffer.status, + pnotifyInfo->buffer.severity); + break; + } + if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = prec->inp.value.pv_link.precord->time; + prec->time = pnotifyInfo->buffer.time; return 2; } diff --git a/src/std/dev/devLiSoftCallback.c b/src/std/dev/devLiSoftCallback.c index fe710d579..4b9a2a00e 100644 --- a/src/std/dev/devLiSoftCallback.c +++ b/src/std/dev/devLiSoftCallback.c @@ -21,6 +21,7 @@ #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" +#include "epicsAssert.h" #include "recGbl.h" #include "recSup.h" #include "devSup.h" @@ -28,37 +29,36 @@ #include "longinRecord.h" #include "epicsExport.h" + +#define GET_OPTIONS (DBR_STATUS | DBR_TIME) + typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; - epicsInt32 value; + long options; int status; + struct { + DBRstatus + DBRtime + epicsInt32 value; + } buffer; } notifyInfo; + static void getCallback(processNotify *ppn, notifyGetType type) { longinRecord *prec = (longinRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - int status = 0; long no_elements = 1; - long options = 0; if (ppn->status == notifyCanceled) { printf("devLiSoftCallback::getCallback notifyCanceled\n"); return; } - switch (type) { - case getFieldType: - status = dbGetField(ppn->paddr, DBR_LONG, &pnotifyInfo->value, - &options, &no_elements, 0); - break; - case getType: - status = dbGet(ppn->paddr, DBR_LONG, &pnotifyInfo->value, - &options, &no_elements, 0); - break; - } - pnotifyInfo->status = status; + assert(type == getFieldType); + pnotifyInfo->status = dbGetField(ppn->paddr, DBR_LONG, + &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) @@ -99,7 +99,7 @@ static long add_record(dbCommon *pcommon) plink->type = PN_LINK; plink->value.pv_link.precord = pcommon; plink->value.pv_link.pvt = pdbaddr; - plink->value.pv_link.pvlMask = 0; + plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ ppn = callocMustSucceed(1, sizeof(*ppn), "devLiSoftCallback::add_record"); @@ -114,6 +114,7 @@ static long add_record(dbCommon *pcommon) pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devLiSoftCallback::add_record"); pnotifyInfo->ppn = ppn; + pnotifyInfo->options = GET_OPTIONS; prec->dpvt = pnotifyInfo; return 0; @@ -125,7 +126,7 @@ static long del_record(dbCommon *pcommon) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; if (plink->type == CONSTANT) return 0; - assert (plink->type == PN_LINK); + assert(plink->type == PN_LINK); dbNotifyCancel(pnotifyInfo->ppn); free(pnotifyInfo->ppn); @@ -186,12 +187,28 @@ static long read_li(longinRecord *prec) return pnotifyInfo->status; } - prec->val = pnotifyInfo->value; + prec->val = pnotifyInfo->buffer.value; prec->udf = FALSE; + switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { + case pvlOptNMS: + break; + case pvlOptMSI: + if (pnotifyInfo->buffer.severity < INVALID_ALARM) + break; + /* else fall through */ + case pvlOptMS: + recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + break; + case pvlOptMSS: + recGblSetSevr(prec, pnotifyInfo->buffer.status, + pnotifyInfo->buffer.severity); + break; + } + if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = prec->inp.value.pv_link.precord->time; + prec->time = pnotifyInfo->buffer.time; return 0; } diff --git a/src/std/dev/devMbbiDirectSoftCallback.c b/src/std/dev/devMbbiDirectSoftCallback.c index 96c8b7cea..b2bcd7bcd 100644 --- a/src/std/dev/devMbbiDirectSoftCallback.c +++ b/src/std/dev/devMbbiDirectSoftCallback.c @@ -21,6 +21,7 @@ #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" +#include "epicsAssert.h" #include "recGbl.h" #include "recSup.h" #include "devSup.h" @@ -28,37 +29,36 @@ #include "mbbiDirectRecord.h" #include "epicsExport.h" + +#define GET_OPTIONS (DBR_STATUS | DBR_TIME) + typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; - epicsUInt16 value; + long options; int status; + struct { + DBRstatus + DBRtime + epicsUInt16 value; + } buffer; } notifyInfo; + static void getCallback(processNotify *ppn, notifyGetType type) { mbbiDirectRecord *prec = (mbbiDirectRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - int status = 0; long no_elements = 1; - long options = 0; if (ppn->status == notifyCanceled) { printf("devMbbiDirectSoftCallback::getCallback notifyCanceled\n"); return; } - switch (type) { - case getFieldType: - status = dbGetField(ppn->paddr, DBR_USHORT, &pnotifyInfo->value, - &options, &no_elements, 0); - break; - case getType: - status = dbGet(ppn->paddr, DBR_USHORT, &pnotifyInfo->value, - &options, &no_elements, 0); - break; - } - pnotifyInfo->status = status; + assert(type == getFieldType); + pnotifyInfo->status = dbGetField(ppn->paddr, DBR_USHORT, + &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) @@ -99,7 +99,7 @@ static long add_record(dbCommon *pcommon) plink->type = PN_LINK; plink->value.pv_link.precord = pcommon; plink->value.pv_link.pvt = pdbaddr; - plink->value.pv_link.pvlMask = 0; + plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ ppn = callocMustSucceed(1, sizeof(*ppn), "devMbbiDirectSoftCallback::add_record"); @@ -114,6 +114,7 @@ static long add_record(dbCommon *pcommon) pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devMbbiDirectSoftCallback::add_record"); pnotifyInfo->ppn = ppn; + pnotifyInfo->options = GET_OPTIONS; prec->dpvt = pnotifyInfo; return 0; @@ -125,7 +126,7 @@ static long del_record(dbCommon *pcommon) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; if (plink->type == CONSTANT) return 0; - assert (plink->type == PN_LINK); + assert(plink->type == PN_LINK); dbNotifyCancel(pnotifyInfo->ppn); free(pnotifyInfo->ppn); @@ -186,12 +187,28 @@ static long read_mbbiDirect(mbbiDirectRecord *prec) return 2; } - prec->val = pnotifyInfo->value; + prec->val = pnotifyInfo->buffer.value; prec->udf = FALSE; + switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { + case pvlOptNMS: + break; + case pvlOptMSI: + if (pnotifyInfo->buffer.severity < INVALID_ALARM) + break; + /* else fall through */ + case pvlOptMS: + recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + break; + case pvlOptMSS: + recGblSetSevr(prec, pnotifyInfo->buffer.status, + pnotifyInfo->buffer.severity); + break; + } + if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = prec->inp.value.pv_link.precord->time; + prec->time = pnotifyInfo->buffer.time; return 2; } diff --git a/src/std/dev/devMbbiSoftCallback.c b/src/std/dev/devMbbiSoftCallback.c index fbac4f6f7..f583d8cff 100644 --- a/src/std/dev/devMbbiSoftCallback.c +++ b/src/std/dev/devMbbiSoftCallback.c @@ -21,6 +21,7 @@ #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" +#include "epicsAssert.h" #include "recGbl.h" #include "recSup.h" #include "devSup.h" @@ -28,37 +29,36 @@ #include "mbbiRecord.h" #include "epicsExport.h" + +#define GET_OPTIONS (DBR_STATUS | DBR_TIME) + typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; - epicsEnum16 value; + long options; int status; + struct { + DBRstatus + DBRtime + epicsEnum16 value; + } buffer; } notifyInfo; + static void getCallback(processNotify *ppn, notifyGetType type) { mbbiRecord *prec = (mbbiRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - int status = 0; long no_elements = 1; - long options = 0; if (ppn->status == notifyCanceled) { printf("devMbbiSoftCallback::getCallback notifyCanceled\n"); return; } - switch (type) { - case getFieldType: - status = dbGetField(ppn->paddr, DBR_ENUM, &pnotifyInfo->value, - &options, &no_elements,0); - break; - case getType: - status = dbGet(ppn->paddr,DBR_ENUM, &pnotifyInfo->value, - &options, &no_elements, 0); - break; - } - pnotifyInfo->status = status; + assert(type == getFieldType); + pnotifyInfo->status = dbGetField(ppn->paddr, DBR_ENUM, + &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) @@ -99,7 +99,7 @@ static long add_record(dbCommon *pcommon) plink->type = PN_LINK; plink->value.pv_link.precord = pcommon; plink->value.pv_link.pvt = pdbaddr; - plink->value.pv_link.pvlMask = 0; + plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ ppn = callocMustSucceed(1, sizeof(*ppn), "devMbbiSoftCallback::add_record"); @@ -114,6 +114,7 @@ static long add_record(dbCommon *pcommon) pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devMbbiSoftCallback::add_record"); pnotifyInfo->ppn = ppn; + pnotifyInfo->options = GET_OPTIONS; prec->dpvt = pnotifyInfo; return 0; @@ -125,7 +126,7 @@ static long del_record(dbCommon *pcommon) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; if (plink->type == CONSTANT) return 0; - assert (plink->type == PN_LINK); + assert(plink->type == PN_LINK); dbNotifyCancel(pnotifyInfo->ppn); free(pnotifyInfo->ppn); @@ -186,12 +187,28 @@ static long read_mbbi(mbbiRecord *prec) return 2; } - prec->val = pnotifyInfo->value; + prec->val = pnotifyInfo->buffer.value; prec->udf = FALSE; + switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { + case pvlOptNMS: + break; + case pvlOptMSI: + if (pnotifyInfo->buffer.severity < INVALID_ALARM) + break; + /* else fall through */ + case pvlOptMS: + recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + break; + case pvlOptMSS: + recGblSetSevr(prec, pnotifyInfo->buffer.status, + pnotifyInfo->buffer.severity); + break; + } + if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = prec->inp.value.pv_link.precord->time; + prec->time = pnotifyInfo->buffer.time; return 2; } diff --git a/src/std/dev/devSiSoftCallback.c b/src/std/dev/devSiSoftCallback.c index 85f7efc3f..2aa732221 100644 --- a/src/std/dev/devSiSoftCallback.c +++ b/src/std/dev/devSiSoftCallback.c @@ -22,6 +22,7 @@ #include "dbDefs.h" #include "dbAccess.h" #include "dbNotify.h" +#include "epicsAssert.h" #include "recGbl.h" #include "recSup.h" #include "devSup.h" @@ -29,37 +30,36 @@ #include "stringinRecord.h" #include "epicsExport.h" + +#define GET_OPTIONS (DBR_STATUS | DBR_TIME) + typedef struct notifyInfo { processNotify *ppn; CALLBACK *pcallback; - char value[MAX_STRING_SIZE]; + long options; int status; + struct { + DBRstatus + DBRtime + char value[MAX_STRING_SIZE]; + } buffer; } notifyInfo; + static void getCallback(processNotify *ppn, notifyGetType type) { stringinRecord *prec = (stringinRecord *)ppn->usrPvt; notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; - int status = 0; long no_elements = 1; - long options = 0; if (ppn->status==notifyCanceled) { printf("devSiSoftCallback::getCallback notifyCanceled\n"); return; } - switch(type) { - case getFieldType: - status = dbGetField(ppn->paddr, DBR_STRING, &pnotifyInfo->value, - &options, &no_elements, 0); - break; - case getType: - status = dbGet(ppn->paddr, DBR_STRING, &pnotifyInfo->value, - &options, &no_elements, 0); - break; - } - pnotifyInfo->status = status; + assert(type == getFieldType); + pnotifyInfo->status = dbGetField(ppn->paddr, DBR_STRING, + &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) @@ -101,7 +101,7 @@ static long add_record(dbCommon *pcommon) plink->type = PN_LINK; plink->value.pv_link.precord = pcommon; plink->value.pv_link.pvt = pdbaddr; - plink->value.pv_link.pvlMask = 0; + plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ ppn = callocMustSucceed(1, sizeof(*ppn), "devSiSoftCallback::add_record"); @@ -116,6 +116,7 @@ static long add_record(dbCommon *pcommon) pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devSiSoftCallback::add_record"); pnotifyInfo->ppn = ppn; + pnotifyInfo->options = GET_OPTIONS; prec->dpvt = pnotifyInfo; return 0; @@ -127,7 +128,7 @@ static long del_record(dbCommon *pcommon) { notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; if (plink->type == CONSTANT) return 0; - assert (plink->type == PN_LINK); + assert(plink->type == PN_LINK); dbNotifyCancel(pnotifyInfo->ppn); free(pnotifyInfo->ppn); @@ -187,12 +188,29 @@ static long read_si(stringinRecord *prec) recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); return pnotifyInfo->status; } - strncpy(prec->val, pnotifyInfo->value, MAX_STRING_SIZE); + strncpy(prec->val, pnotifyInfo->buffer.value, MAX_STRING_SIZE); + prec->val[MAX_STRING_SIZE-1] = 0; prec->udf = FALSE; + switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { + case pvlOptNMS: + break; + case pvlOptMSI: + if (pnotifyInfo->buffer.severity < INVALID_ALARM) + break; + /* else fall through */ + case pvlOptMS: + recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + break; + case pvlOptMSS: + recGblSetSevr(prec, pnotifyInfo->buffer.status, + pnotifyInfo->buffer.severity); + break; + } + if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = prec->inp.value.pv_link.precord->time; + prec->time = pnotifyInfo->buffer.time; return 0; } From 90ab2845830468b29499fd9d13f06b8a56ed578b Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 20 Aug 2010 00:40:26 -0500 Subject: [PATCH 7/9] db: Replace forward reference to notifyCallback, got lost in rebase. --- src/ioc/db/dbNotify.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ioc/db/dbNotify.c b/src/ioc/db/dbNotify.c index c6403d502..5fcbb5cdc 100644 --- a/src/ioc/db/dbNotify.c +++ b/src/ioc/db/dbNotify.c @@ -92,6 +92,7 @@ static void notifyCleanup(processNotify *ppn); static void restartCheck(processNotifyRecord *ppnr); static void callDone(dbCommon *precord,processNotify *ppn); static void processNotifyCommon(processNotify *ppn,dbCommon *precord); +static void notifyCallback(CALLBACK *pcallback); #define ellSafeAdd(list,listnode) \ { \ From 26f6eabdf553d51c9d52acedc6644ec153de21db Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 30 Nov 2010 17:32:09 -0600 Subject: [PATCH 8/9] dev: Rename notifyInfo structure to devPvt. --- src/std/dev/devAiSoftCallback.c | 62 ++++++++++++------------- src/std/dev/devBiSoftCallback.c | 54 ++++++++++----------- src/std/dev/devLiSoftCallback.c | 56 +++++++++++----------- src/std/dev/devMbbiDirectSoftCallback.c | 54 ++++++++++----------- src/std/dev/devMbbiSoftCallback.c | 54 ++++++++++----------- src/std/dev/devSiSoftCallback.c | 56 +++++++++++----------- 6 files changed, 168 insertions(+), 168 deletions(-) diff --git a/src/std/dev/devAiSoftCallback.c b/src/std/dev/devAiSoftCallback.c index 8dfae71ea..ee73b0b44 100644 --- a/src/std/dev/devAiSoftCallback.c +++ b/src/std/dev/devAiSoftCallback.c @@ -32,7 +32,7 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) -typedef struct notifyInfo { +typedef struct devPvt { processNotify *ppn; CALLBACK *pcallback; long options; @@ -43,13 +43,13 @@ typedef struct notifyInfo { DBRtime epicsFloat64 value; } buffer; -} notifyInfo; +} devPvt; static void getCallback(processNotify *ppn, notifyGetType type) { aiRecord *prec = (aiRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; long no_elements = 1; if (ppn->status == notifyCanceled) { @@ -58,16 +58,16 @@ static void getCallback(processNotify *ppn, notifyGetType type) } assert(type == getFieldType); - pnotifyInfo->status = dbGetField(ppn->paddr, DBR_DOUBLE, - &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); + pdevPvt->status = dbGetField(ppn->paddr, DBR_DOUBLE, + &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) { aiRecord *prec = (aiRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); + callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); } static long add_record(dbCommon *pcommon) @@ -76,7 +76,7 @@ static long add_record(dbCommon *pcommon) DBLINK *plink = &prec->inp; DBADDR *pdbaddr; long status; - notifyInfo *pnotifyInfo; + devPvt *pdevPvt; processNotify *ppn; if (plink->type == CONSTANT) return 0; @@ -110,29 +110,29 @@ static long add_record(dbCommon *pcommon) ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), "devAiSoftCallback::add_record"); - pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devAiSoftCallback::add_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->options = GET_OPTIONS; + pdevPvt->ppn = ppn; + pdevPvt->options = GET_OPTIONS; - prec->dpvt = pnotifyInfo; + prec->dpvt = pdevPvt; return 0; } static long del_record(dbCommon *pcommon) { aiRecord *prec = (aiRecord *)pcommon; DBLINK *plink = &prec->inp; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pnotifyInfo->ppn); - free(pnotifyInfo->ppn); - free(pnotifyInfo->pcallback); - free(pnotifyInfo); + dbNotifyCancel(pdevPvt->ppn); + free(pdevPvt->ppn); + free(pdevPvt->pcallback); + free(pdevPvt); free(plink->value.pv_link.pvt); plink->type = PV_LINK; @@ -172,51 +172,51 @@ static long init_record(aiRecord *prec) static long read_ai(aiRecord *prec) { - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (!prec->dpvt) return 2; if (!prec->pact) { - dbProcessNotify(pnotifyInfo->ppn); + dbProcessNotify(pdevPvt->ppn); prec->pact = TRUE; return 0; } - if (pnotifyInfo->status) { + if (pdevPvt->status) { recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - pnotifyInfo->smooth = FALSE; + pdevPvt->smooth = FALSE; return 2; } /* Apply smoothing algorithm */ - if (prec->smoo != 0.0 && pnotifyInfo->smooth) + if (prec->smoo != 0.0 && pdevPvt->smooth) prec->val = prec->val * prec->smoo + - pnotifyInfo->buffer.value * (1.0 - prec->smoo); + pdevPvt->buffer.value * (1.0 - prec->smoo); else - prec->val = pnotifyInfo->buffer.value; + prec->val = pdevPvt->buffer.value; prec->udf = FALSE; - pnotifyInfo->smooth = TRUE; + pdevPvt->smooth = TRUE; switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { case pvlOptNMS: break; case pvlOptMSI: - if (pnotifyInfo->buffer.severity < INVALID_ALARM) + if (pdevPvt->buffer.severity < INVALID_ALARM) break; /* else fall through */ case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); break; case pvlOptMSS: - recGblSetSevr(prec, pnotifyInfo->buffer.status, - pnotifyInfo->buffer.severity); + recGblSetSevr(prec, pdevPvt->buffer.status, + pdevPvt->buffer.severity); break; } if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = pnotifyInfo->buffer.time; + prec->time = pdevPvt->buffer.time; return 2; } diff --git a/src/std/dev/devBiSoftCallback.c b/src/std/dev/devBiSoftCallback.c index 7c6dc6bbc..fff6f7017 100644 --- a/src/std/dev/devBiSoftCallback.c +++ b/src/std/dev/devBiSoftCallback.c @@ -32,7 +32,7 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) -typedef struct notifyInfo { +typedef struct devPvt { processNotify *ppn; CALLBACK *pcallback; long options; @@ -42,13 +42,13 @@ typedef struct notifyInfo { DBRtime epicsEnum16 value; } buffer; -} notifyInfo; +} devPvt; static void getCallback(processNotify *ppn,notifyGetType type) { biRecord *prec = (biRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; long no_elements = 1; if (ppn->status == notifyCanceled) { @@ -57,16 +57,16 @@ static void getCallback(processNotify *ppn,notifyGetType type) } assert(type == getFieldType); - pnotifyInfo->status = dbGetField(ppn->paddr, DBR_ENUM, - &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); + pdevPvt->status = dbGetField(ppn->paddr, DBR_ENUM, + &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) { biRecord *prec = (biRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); + callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); } static long add_record(dbCommon *pcommon) @@ -75,7 +75,7 @@ static long add_record(dbCommon *pcommon) DBLINK *plink = &prec->inp; DBADDR *pdbaddr; long status; - notifyInfo *pnotifyInfo; + devPvt *pdevPvt; processNotify *ppn; if (plink->type == CONSTANT) return 0; @@ -109,29 +109,29 @@ static long add_record(dbCommon *pcommon) ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), "devBiSoftCallback::add_record"); - pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devBiSoftCallback::add_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->options = GET_OPTIONS; + pdevPvt->ppn = ppn; + pdevPvt->options = GET_OPTIONS; - prec->dpvt = pnotifyInfo; + prec->dpvt = pdevPvt; return 0; } static long del_record(dbCommon *pcommon) { biRecord *prec = (biRecord *)pcommon; DBLINK *plink = &prec->inp; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pnotifyInfo->ppn); - free(pnotifyInfo->ppn); - free(pnotifyInfo->pcallback); - free(pnotifyInfo); + dbNotifyCancel(pdevPvt->ppn); + free(pdevPvt->ppn); + free(pdevPvt->pcallback); + free(pdevPvt); free(plink->value.pv_link.pvt); plink->type = PV_LINK; @@ -171,44 +171,44 @@ static long init_record(biRecord *prec) static long read_bi(biRecord *prec) { - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (!prec->dpvt) return 2; if (!prec->pact) { - dbProcessNotify(pnotifyInfo->ppn); + dbProcessNotify(pdevPvt->ppn); prec->pact = TRUE; return 0; } - if (pnotifyInfo->status) { + if (pdevPvt->status) { recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); return 2; } - prec->val = pnotifyInfo->buffer.value; + prec->val = pdevPvt->buffer.value; prec->udf = FALSE; switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { case pvlOptNMS: break; case pvlOptMSI: - if (pnotifyInfo->buffer.severity < INVALID_ALARM) + if (pdevPvt->buffer.severity < INVALID_ALARM) break; /* else fall through */ case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); break; case pvlOptMSS: - recGblSetSevr(prec, pnotifyInfo->buffer.status, - pnotifyInfo->buffer.severity); + recGblSetSevr(prec, pdevPvt->buffer.status, + pdevPvt->buffer.severity); break; } if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = pnotifyInfo->buffer.time; + prec->time = pdevPvt->buffer.time; return 2; } diff --git a/src/std/dev/devLiSoftCallback.c b/src/std/dev/devLiSoftCallback.c index 4b9a2a00e..8c9e7a280 100644 --- a/src/std/dev/devLiSoftCallback.c +++ b/src/std/dev/devLiSoftCallback.c @@ -32,7 +32,7 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) -typedef struct notifyInfo { +typedef struct devPvt { processNotify *ppn; CALLBACK *pcallback; long options; @@ -42,13 +42,13 @@ typedef struct notifyInfo { DBRtime epicsInt32 value; } buffer; -} notifyInfo; +} devPvt; static void getCallback(processNotify *ppn, notifyGetType type) { longinRecord *prec = (longinRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; long no_elements = 1; if (ppn->status == notifyCanceled) { @@ -57,16 +57,16 @@ static void getCallback(processNotify *ppn, notifyGetType type) } assert(type == getFieldType); - pnotifyInfo->status = dbGetField(ppn->paddr, DBR_LONG, - &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); + pdevPvt->status = dbGetField(ppn->paddr, DBR_LONG, + &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) { longinRecord *prec = (longinRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); + callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); } static long add_record(dbCommon *pcommon) @@ -75,7 +75,7 @@ static long add_record(dbCommon *pcommon) DBLINK *plink = &prec->inp; DBADDR *pdbaddr; long status; - notifyInfo *pnotifyInfo; + devPvt *pdevPvt; processNotify *ppn; if (plink->type == CONSTANT) return 0; @@ -109,29 +109,29 @@ static long add_record(dbCommon *pcommon) ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), "devLiSoftCallback::add_record"); - pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devLiSoftCallback::add_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->options = GET_OPTIONS; + pdevPvt->ppn = ppn; + pdevPvt->options = GET_OPTIONS; - prec->dpvt = pnotifyInfo; + prec->dpvt = pdevPvt; return 0; } static long del_record(dbCommon *pcommon) { longinRecord *prec = (longinRecord *)pcommon; DBLINK *plink = &prec->inp; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pnotifyInfo->ppn); - free(pnotifyInfo->ppn); - free(pnotifyInfo->pcallback); - free(pnotifyInfo); + dbNotifyCancel(pdevPvt->ppn); + free(pdevPvt->ppn); + free(pdevPvt->pcallback); + free(pdevPvt); free(plink->value.pv_link.pvt); plink->type = PV_LINK; @@ -171,44 +171,44 @@ static long init_record(longinRecord *prec) static long read_li(longinRecord *prec) { - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (!prec->dpvt) return 0; if (!prec->pact) { - dbProcessNotify(pnotifyInfo->ppn); + dbProcessNotify(pdevPvt->ppn); prec->pact = TRUE; return 0; } - if (pnotifyInfo->status) { + if (pdevPvt->status) { recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - return pnotifyInfo->status; + return pdevPvt->status; } - prec->val = pnotifyInfo->buffer.value; + prec->val = pdevPvt->buffer.value; prec->udf = FALSE; switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { case pvlOptNMS: break; case pvlOptMSI: - if (pnotifyInfo->buffer.severity < INVALID_ALARM) + if (pdevPvt->buffer.severity < INVALID_ALARM) break; /* else fall through */ case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); break; case pvlOptMSS: - recGblSetSevr(prec, pnotifyInfo->buffer.status, - pnotifyInfo->buffer.severity); + recGblSetSevr(prec, pdevPvt->buffer.status, + pdevPvt->buffer.severity); break; } if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = pnotifyInfo->buffer.time; + prec->time = pdevPvt->buffer.time; return 0; } diff --git a/src/std/dev/devMbbiDirectSoftCallback.c b/src/std/dev/devMbbiDirectSoftCallback.c index b2bcd7bcd..1597a1e23 100644 --- a/src/std/dev/devMbbiDirectSoftCallback.c +++ b/src/std/dev/devMbbiDirectSoftCallback.c @@ -32,7 +32,7 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) -typedef struct notifyInfo { +typedef struct devPvt { processNotify *ppn; CALLBACK *pcallback; long options; @@ -42,13 +42,13 @@ typedef struct notifyInfo { DBRtime epicsUInt16 value; } buffer; -} notifyInfo; +} devPvt; static void getCallback(processNotify *ppn, notifyGetType type) { mbbiDirectRecord *prec = (mbbiDirectRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; long no_elements = 1; if (ppn->status == notifyCanceled) { @@ -57,16 +57,16 @@ static void getCallback(processNotify *ppn, notifyGetType type) } assert(type == getFieldType); - pnotifyInfo->status = dbGetField(ppn->paddr, DBR_USHORT, - &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); + pdevPvt->status = dbGetField(ppn->paddr, DBR_USHORT, + &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) { mbbiDirectRecord *prec = (mbbiDirectRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); + callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); } static long add_record(dbCommon *pcommon) @@ -75,7 +75,7 @@ static long add_record(dbCommon *pcommon) DBLINK *plink = &prec->inp; DBADDR *pdbaddr; long status; - notifyInfo *pnotifyInfo; + devPvt *pdevPvt; processNotify *ppn; if (plink->type == CONSTANT) return 0; @@ -109,29 +109,29 @@ static long add_record(dbCommon *pcommon) ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), "devMbbiDirectSoftCallback::add_record"); - pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devMbbiDirectSoftCallback::add_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->options = GET_OPTIONS; + pdevPvt->ppn = ppn; + pdevPvt->options = GET_OPTIONS; - prec->dpvt = pnotifyInfo; + prec->dpvt = pdevPvt; return 0; } static long del_record(dbCommon *pcommon) { mbbiDirectRecord *prec = (mbbiDirectRecord *)pcommon; DBLINK *plink = &prec->inp; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pnotifyInfo->ppn); - free(pnotifyInfo->ppn); - free(pnotifyInfo->pcallback); - free(pnotifyInfo); + dbNotifyCancel(pdevPvt->ppn); + free(pdevPvt->ppn); + free(pdevPvt->pcallback); + free(pdevPvt); free(plink->value.pv_link.pvt); plink->type = PV_LINK; @@ -171,44 +171,44 @@ static long init_record(mbbiDirectRecord *prec) static long read_mbbiDirect(mbbiDirectRecord *prec) { - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (!prec->dpvt) return 2; if (!prec->pact) { - dbProcessNotify(pnotifyInfo->ppn); + dbProcessNotify(pdevPvt->ppn); prec->pact = TRUE; return 0; } - if (pnotifyInfo->status) { + if (pdevPvt->status) { recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); return 2; } - prec->val = pnotifyInfo->buffer.value; + prec->val = pdevPvt->buffer.value; prec->udf = FALSE; switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { case pvlOptNMS: break; case pvlOptMSI: - if (pnotifyInfo->buffer.severity < INVALID_ALARM) + if (pdevPvt->buffer.severity < INVALID_ALARM) break; /* else fall through */ case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); break; case pvlOptMSS: - recGblSetSevr(prec, pnotifyInfo->buffer.status, - pnotifyInfo->buffer.severity); + recGblSetSevr(prec, pdevPvt->buffer.status, + pdevPvt->buffer.severity); break; } if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = pnotifyInfo->buffer.time; + prec->time = pdevPvt->buffer.time; return 2; } diff --git a/src/std/dev/devMbbiSoftCallback.c b/src/std/dev/devMbbiSoftCallback.c index f583d8cff..1cf25640e 100644 --- a/src/std/dev/devMbbiSoftCallback.c +++ b/src/std/dev/devMbbiSoftCallback.c @@ -32,7 +32,7 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) -typedef struct notifyInfo { +typedef struct devPvt { processNotify *ppn; CALLBACK *pcallback; long options; @@ -42,13 +42,13 @@ typedef struct notifyInfo { DBRtime epicsEnum16 value; } buffer; -} notifyInfo; +} devPvt; static void getCallback(processNotify *ppn, notifyGetType type) { mbbiRecord *prec = (mbbiRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; long no_elements = 1; if (ppn->status == notifyCanceled) { @@ -57,16 +57,16 @@ static void getCallback(processNotify *ppn, notifyGetType type) } assert(type == getFieldType); - pnotifyInfo->status = dbGetField(ppn->paddr, DBR_ENUM, - &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); + pdevPvt->status = dbGetField(ppn->paddr, DBR_ENUM, + &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) { mbbiRecord *prec = (mbbiRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); + callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); } static long add_record(dbCommon *pcommon) @@ -75,7 +75,7 @@ static long add_record(dbCommon *pcommon) DBLINK *plink = &prec->inp; DBADDR *pdbaddr; long status; - notifyInfo *pnotifyInfo; + devPvt *pdevPvt; processNotify *ppn; if (plink->type == CONSTANT) return 0; @@ -109,29 +109,29 @@ static long add_record(dbCommon *pcommon) ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), "devMbbiSoftCallback::add_record"); - pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devMbbiSoftCallback::add_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->options = GET_OPTIONS; + pdevPvt->ppn = ppn; + pdevPvt->options = GET_OPTIONS; - prec->dpvt = pnotifyInfo; + prec->dpvt = pdevPvt; return 0; } static long del_record(dbCommon *pcommon) { mbbiRecord *prec = (mbbiRecord *)pcommon; DBLINK *plink = &prec->inp; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pnotifyInfo->ppn); - free(pnotifyInfo->ppn); - free(pnotifyInfo->pcallback); - free(pnotifyInfo); + dbNotifyCancel(pdevPvt->ppn); + free(pdevPvt->ppn); + free(pdevPvt->pcallback); + free(pdevPvt); free(plink->value.pv_link.pvt); plink->type = PV_LINK; @@ -171,44 +171,44 @@ static long init_record(mbbiRecord *prec) static long read_mbbi(mbbiRecord *prec) { - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (!prec->dpvt) return 2; if (!prec->pact) { - dbProcessNotify(pnotifyInfo->ppn); + dbProcessNotify(pdevPvt->ppn); prec->pact = TRUE; return 0; } - if (pnotifyInfo->status) { + if (pdevPvt->status) { recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); return 2; } - prec->val = pnotifyInfo->buffer.value; + prec->val = pdevPvt->buffer.value; prec->udf = FALSE; switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { case pvlOptNMS: break; case pvlOptMSI: - if (pnotifyInfo->buffer.severity < INVALID_ALARM) + if (pdevPvt->buffer.severity < INVALID_ALARM) break; /* else fall through */ case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); break; case pvlOptMSS: - recGblSetSevr(prec, pnotifyInfo->buffer.status, - pnotifyInfo->buffer.severity); + recGblSetSevr(prec, pdevPvt->buffer.status, + pdevPvt->buffer.severity); break; } if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = pnotifyInfo->buffer.time; + prec->time = pdevPvt->buffer.time; return 2; } diff --git a/src/std/dev/devSiSoftCallback.c b/src/std/dev/devSiSoftCallback.c index 2aa732221..18438a06d 100644 --- a/src/std/dev/devSiSoftCallback.c +++ b/src/std/dev/devSiSoftCallback.c @@ -33,7 +33,7 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) -typedef struct notifyInfo { +typedef struct devPvt { processNotify *ppn; CALLBACK *pcallback; long options; @@ -43,13 +43,13 @@ typedef struct notifyInfo { DBRtime char value[MAX_STRING_SIZE]; } buffer; -} notifyInfo; +} devPvt; static void getCallback(processNotify *ppn, notifyGetType type) { stringinRecord *prec = (stringinRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; long no_elements = 1; if (ppn->status==notifyCanceled) { @@ -58,16 +58,16 @@ static void getCallback(processNotify *ppn, notifyGetType type) } assert(type == getFieldType); - pnotifyInfo->status = dbGetField(ppn->paddr, DBR_STRING, - &pnotifyInfo->buffer, &pnotifyInfo->options, &no_elements, 0); + pdevPvt->status = dbGetField(ppn->paddr, DBR_STRING, + &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); } static void doneCallback(processNotify *ppn) { stringinRecord *prec = (stringinRecord *)ppn->usrPvt; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec); + callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); } @@ -77,7 +77,7 @@ static long add_record(dbCommon *pcommon) DBLINK *plink = &prec->inp; DBADDR *pdbaddr; long status; - notifyInfo *pnotifyInfo; + devPvt *pdevPvt; processNotify *ppn; if (plink->type == CONSTANT) return 0; @@ -111,29 +111,29 @@ static long add_record(dbCommon *pcommon) ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), "devSiSoftCallback::add_record"); - pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK), + pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), "devSiSoftCallback::add_record"); - pnotifyInfo->ppn = ppn; - pnotifyInfo->options = GET_OPTIONS; + pdevPvt->ppn = ppn; + pdevPvt->options = GET_OPTIONS; - prec->dpvt = pnotifyInfo; + prec->dpvt = pdevPvt; return 0; } static long del_record(dbCommon *pcommon) { stringinRecord *prec = (stringinRecord *)pcommon; DBLINK *plink = &prec->inp; - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pnotifyInfo->ppn); - free(pnotifyInfo->ppn); - free(pnotifyInfo->pcallback); - free(pnotifyInfo); + dbNotifyCancel(pdevPvt->ppn); + free(pdevPvt->ppn); + free(pdevPvt->pcallback); + free(pdevPvt); free(plink->value.pv_link.pvt); plink->type = PV_LINK; @@ -173,22 +173,22 @@ static long init_record(stringinRecord *prec) static long read_si(stringinRecord *prec) { - notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + devPvt *pdevPvt = (devPvt *)prec->dpvt; if (!prec->dpvt) return 0; if (!prec->pact) { - dbProcessNotify(pnotifyInfo->ppn); + dbProcessNotify(pdevPvt->ppn); prec->pact = TRUE; return 0; } - if (pnotifyInfo->status) { + if (pdevPvt->status) { recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - return pnotifyInfo->status; + return pdevPvt->status; } - strncpy(prec->val, pnotifyInfo->buffer.value, MAX_STRING_SIZE); + strncpy(prec->val, pdevPvt->buffer.value, MAX_STRING_SIZE); prec->val[MAX_STRING_SIZE-1] = 0; prec->udf = FALSE; @@ -196,21 +196,21 @@ static long read_si(stringinRecord *prec) case pvlOptNMS: break; case pvlOptMSI: - if (pnotifyInfo->buffer.severity < INVALID_ALARM) + if (pdevPvt->buffer.severity < INVALID_ALARM) break; /* else fall through */ case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pnotifyInfo->buffer.severity); + recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); break; case pvlOptMSS: - recGblSetSevr(prec, pnotifyInfo->buffer.status, - pnotifyInfo->buffer.severity); + recGblSetSevr(prec, pdevPvt->buffer.status, + pdevPvt->buffer.severity); break; } if (prec->tsel.type == CONSTANT && prec->tse == epicsTimeEventDeviceTime) - prec->time = pnotifyInfo->buffer.time; + prec->time = pdevPvt->buffer.time; return 0; } From 51578959d4ca448a7b5d32c08ce473820fe803f8 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 1 Dec 2010 15:14:09 -0600 Subject: [PATCH 9/9] dev: Replaced callocMustSucceed() with calloc() Make the *iSoftCallback devices allocate a single buffer for private storage instead of several, and cope with calloc failures without suspending the IOC thread. --- src/std/dev/devAiSoftCallback.c | 35 ++++++++++++------------ src/std/dev/devBiSoftCallback.c | 35 ++++++++++++------------ src/std/dev/devLiSoftCallback.c | 35 ++++++++++++------------ src/std/dev/devMbbiDirectSoftCallback.c | 35 ++++++++++++------------ src/std/dev/devMbbiSoftCallback.c | 35 ++++++++++++------------ src/std/dev/devSiSoftCallback.c | 36 ++++++++++++------------- 6 files changed, 102 insertions(+), 109 deletions(-) diff --git a/src/std/dev/devAiSoftCallback.c b/src/std/dev/devAiSoftCallback.c index ee73b0b44..6ed92e5d6 100644 --- a/src/std/dev/devAiSoftCallback.c +++ b/src/std/dev/devAiSoftCallback.c @@ -33,8 +33,9 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) typedef struct devPvt { - processNotify *ppn; - CALLBACK *pcallback; + DBADDR dbaddr; + processNotify pn; + CALLBACK callback; long options; int status; int smooth; @@ -67,7 +68,7 @@ static void doneCallback(processNotify *ppn) aiRecord *prec = (aiRecord *)ppn->usrPvt; devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); + callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); } static long add_record(dbCommon *pcommon) @@ -87,11 +88,19 @@ static long add_record(dbCommon *pcommon) return S_db_badField; } - pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devAiSoftCallback::add_record"); + pdevPvt = calloc(1, sizeof(*pdevPvt)); + if (!pdevPvt) { + status = S_db_noMemory; + recGblRecordError(status, (void *)prec, + "devAiSoftCallback (add_record) out of memory, calloc() failed"); + return status; + } + pdbaddr = &pdevPvt->dbaddr; + ppn = &pdevPvt->pn; + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); if (status) { - free(pdbaddr); + free(pdevPvt); recGblRecordError(status, (void *)prec, "devAiSoftCallback (add_record) link target not found"); return status; @@ -102,19 +111,12 @@ static long add_record(dbCommon *pcommon) plink->value.pv_link.pvt = pdbaddr; plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - ppn = callocMustSucceed(1, sizeof(*ppn), - "devAiSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), - "devAiSoftCallback::add_record"); - pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), - "devAiSoftCallback::add_record"); - pdevPvt->ppn = ppn; pdevPvt->options = GET_OPTIONS; prec->dpvt = pdevPvt; @@ -129,11 +131,8 @@ static long del_record(dbCommon *pcommon) { if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pdevPvt->ppn); - free(pdevPvt->ppn); - free(pdevPvt->pcallback); + dbNotifyCancel(&pdevPvt->pn); free(pdevPvt); - free(plink->value.pv_link.pvt); plink->type = PV_LINK; plink->value.pv_link.pvt = NULL; @@ -178,7 +177,7 @@ static long read_ai(aiRecord *prec) return 2; if (!prec->pact) { - dbProcessNotify(pdevPvt->ppn); + dbProcessNotify(&pdevPvt->pn); prec->pact = TRUE; return 0; } diff --git a/src/std/dev/devBiSoftCallback.c b/src/std/dev/devBiSoftCallback.c index fff6f7017..d11350a2e 100644 --- a/src/std/dev/devBiSoftCallback.c +++ b/src/std/dev/devBiSoftCallback.c @@ -33,8 +33,9 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) typedef struct devPvt { - processNotify *ppn; - CALLBACK *pcallback; + DBADDR dbaddr; + processNotify pn; + CALLBACK callback; long options; int status; struct { @@ -66,7 +67,7 @@ static void doneCallback(processNotify *ppn) biRecord *prec = (biRecord *)ppn->usrPvt; devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); + callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); } static long add_record(dbCommon *pcommon) @@ -86,11 +87,19 @@ static long add_record(dbCommon *pcommon) return S_db_badField; } - pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devBiSoftCallback::add_record"); + pdevPvt = calloc(1, sizeof(*pdevPvt)); + if (!pdevPvt) { + status = S_db_noMemory; + recGblRecordError(status, (void *)prec, + "devBiSoftCallback (add_record) out of memory, calloc() failed"); + return status; + } + pdbaddr = &pdevPvt->dbaddr; + ppn = &pdevPvt->pn; + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); if (status) { - free(pdbaddr); + free(pdevPvt); recGblRecordError(status, (void *)prec, "devBiSoftCallback (add_record) link target not found"); return status; @@ -101,19 +110,12 @@ static long add_record(dbCommon *pcommon) plink->value.pv_link.pvt = pdbaddr; plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - ppn = callocMustSucceed(1, sizeof(*ppn), - "devBiSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), - "devBiSoftCallback::add_record"); - pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), - "devBiSoftCallback::add_record"); - pdevPvt->ppn = ppn; pdevPvt->options = GET_OPTIONS; prec->dpvt = pdevPvt; @@ -128,11 +130,8 @@ static long del_record(dbCommon *pcommon) { if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pdevPvt->ppn); - free(pdevPvt->ppn); - free(pdevPvt->pcallback); + dbNotifyCancel(&pdevPvt->pn); free(pdevPvt); - free(plink->value.pv_link.pvt); plink->type = PV_LINK; plink->value.pv_link.pvt = NULL; @@ -177,7 +176,7 @@ static long read_bi(biRecord *prec) return 2; if (!prec->pact) { - dbProcessNotify(pdevPvt->ppn); + dbProcessNotify(&pdevPvt->pn); prec->pact = TRUE; return 0; } diff --git a/src/std/dev/devLiSoftCallback.c b/src/std/dev/devLiSoftCallback.c index 8c9e7a280..020ea7cf0 100644 --- a/src/std/dev/devLiSoftCallback.c +++ b/src/std/dev/devLiSoftCallback.c @@ -33,8 +33,9 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) typedef struct devPvt { - processNotify *ppn; - CALLBACK *pcallback; + DBADDR dbaddr; + processNotify pn; + CALLBACK callback; long options; int status; struct { @@ -66,7 +67,7 @@ static void doneCallback(processNotify *ppn) longinRecord *prec = (longinRecord *)ppn->usrPvt; devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); + callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); } static long add_record(dbCommon *pcommon) @@ -86,11 +87,19 @@ static long add_record(dbCommon *pcommon) return S_db_badField; } - pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devLiSoftCallback::add_record"); + pdevPvt = calloc(1, sizeof(*pdevPvt)); + if (!pdevPvt) { + status = S_db_noMemory; + recGblRecordError(status, (void *)prec, + "devLiSoftCallback (add_record) out of memory, calloc() failed"); + return status; + } + pdbaddr = &pdevPvt->dbaddr; + ppn = &pdevPvt->pn; + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); if (status) { - free(pdbaddr); + free(pdevPvt); recGblRecordError(status, (void *)prec, "devLiSoftCallback (init_record) linked record not found"); return status; @@ -101,19 +110,12 @@ static long add_record(dbCommon *pcommon) plink->value.pv_link.pvt = pdbaddr; plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - ppn = callocMustSucceed(1, sizeof(*ppn), - "devLiSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), - "devLiSoftCallback::add_record"); - pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), - "devLiSoftCallback::add_record"); - pdevPvt->ppn = ppn; pdevPvt->options = GET_OPTIONS; prec->dpvt = pdevPvt; @@ -128,11 +130,8 @@ static long del_record(dbCommon *pcommon) { if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pdevPvt->ppn); - free(pdevPvt->ppn); - free(pdevPvt->pcallback); + dbNotifyCancel(&pdevPvt->pn); free(pdevPvt); - free(plink->value.pv_link.pvt); plink->type = PV_LINK; plink->value.pv_link.pvt = NULL; @@ -177,7 +176,7 @@ static long read_li(longinRecord *prec) return 0; if (!prec->pact) { - dbProcessNotify(pdevPvt->ppn); + dbProcessNotify(&pdevPvt->pn); prec->pact = TRUE; return 0; } diff --git a/src/std/dev/devMbbiDirectSoftCallback.c b/src/std/dev/devMbbiDirectSoftCallback.c index 1597a1e23..18994a3b7 100644 --- a/src/std/dev/devMbbiDirectSoftCallback.c +++ b/src/std/dev/devMbbiDirectSoftCallback.c @@ -33,8 +33,9 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) typedef struct devPvt { - processNotify *ppn; - CALLBACK *pcallback; + DBADDR dbaddr; + processNotify pn; + CALLBACK callback; long options; int status; struct { @@ -66,7 +67,7 @@ static void doneCallback(processNotify *ppn) mbbiDirectRecord *prec = (mbbiDirectRecord *)ppn->usrPvt; devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); + callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); } static long add_record(dbCommon *pcommon) @@ -86,11 +87,19 @@ static long add_record(dbCommon *pcommon) return S_db_badField; } - pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devMbbiDirectSoftCallback::add_record"); + pdevPvt = calloc(1, sizeof(*pdevPvt)); + if (!pdevPvt) { + status = S_db_noMemory; + recGblRecordError(status, (void *)prec, + "devMbbiDirectSoftCallback (add_record) out of memory, calloc() failed"); + return status; + } + pdbaddr = &pdevPvt->dbaddr; + ppn = &pdevPvt->pn; + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); if (status) { - free(pdbaddr); + free(pdevPvt); recGblRecordError(status,(void *)prec, "devMbbiDirectSoftCallback (add_record) linked record not found"); return status; @@ -101,19 +110,12 @@ static long add_record(dbCommon *pcommon) plink->value.pv_link.pvt = pdbaddr; plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - ppn = callocMustSucceed(1, sizeof(*ppn), - "devMbbiDirectSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), - "devMbbiDirectSoftCallback::add_record"); - pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), - "devMbbiDirectSoftCallback::add_record"); - pdevPvt->ppn = ppn; pdevPvt->options = GET_OPTIONS; prec->dpvt = pdevPvt; @@ -128,11 +130,8 @@ static long del_record(dbCommon *pcommon) { if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pdevPvt->ppn); - free(pdevPvt->ppn); - free(pdevPvt->pcallback); + dbNotifyCancel(&pdevPvt->pn); free(pdevPvt); - free(plink->value.pv_link.pvt); plink->type = PV_LINK; plink->value.pv_link.pvt = NULL; @@ -177,7 +176,7 @@ static long read_mbbiDirect(mbbiDirectRecord *prec) return 2; if (!prec->pact) { - dbProcessNotify(pdevPvt->ppn); + dbProcessNotify(&pdevPvt->pn); prec->pact = TRUE; return 0; } diff --git a/src/std/dev/devMbbiSoftCallback.c b/src/std/dev/devMbbiSoftCallback.c index 1cf25640e..4cb89c0bd 100644 --- a/src/std/dev/devMbbiSoftCallback.c +++ b/src/std/dev/devMbbiSoftCallback.c @@ -33,8 +33,9 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) typedef struct devPvt { - processNotify *ppn; - CALLBACK *pcallback; + DBADDR dbaddr; + processNotify pn; + CALLBACK callback; long options; int status; struct { @@ -66,7 +67,7 @@ static void doneCallback(processNotify *ppn) mbbiRecord *prec = (mbbiRecord *)ppn->usrPvt; devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); + callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); } static long add_record(dbCommon *pcommon) @@ -86,11 +87,19 @@ static long add_record(dbCommon *pcommon) return S_db_badField; } - pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devMbbiSoftCallback::add_record"); + pdevPvt = calloc(1, sizeof(*pdevPvt)); + if (!pdevPvt) { + status = S_db_noMemory; + recGblRecordError(status, (void *)prec, + "devMbbiSoftCallback (add_record) out of memory, calloc() failed"); + return status; + } + pdbaddr = &pdevPvt->dbaddr; + ppn = &pdevPvt->pn; + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); if (status) { - free(pdbaddr); + free(pdevPvt); recGblRecordError(status, (void *)prec, "devMbbiSoftCallback (add_record) linked record not found"); return status; @@ -101,19 +110,12 @@ static long add_record(dbCommon *pcommon) plink->value.pv_link.pvt = pdbaddr; plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - ppn = callocMustSucceed(1, sizeof(*ppn), - "devMbbiSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), - "devMbbiSoftCallback::add_record"); - pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), - "devMbbiSoftCallback::add_record"); - pdevPvt->ppn = ppn; pdevPvt->options = GET_OPTIONS; prec->dpvt = pdevPvt; @@ -128,11 +130,8 @@ static long del_record(dbCommon *pcommon) { if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pdevPvt->ppn); - free(pdevPvt->ppn); - free(pdevPvt->pcallback); + dbNotifyCancel(&pdevPvt->pn); free(pdevPvt); - free(plink->value.pv_link.pvt); plink->type = PV_LINK; plink->value.pv_link.pvt = NULL; @@ -177,7 +176,7 @@ static long read_mbbi(mbbiRecord *prec) return 2; if (!prec->pact) { - dbProcessNotify(pdevPvt->ppn); + dbProcessNotify(&pdevPvt->pn); prec->pact = TRUE; return 0; } diff --git a/src/std/dev/devSiSoftCallback.c b/src/std/dev/devSiSoftCallback.c index 18438a06d..14dfd6d1e 100644 --- a/src/std/dev/devSiSoftCallback.c +++ b/src/std/dev/devSiSoftCallback.c @@ -34,8 +34,9 @@ #define GET_OPTIONS (DBR_STATUS | DBR_TIME) typedef struct devPvt { - processNotify *ppn; - CALLBACK *pcallback; + DBADDR dbaddr; + processNotify pn; + CALLBACK callback; long options; int status; struct { @@ -67,10 +68,9 @@ static void doneCallback(processNotify *ppn) stringinRecord *prec = (stringinRecord *)ppn->usrPvt; devPvt *pdevPvt = (devPvt *)prec->dpvt; - callbackRequestProcessCallback(pdevPvt->pcallback, prec->prio, prec); + callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); } - static long add_record(dbCommon *pcommon) { stringinRecord *prec = (stringinRecord *)pcommon; @@ -88,11 +88,19 @@ static long add_record(dbCommon *pcommon) return S_db_badField; } - pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), - "devSiSoftCallback::add_record"); + pdevPvt = calloc(1, sizeof(*pdevPvt)); + if (!pdevPvt) { + status = S_db_noMemory; + recGblRecordError(status, (void *)prec, + "devSiSoftCallback (add_record) out of memory, calloc() failed"); + return status; + } + pdbaddr = &pdevPvt->dbaddr; + ppn = &pdevPvt->pn; + status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr); if (status) { - free(pdbaddr); + free(pdevPvt); recGblRecordError(status, (void *)prec, "devSiSoftCallback (add_record) linked record not found"); return status; @@ -103,19 +111,12 @@ static long add_record(dbCommon *pcommon) plink->value.pv_link.pvt = pdbaddr; plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - ppn = callocMustSucceed(1, sizeof(*ppn), - "devSiSoftCallback::add_record"); ppn->usrPvt = prec; ppn->paddr = pdbaddr; ppn->getCallback = getCallback; ppn->doneCallback = doneCallback; ppn->requestType = processGetRequest; - pdevPvt = callocMustSucceed(1, sizeof(*pdevPvt), - "devSiSoftCallback::add_record"); - pdevPvt->pcallback = callocMustSucceed(1, sizeof(CALLBACK), - "devSiSoftCallback::add_record"); - pdevPvt->ppn = ppn; pdevPvt->options = GET_OPTIONS; prec->dpvt = pdevPvt; @@ -130,11 +131,8 @@ static long del_record(dbCommon *pcommon) { if (plink->type == CONSTANT) return 0; assert(plink->type == PN_LINK); - dbNotifyCancel(pdevPvt->ppn); - free(pdevPvt->ppn); - free(pdevPvt->pcallback); + dbNotifyCancel(&pdevPvt->pn); free(pdevPvt); - free(plink->value.pv_link.pvt); plink->type = PV_LINK; plink->value.pv_link.pvt = NULL; @@ -179,7 +177,7 @@ static long read_si(stringinRecord *prec) return 0; if (!prec->pact) { - dbProcessNotify(pdevPvt->ppn); + dbProcessNotify(&pdevPvt->pn); prec->pact = TRUE; return 0; }