示例#1
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);
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
/* 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);
}