示例#1
0
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);
}
示例#2
0
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);
    }
}
示例#3
0
文件: dbNotify.c 项目: ukaea/epics
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);
}
示例#4
0
/* 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);
}
示例#5
0
文件: dbPvPut.cpp 项目: pheest/pvaSrv
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);
}
示例#6
0
文件: dbPvPut.cpp 项目: pheest/pvaSrv
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());
}
示例#7
0
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());
    }
}
示例#8
0
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;
}
示例#9
0
文件: dbNotify.c 项目: ukaea/epics
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;
}
示例#10
0
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;
}
示例#11
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;
}
示例#12
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);
}
示例#13
0
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);
}
示例#14
0
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);
}
示例#15
0
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;
}
示例#16
0
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 );
}
示例#17
0
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);
	}
}
示例#18
0
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);
    }
}
示例#19
0
文件: dbNotify.c 项目: ukaea/epics
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);
}
示例#20
0
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);
}
示例#21
0
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);
    }
}
示例#22
0
文件: callback.c 项目: ukaea/epics
static void ProcessCallback(CALLBACK *pcallback)
{
    dbCommon *pRec;

    callbackGetUser(pRec, pcallback);
    if (!pRec) return;
    dbScanLock(pRec);
    (*pRec->rset->process)(pRec);
    dbScanUnlock(pRec);
}
示例#23
0
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;
}
示例#24
0
/* 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);
}
示例#25
0
文件: dbAccess.c 项目: ukaea/epics
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;
}
示例#26
0
文件: dbNotify.c 项目: ukaea/epics
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);
}
示例#27
0
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;
}
示例#28
0
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);
}
示例#29
0
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);
}
示例#30
0
/* ---------------------------------------------------------------------- */
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__ );
}