static void putNotifyCommon(putNotify *ppn,dbCommon *precord) { long status=0; dbFldDes *pfldDes = ppn->paddr->pfldDes; putNotifyPvt *pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; if(precord->ppn && pputNotifyPvt->state!=putNotifyRestartCallbackRequested) { /*another putNotify owns the record */ pputNotifyPvt->state = putNotifyWaitForRestart; ellSafeAdd(&precord->ppnr->restartList,&ppn->restartNode); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } else if(precord->ppn){ assert(precord->ppn==ppn); assert(pputNotifyPvt->state==putNotifyRestartCallbackRequested); } if(precord->pact) { precord->ppn = ppn; ellSafeAdd(&pputNotifyPvt->waitList,&precord->ppnr->waitNode); pputNotifyPvt->state = putNotifyRestartInProgress; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } status=dbPut(ppn->paddr,ppn->dbrType,ppn->pbuffer,ppn->nRequest); ppn->status = (status==0) ? putNotifyOK : putNotifyError; /* 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))) { precord->ppn = ppn; ellSafeAdd(&pputNotifyPvt->waitList,&precord->ppnr->waitNode); pputNotifyPvt->state = putNotifyPutInProgress; epicsMutexUnlock(pnotifyGlobal->lock); dbProcess(precord); dbScanUnlock(precord); return; } if(pputNotifyPvt->state==putNotifyRestartCallbackRequested) { restartCheck(precord->ppnr); } pputNotifyPvt->state = putNotifyUserCallbackActive; assert(precord->ppn!=ppn); callUser(precord,ppn); }
long epicsShareAPI dbPutField(DBADDR *paddr, short dbrType, const void *pbuffer, long nRequest) { long status = 0; long special = paddr->special; dbFldDes *pfldDes = paddr->pfldDes; dbCommon *precord = paddr->precord; short dbfType = paddr->field_type; if (special == SPC_ATTRIBUTE) return S_db_noMod; /*check for putField disabled*/ if (precord->disp && (void *)(&precord->disp) != paddr->pfield) return S_db_putDisabled; if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) return dbPutFieldLink(paddr, dbrType, pbuffer, nRequest); dbScanLock(precord); status = dbPut(paddr, dbrType, pbuffer, nRequest); if (status == 0) { if (paddr->pfield == (void *)&precord->proc || (pfldDes->process_passive && precord->scan == 0 && dbrType < DBR_PUT_ACKT)) { if (precord->pact) { if (precord->tpro) printf("%s: Active %s\n", epicsThreadGetNameSelf(), precord->name); precord->rpro = TRUE; } else { /* indicate that dbPutField called dbProcess */ precord->putf = TRUE; status = dbProcess(precord); } } } dbScanUnlock(precord); return status; }
long epicsShareAPI dbPutLinkValue(struct link *plink, short dbrType, const void *pbuffer, long nRequest) { long status = 0; if (plink->type == DB_LINK) { struct dbCommon *psource = plink->value.pv_link.precord; struct pv_link *ppv_link = &plink->value.pv_link; DBADDR *paddr = (DBADDR *)ppv_link->pvt; dbCommon *pdest = paddr->precord; status = dbPut(paddr, dbrType, pbuffer, nRequest); inherit_severity(ppv_link,pdest,psource->nsta,psource->nsev); if (status) return status; if (paddr->pfield == (void *)&pdest->proc || (ppv_link->pvlMask & pvlOptPP && pdest->scan == 0)) { /*if dbPutField caused asyn record to process */ /* ask for reprocessing*/ if (pdest->putf) { pdest->rpro = TRUE; } else { /* otherwise ask for the record to be processed*/ status = dbScanLink(psource, pdest); } } if (status) recGblSetSevr(psource, LINK_ALARM, INVALID_ALARM); } else if (plink->type == CA_LINK) { struct dbCommon *psource = plink->value.pv_link.precord; status = dbCaPutLink(plink, dbrType, pbuffer, nRequest); if (status < 0) recGblSetSevr(psource, LINK_ALARM, INVALID_ALARM); } else { cantProceed("dbPutLinkValue: Illegal link type"); } return status; }
/* Only use dbChannelPut() if the record is already locked. * This routine doesn't work on link fields, ignores DISP, and * doesn't trigger record processing on PROC or pp(TRUE). */ long dbChannelPut(dbChannel *chan, short type, const void *pbuffer, long nRequest) { return dbPut(&chan->addr, type, pbuffer, nRequest); }