void dbNotifyCancel(processNotify *ppn) { dbCommon *precord = dbChannelRecord(ppn->chan); notifyState state; notifyPvt *pnotifyPvt; dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); ppn->status = notifyCanceled; pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; if (!pnotifyPvt || pnotifyPvt->state == notifyNotActive) { epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } state = pnotifyPvt->state; switch (state) { case notifyUserCallbackRequested: case notifyRestartCallbackRequested: case notifyUserCallbackActive: /* Callback is scheduled or active, wait for it to complete */ pnotifyPvt->cancelWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); epicsEventWait(pnotifyPvt->cancelEvent); epicsMutexMustLock(pnotifyGlobal->lock); notifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); return; case notifyNotActive: break; case notifyWaitForRestart: assert(precord->ppn); assert(precord->ppn!=ppn); ellSafeDelete(&precord->ppnr->restartList,&ppn->restartNode); break; case notifyRestartInProgress: case notifyProcessInProgress: { /*Take all records out of wait list */ processNotifyRecord *ppnrWait; while ((ppnrWait = (processNotifyRecord *) ellFirst(&pnotifyPvt->waitList))) { ellSafeDelete(&pnotifyPvt->waitList, &ppnrWait->waitNode); restartCheck(ppnrWait); } } if (precord->ppn == ppn) restartCheck(precord->ppnr); break; default: printf("dbNotify: illegal state for notifyCallback\n"); } pnotifyPvt->state = notifyNotActive; notifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); }
static void asynCallback(asynUser *pasynUser) { mcaAsynPvt *pPvt = (mcaAsynPvt *)pasynUser->userPvt; mcaRecord *pmca = pPvt->pmca; mcaAsynMessage *pmsg = pasynUser->userData; rset *prset = (rset *)pmca->rset; int status; asynPrint(pasynUser, ASYN_TRACE_FLOW, "devMcaAsyn::asynCallback: %s command=%d, ivalue=%d, dvalue=%f\n", pmca->name, pmsg->command, pmsg->ivalue, pmsg->dvalue); pasynUser->reason = pPvt->driverReasons[pmsg->command]; if (pmsg->command == mcaData) { /* Read data */ pPvt->pasynInt32Array->read(pPvt->asynInt32ArrayPvt, pasynUser, pPvt->data, pmca->nuse, &pPvt->nread); dbScanLock((dbCommon *)pmca); (*prset->process)(pmca); dbScanUnlock((dbCommon *)pmca); } else if (pmsg->command == mcaReadStatus) { /* Read the current status of the device */ pPvt->pasynInt32->write(pPvt->asynInt32Pvt, pasynUser, 0); pasynUser->reason = pPvt->driverReasons[mcaAcquiring]; pPvt->pasynInt32->read(pPvt->asynInt32Pvt, pasynUser, &pPvt->acquiring); pasynUser->reason = pPvt->driverReasons[mcaElapsedLiveTime]; pPvt->pasynFloat64->read(pPvt->asynFloat64Pvt, pasynUser, &pPvt->elapsedLive); pasynUser->reason = pPvt->driverReasons[mcaElapsedRealTime]; pPvt->pasynFloat64->read(pPvt->asynFloat64Pvt, pasynUser, &pPvt->elapsedReal); pasynUser->reason = pPvt->driverReasons[mcaElapsedCounts]; pPvt->pasynFloat64->read(pPvt->asynFloat64Pvt, pasynUser, &pPvt->totalCounts); pasynUser->reason = pPvt->driverReasons[mcaDwellTime]; pPvt->pasynFloat64->read(pPvt->asynFloat64Pvt, pasynUser, &pPvt->dwellTime); dbScanLock((dbCommon *)pmca); (*prset->process)(pmca); dbScanUnlock((dbCommon *)pmca); } else { if (pmsg->interface == int32Type) { pPvt->pasynInt32->write(pPvt->asynInt32Pvt, pasynUser, pmsg->ivalue); } else { pPvt->pasynFloat64->write(pPvt->asynFloat64Pvt, pasynUser, pmsg->dvalue); } } pasynManager->memFree(pmsg, sizeof(*pmsg)); status = pasynManager->freeAsynUser(pasynUser); if (status != asynSuccess) { asynPrint(pasynUser, ASYN_TRACE_ERROR, "devMcaAsyn::asynCallback: %s error in freeAsynUser, %s\n", pmca->name, pasynUser->errorMessage); } }
void epicsShareAPI dbNotifyCancel(putNotify *ppn) { dbCommon *precord = ppn->paddr->precord; putNotifyState state; putNotifyPvt *pputNotifyPvt; assert(precord); dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; if(!pputNotifyPvt || pputNotifyPvt->state==putNotifyNotActive) { epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } state = pputNotifyPvt->state; /*If callback is scheduled or active wait for it to complete*/ if(state==putNotifyUserCallbackRequested || state==putNotifyRestartCallbackRequested || state==putNotifyUserCallbackActive) { pputNotifyPvt->cancelWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); epicsEventWait(pputNotifyPvt->cancelEvent); epicsMutexMustLock(pnotifyGlobal->lock); putNotifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); return; } switch(state) { case putNotifyNotActive: break; case putNotifyWaitForRestart: assert(precord->ppn); assert(precord->ppn!=ppn); ellSafeDelete(&precord->ppnr->restartList,&ppn->restartNode); break; case putNotifyRestartInProgress: case putNotifyPutInProgress: { /*Take all records out of wait list */ putNotifyRecord *ppnrWait; while((ppnrWait = (putNotifyRecord *)ellFirst(&pputNotifyPvt->waitList))){ ellSafeDelete(&pputNotifyPvt->waitList,&ppnrWait->waitNode); restartCheck(ppnrWait); } } if(precord->ppn==ppn) restartCheck(precord->ppnr); break; default: printf("dbNotify: illegal state for notifyCallback\n"); } pputNotifyPvt->state = putNotifyNotActive; putNotifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); }
/* Callback for bo, see ao_callback comments */ static void check_bo_callback(void *arg) { boRecord *rec = (boRecord *) arg; struct rset *rset= (struct rset *)(rec->rset); DevicePrivate *pvt = (DevicePrivate *)rec->dpvt; unsigned long rval; eip_bool process = false; /* We are about the check and even set val, & rval -> lock */ dbScanLock((dbCommon *)rec); if (rec->pact) { (*rset->process) ((dbCommon *)rec); dbScanUnlock((dbCommon *)rec); return; } /* Check if record's (R)VAL is current */ if (!check_data((dbCommon *) rec)) { (*rset->process) ((dbCommon *)rec); dbScanUnlock((dbCommon *)rec); return; } if (get_bits((dbCommon *)rec, 1, &rval) && (rec->udf || rec->sevr == INVALID_ALARM || rec->rval != rval)) { if (rec->tpro) printf("'%s': got %lu from driver\n", rec->name, rval); if (!rec->udf && pvt->special & SPCO_FORCE) { if (rec->tpro) printf("'%s': will re-write record's value %u\n", rec->name, (unsigned int)rec->val); } else { /* back-convert rval into val */ rec->rval = rval; rec->val = (rec->rval==0) ? 0 : 1; rec->udf = false; if (rec->tpro) printf("'%s': updated record to tag, val = %u\n", rec->name, (unsigned int)rec->val); } process = true; } dbScanUnlock((dbCommon *)rec); /* Does record need processing and is not periodic? */ if (process && rec->scan < SCAN_1ST_PERIODIC) scanOnce(rec); }
void DbPvPut::get() { if(DbPvDebug::getLevel()>0) printf("dbPvPut::get()\n"); { Lock lock(dataMutex); dbScanLock(dbChannelRecord(dbPv->getDbChannel())); bitSet->clear(); Status status = dbUtil->get( channelPutRequester, propertyMask, dbPv->getDbChannel(), pvStructure, bitSet, 0); dbScanUnlock(dbChannelRecord(dbPv->getDbChannel())); if(firstTime) { firstTime = false; bitSet->set(pvStructure->getFieldOffset()); } } channelPutRequester->getDone( status, getPtrSelf(), pvStructure, bitSet); }
void DbPvPut::put(PVStructurePtr const &pvStructure, BitSetPtr const & bitSet) { if (DbPvDebug::getLevel() > 0) printf("dbPvPut::put()\n"); this->pvStructure = pvStructure; this->bitSet = bitSet; if (block && process) { dbProcessNotify(pNotify.get()); return; } Lock lock(dataMutex); PVFieldPtr pvField = pvStructure.get()->getPVFields()[0]; if (propertyMask & dbUtil->dbPutBit) { status = dbUtil->putField( channelPutRequester, propertyMask, dbPv->getDbChannel(), pvField); } else { dbScanLock(dbChannelRecord(dbPv->getDbChannel())); status = dbUtil->put( channelPutRequester, propertyMask, dbPv->getDbChannel(), pvField); if (process) dbProcess(dbChannelRecord(dbPv->getDbChannel())); dbScanUnlock(dbChannelRecord(dbPv->getDbChannel())); } lock.unlock(); channelPutRequester->putDone(status, getPtrSelf()); }
void DbPvPut::put(PVStructurePtr const &pvStructure, BitSetPtr const & bitSet) { if(DbPvDebug::getLevel()>0) printf("dbPvPut::put()\n"); Lock lock(dataMutex); this->pvStructure = pvStructure; this->bitSet = bitSet; PVFieldPtr pvField = pvStructure.get()->getPVFields()[0]; if(propertyMask&dbUtil->dbPutBit) { Status status = dbUtil->putField( channelPutRequester,propertyMask,dbAddr,pvField); lock.unlock(); channelPutRequester->putDone(status,getPtrSelf()); return; } dbScanLock(dbAddr.precord); Status status = dbUtil->put( channelPutRequester, propertyMask, dbAddr, pvField); if (process && !block) dbProcess(dbAddr.precord); dbScanUnlock(dbAddr.precord); lock.unlock(); if (block && process) { epicsUInt8 value = 1; pNotify.get()->pbuffer = &value; dbPutNotify(pNotify.get()); } else { channelPutRequester->putDone(status, getPtrSelf()); } }
static void myCallback_devBoSyncSoft(CALLBACK *p_callback) { struct dbCommon *precord; CONTEXT *p_myContext; struct rset *prset; callbackGetUser(precord,p_callback); #ifdef DEBUG1 printf( __FILE__ "[%d] -> %s (%s)\n", __LINE__, __func__, precord->name ); #endif p_myContext=(CONTEXT *)precord->dpvt; prset = (struct rset *)(precord->rset); dbScanLock(precord); (*prset->process)(precord); dbScanUnlock(precord); #ifdef DEBUG1 printf( __FILE__ "[%d] <- %s\n", __LINE__, __func__ ); #endif return; }
static void callUser(dbCommon *precord,putNotify *ppn) { putNotifyPvt *pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; 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(!pputNotifyPvt->cancelWait && !pputNotifyPvt->userCallbackWait) { putNotifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); return; } if(pputNotifyPvt->cancelWait) { pputNotifyPvt->cancelWait = 0; epicsEventSignal(pputNotifyPvt->cancelEvent); epicsMutexUnlock(pnotifyGlobal->lock); return; } assert(pputNotifyPvt->userCallbackWait); pputNotifyPvt->userCallbackWait = 0; epicsEventSignal(pputNotifyPvt->userCallbackEvent); epicsMutexUnlock(pnotifyGlobal->lock); return; }
static EPICSTHREADFUNC calcThread(void *param) { subRecord *precord; myData *pmyData; struct rset *prset; while(epicsMessageQueueReceive(queueId, (void*) &pmyData, sizeof(myData*))) { precord = pmyData->precord; prset = (struct rset*) precord->rset; if(dbSubFinalDebug) { epicsMessageQueueShow(queueId, 1); epicsPrintf("Thread %s: Record %s requested thread processing\n", epicsThreadGetNameSelf(), precord->name); } pmyData->private_counter ++; dbScanLock((struct dbCommon*) precord); (*prset->process)(precord); dbScanUnlock((struct dbCommon*) precord); } return 0; }
long epicsShareAPI dbtr(const char *pname) { DBADDR addr; long status; struct dbCommon *precord; if (!pname || !*pname) { printf("Usage: dbtr \"pv name\"\n"); return 1; } if (nameToAddr(pname, &addr)) return -1; precord = (struct dbCommon*)addr.precord; if (precord->pact) { printf("record active\n"); return 1; } dbScanLock(precord); status = dbProcess(precord); dbScanUnlock(precord); if (status) recGblRecordError(status, precord, "dbtr(dbProcess)"); dbpr(pname, 3); return 0; }
static void interruptCallback(void *drvPvt, asynUser *pasynUser, epicsInt32 value) { devBusyPvt *pPvt = (devBusyPvt *)drvPvt; busyRecord *pr = (busyRecord *)pPvt->pr; unsigned short monitor_mask; dbScanLock((dbCommon *)pr); asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE, "%s devAsynBusy::interruptCallback new value=%d\n", pr->name, value); /* If the current value of the record is 1 and the new value is 0 then post monitors * and call recGblFwdLink * Ignore the callback if pr->pact=1 because a write operation is in progress. */ if ((pr->pact == 0) && (pr->val == 1) && (value == 0)) { /* If the current value of the record is 1 and the new value is 0 then post monitors * and call recGblFwdLink */ asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE, "%s devAsynBusy::interruptCallback 1 to 0 transition, posting monitors and calling recGblFwdLink\n", pr->name); pr->val = value; monitor_mask = recGblResetAlarms(pr); /* post events for value change and archive change */ monitor_mask |= (DBE_VALUE | DBE_LOG); /* update last value monitored */ pr->mlst = pr->val; /* send out monitors connected to the value field */ if (monitor_mask){ db_post_events(pr,&pr->val,monitor_mask); } recGblFwdLink(pr); } dbScanUnlock((dbCommon *)pr); }
static void notifyCallback(CALLBACK *pcallback) { processNotify *ppn = NULL; dbCommon *precord; notifyPvt *pnotifyPvt; callbackGetUser(ppn,pcallback); pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; precord = dbChannelRecord(ppn->chan); dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); assert(precord->ppnr); assert(pnotifyPvt->state == notifyRestartCallbackRequested || pnotifyPvt->state == notifyUserCallbackRequested); assert(ellCount(&pnotifyPvt->waitList) == 0); if (pnotifyPvt->cancelWait) { if (pnotifyPvt->state == notifyRestartCallbackRequested) { restartCheck(precord->ppnr); } epicsEventSignal(pnotifyPvt->cancelEvent); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } if(pnotifyPvt->state == notifyRestartCallbackRequested) { processNotifyCommon(ppn, precord); return; } /* All done. Clean up and call userCallback */ pnotifyPvt->state = notifyUserCallbackActive; assert(precord->ppn!=ppn); callDone(precord, ppn); }
void dbProcessNotify(processNotify *ppn) { struct dbChannel *chan = ppn->chan; dbCommon *precord = dbChannelRecord(chan); short dbfType = dbChannelFieldType(chan); notifyPvt *pnotifyPvt; /* Must handle DBF_XXXLINKs as special case. * Only dbPutField will change link fields. * Also the record is not processed as a result */ ppn->status = notifyOK; ppn->wasProcessed = 0; if (dbfType>=DBF_INLINK && dbfType<=DBF_FWDLINK) { if (ppn->requestType == putProcessRequest || ppn->requestType == putProcessGetRequest) { /* Check if puts disabled */ if (precord->disp && (dbChannelField(ppn->chan) != (void *) &precord->disp)) { 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); pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; if (pnotifyPvt && (pnotifyPvt->magic != MAGIC)) { printf("dbPutNotify:pnotifyPvt was not initialized\n"); pnotifyPvt = 0; } if (pnotifyPvt) { assert(pnotifyPvt->state == notifyUserCallbackActive); pnotifyPvt->userCallbackWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); epicsEventWait(pnotifyPvt->userCallbackEvent); dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); notifyCleanup(ppn); } 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); } processNotifyCommon(ppn, precord); }
static void callDone(dbCommon *precord, processNotify *ppn) { notifyPvt *pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; epicsMutexUnlock(pnotifyGlobal->lock); if (ppn->requestType == processGetRequest || ppn->requestType == putProcessGetRequest) { ppn->getCallback(ppn, getFieldType); } 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 (pnotifyPvt->cancelWait) { pnotifyPvt->cancelWait = 0; epicsEventSignal(pnotifyPvt->cancelEvent); epicsMutexUnlock(pnotifyGlobal->lock); return; } assert(pnotifyPvt->userCallbackWait); pnotifyPvt->userCallbackWait = 0; epicsEventSignal(pnotifyPvt->userCallbackEvent); epicsMutexUnlock(pnotifyGlobal->lock); return; }
void myBoard_wakeupQueue( int board ) { MY_BOARD_SOFTWARE *pBoardSoft = myBoard_getSoftwareBoard( board ); if (pBoardSoft == NULL) return; QUEUE_T *pQueue = &pBoardSoft->asyncQueue; int numCurrent = asyncQueueGetUsed( pQueue ); int qid; fprintf( stderr, "queue length=%d\n", numCurrent ); for (qid = 0; qid < numCurrent; ++qid) { dbCommon *p = asyncQueuePop( pQueue ); fprintf( stderr, "checking [%d] %s\n", qid, p->name ); if (enoughDataToProcess( p )) { struct rset * prset = p->rset; fprintf( stderr, "processing q[%d] id=%d\n", board, qid ); dbScanLock( p ); (*prset->process)( p ); dbScanUnlock( p ); } else { /* put back */ asyncQueuePush( pQueue, p ); } } fprintf( stderr, "done processing queue for b=%d\n", board ); }
static void acalcPerformTask(void *parm) { calcMessage msg; acalcoutRecord *pcalc; struct rset *prset; if (aCalcoutRecordDebug >= 10) printf("acalcPerformTask:entry\n"); while (1) { /* waiting for messages */ if (epicsMessageQueueReceive(acalcMsgQueue, &msg, MSG_SIZE) != MSG_SIZE) { printf("acalcPerformTask: epicsMessageQueueReceive returned wrong size\n"); break; } pcalc = msg.pcalc; prset = (struct rset *)(pcalc->rset); dbScanLock((struct dbCommon *)pcalc); if (aCalcoutRecordDebug >= 10) printf("acalcPerformTask:message from '%s'\n", pcalc->name); call_aCalcPerform(pcalc); if (aCalcoutRecordDebug >= 10) printf("acalcPerformTask:processing '%s'\n", pcalc->name); (*prset->process)(pcalc); dbScanUnlock((struct dbCommon *)pcalc); } }
static void outputCallbackCallback(CALLBACK *pcb) { devPvt *pPvt; static const char *functionName="outputCallbackCallback"; callbackGetUser(pPvt, pcb); { dbCommon *pr = pPvt->pr; dbScanLock(pr); epicsMutexLock(pPvt->devPvtLock); pPvt->newOutputCallbackValue = 1; dbProcess(pr); if (pPvt->newOutputCallbackValue != 0) { /* We called dbProcess but the record did not process, perhaps because PACT was 1 * Need to remove ring buffer element */ asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, "%s %s::%s warning dbProcess did not process record, PACT=%d\n", pr->name, driverName, functionName,pr->pact); getCallbackValue(pPvt); pPvt->newOutputCallbackValue = 0; } epicsMutexUnlock(pPvt->devPvtLock); dbScanUnlock(pr); } }
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); }
void dbCaCallbackProcess(void *usrPvt) { struct link *plink = (struct link *)usrPvt; dbCommon *pdbCommon = plink->value.pv_link.precord; dbScanLock(pdbCommon); pdbCommon->rset->process(pdbCommon); dbScanUnlock(pdbCommon); }
static void scanList(scan_list *psl) { /* When reading this code remember that the call to dbProcess can result * in the SCAN field being changed in an arbitrary number of records. */ scan_element *pse; scan_element *prev = NULL; scan_element *next = NULL; epicsMutexMustLock(psl->lock); psl->modified = FALSE; pse = (scan_element *)ellFirst(&psl->list); if (pse) next = (scan_element *)ellNext(&pse->node); epicsMutexUnlock(psl->lock); while (pse) { struct dbCommon *precord = pse->precord; dbScanLock(precord); dbProcess(precord); dbScanUnlock(precord); epicsMutexMustLock(psl->lock); if (!psl->modified) { prev = pse; pse = (scan_element *)ellNext(&pse->node); if (pse) next = (scan_element *)ellNext(&pse->node); } else if (pse->pscan_list == psl) { /*This scan element is still in same scan list*/ prev = pse; pse = (scan_element *)ellNext(&pse->node); if (pse) next = (scan_element *)ellNext(&pse->node); psl->modified = FALSE; } else if (prev && prev->pscan_list == psl) { /*Previous scan element is still in same scan list*/ pse = (scan_element *)ellNext(&prev->node); if (pse) { prev = (scan_element *)ellPrevious(&pse->node); next = (scan_element *)ellNext(&pse->node); } psl->modified = FALSE; } else if (next && next->pscan_list == psl) { /*Next scan element is still in same scan list*/ pse = next; prev = (scan_element *)ellPrevious(&pse->node); next = (scan_element *)ellNext(&pse->node); psl->modified = FALSE; } else { /*Too many changes. Just wait till next period*/ epicsMutexUnlock(psl->lock); return; } epicsMutexUnlock(psl->lock); } }
static void ProcessCallback(CALLBACK *pcallback) { dbCommon *pRec; callbackGetUser(pRec, pcallback); if (!pRec) return; dbScanLock(pRec); (*pRec->rset->process)(pRec); dbScanUnlock(pRec); }
long dbChannelGetField(dbChannel *chan, short dbrType, void *pbuffer, long *options, long *nRequest, void *pfl) { dbCommon *precord = chan->addr.precord; long status = 0; dbScanLock(precord); status = dbChannelGet(chan, dbrType, pbuffer, options, nRequest, pfl); dbScanUnlock(precord); return status; }
/* We need to know when a save or restore operation has completed, so client software * can wait for the operation to complete before acting on the result. */ void configMenuCallback(int status, void *puserPvt) { aSubRecord *pasub = (aSubRecord *)puserPvt; epicsInt32 *d = (epicsInt32 *)pasub->d; if (configMenuDebug) printf("configMenuCallback:status=%d, puserPvt=%p\n", status, puserPvt); dbScanLock((dbCommon *)pasub); *d = (epicsInt32)status; dbScanUnlock((dbCommon *)pasub); scanOnce((dbCommon *)puserPvt); }
long dbGetField(DBADDR *paddr,short dbrType, void *pbuffer, long *options, long *nRequest, void *pflin) { dbCommon *precord = paddr->precord; long status = 0; dbScanLock(precord); status = dbGet(paddr, dbrType, pbuffer, options, nRequest, pflin); dbScanUnlock(precord); return status; }
void epicsShareAPI dbPutNotify(putNotify *ppn) { dbCommon *precord = ppn->paddr->precord; short dbfType = ppn->paddr->field_type; long status=0; putNotifyPvt *pputNotifyPvt; 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); return; } dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; if(pputNotifyPvt && (pputNotifyPvt->magic!=MAGIC)) { printf("dbPutNotify:pputNotifyPvt was not initialized\n"); pputNotifyPvt = 0; } if(pputNotifyPvt) { assert(pputNotifyPvt->state==putNotifyUserCallbackActive); pputNotifyPvt->userCallbackWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); epicsEventWait(pputNotifyPvt->userCallbackEvent); dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); putNotifyCleanup(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)); precord->ppnr->precord = precord; ellInit(&precord->ppnr->restartList); } putNotifyCommon(ppn,precord); }
long epicsShareAPI dbGetField(DBADDR *paddr,short dbrType, void *pbuffer, long *options, long *nRequest, void *pflin) { short dbfType = paddr->field_type; dbCommon *precord = paddr->precord; long status = 0; dbScanLock(precord); if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { DBENTRY dbEntry; dbFldDes *pfldDes = paddr->pfldDes; char *rtnString; char *pbuf = (char *)pbuffer; int maxlen; if (options && (*options)) getOptions(paddr, &pbuf, options, pflin); if (nRequest && *nRequest == 0) goto done; switch (dbrType) { case DBR_STRING: maxlen = MAX_STRING_SIZE - 1; if (nRequest && *nRequest > 1) *nRequest = 1; break; case DBR_CHAR: case DBR_UCHAR: if (nRequest && *nRequest > 0) { maxlen = *nRequest - 1; break; } /* else fall through ... */ default: status = S_db_badDbrtype; goto done; } dbInitEntry(pdbbase, &dbEntry); status = dbFindRecord(&dbEntry, precord->name); if (!status) status = dbFindField(&dbEntry, pfldDes->name); if (!status) { rtnString = dbGetString(&dbEntry); strncpy(pbuf, rtnString, maxlen); pbuf[maxlen] = 0; } dbFinishEntry(&dbEntry); } else { status = dbGet(paddr, dbrType, pbuffer, options, nRequest, pflin); } done: dbScanUnlock(precord); return status; }
static void interruptCallbackEnumBo(void *drvPvt, asynUser *pasynUser, char *strings[], int values[], int severities[], size_t nElements) { devPvt *pPvt = (devPvt *)drvPvt; boRecord *pr = (boRecord *)pPvt->pr; if (!interruptAccept) return; dbScanLock((dbCommon*)pr); setEnums((char*)&pr->znam, NULL, &pr->zsv, strings, NULL, severities, nElements, 2); db_post_events(pr, &pr->val, DBE_PROPERTY); dbScanUnlock((dbCommon*)pr); }
static void interruptCallbackEnumMbbo(void *drvPvt, asynUser *pasynUser, char *strings[], int values[], int severities[], size_t nElements) { devPvt *pPvt = (devPvt *)drvPvt; mbboRecord *pr = (mbboRecord *)pPvt->pr; if (!interruptAccept) return; dbScanLock((dbCommon*)pr); setEnums((char*)&pr->zrst, (int*)&pr->zrvl, &pr->zrsv, strings, values, severities, nElements, MAX_ENUM_STATES); db_post_events(pr, &pr->val, DBE_PROPERTY); dbScanUnlock((dbCommon*)pr); }
/* ---------------------------------------------------------------------- */ void myCallback_devAiAsyncGpib(CALLBACK *p_callback) { struct dbCommon *p_record; struct rset *p_rset; dsetLog(3, __FILE__ "[%d] -> %s \n", __LINE__, __func__ ); callbackGetUser(p_record,p_callback); p_rset=(struct rset *)(p_record->rset); dbScanLock(p_record); (*p_rset->process)(p_record); dbScanUnlock(p_record); dsetLog(3, __FILE__ "[%d] <- %s \n", __LINE__, __func__ ); }