ADApp/pluginSrc/NDPluginDriver.cpp
void NDPluginDriver::driverCallback(asynUser *pasynUser, void *genericPointer)
{
     
    NDArray *pArray = (NDArray *)genericPointer;
    epicsTimeStamp tNow;
    double minCallbackTime, deltaTime;
    int status=0;
    int blockingCallbacks;
    int arrayCounter, droppedArrays, queueSize, queueFree;
    static const char *functionName = "driverCallback";

    this->lock();

    status |= getDoubleParam(NDPluginDriverMinCallbackTime, &minCallbackTime);
    status |= getIntegerParam(NDPluginDriverBlockingCallbacks, &blockingCallbacks);
    status |= getIntegerParam(NDPluginDriverQueueSize, &queueSize);
    
    epicsTimeGetCurrent(&tNow);
    deltaTime = epicsTimeDiffInSeconds(&tNow, &this->lastProcessTime);

    if ((minCallbackTime == 0.) || (deltaTime > minCallbackTime)) {  
        /* Time to process the next array */
        
        /* The callbacks can operate in 2 modes: blocking or non-blocking.
         * If blocking we call processCallbacks directly, executing them
         * in the detector callback thread.
         * If non-blocking we put the array on the queue and it executes
         * in our background thread. */
        /* Update the time we last posted an array */
        epicsTimeGetCurrent(&tNow);
        memcpy(&this->lastProcessTime, &tNow, sizeof(tNow));
        if (blockingCallbacks) {
            processCallbacks(pArray);
        } else {
            /* Increase the reference count again on this array
             * It will be released in the background task when processing is done */
            pArray->reserve();
            /* Try to put this array on the message queue.  If there is no room then return
             * immediately. */
            status = epicsMessageQueueTrySend(this->msgQId, &pArray, sizeof(&pArray));
            queueFree = queueSize - epicsMessageQueuePending(this->msgQId);
            setIntegerParam(NDPluginDriverQueueFree, queueFree);
            if (status) {
                status |= getIntegerParam(NDArrayCounter, &arrayCounter);
                status |= getIntegerParam(NDPluginDriverDroppedArrays, &droppedArrays);
                asynPrint(pasynUser, ASYN_TRACE_FLOW, 
                    "%s:%s message queue full, dropped array %d\n",
                    driverName, functionName, arrayCounter);
                droppedArrays++;
                status |= setIntegerParam(NDPluginDriverDroppedArrays, droppedArrays);
                /* This buffer needs to be released */
                pArray->release();
            }
        }
    }
    callParamCallbacks();
    this->unlock();
}
/** Method that is called from the driver with a new NDArray.
  * It calls the processCallbacks function, which typically is implemented in the
  * derived class.
  * It can either do the callbacks directly (if NDPluginDriverBlockingCallbacks=1) or by queueing
  * the arrays to be processed by a background task (if NDPluginDriverBlockingCallbacks=0).
  * In the latter case arrays can be dropped if the queue is full.  This method should really
  * be private, but it must be called from a C-linkage callback function, so it must be public.
  * \param[in] pasynUser  The pasynUser from the asyn client.
  * \param[in] genericPointer The pointer to the NDArray */
Method that is called from the driver with a new NDArray.
It calls the processCallbacks function, which typically is implemented in the
derived class.
It can either do the callbacks directly (if NDPluginDriverBlockingCallbacks=1) or by queueing
the arrays to be processed by a background task (if NDPluginDriverBlockingCallbacks=0).
In the latter case arrays can be dropped if the queue is full.  This method should really
be private, but it must be called from a C-linkage callback function, so it must be public.
\param[in] pasynUser  The pasynUser from the asyn client.
\param[in] genericPointer The pointer to the NDArray
Method that is called from the driver with a new NDArray . It calls the processCallbacks function which typically is implemented in the derived class . It can either do the callbacks directly ( if NDPluginDriverBlockingCallbacks = 1 ) or by queueing the arrays to be processed by a background task ( if NDPluginDriverBlockingCallbacks = 0 ) . In the latter case arrays can be dropped if the queue is full . This method should really be private but it must be called from a C - linkage callback function so it must be public . \ param [ in ] pasynUser The pasynUser from the asyn client . \ param [ in ] genericPointer The pointer to the NDArray
void NDPluginDriver::driverCallback(asynUser *pasynUser, void *genericPointer)
{
    NDArray *pArray = (NDArray *)genericPointer;
    epicsTimeStamp tNow;
    double minCallbackTime, deltaTime;
    int status=0;
    int blockingCallbacks;
    int arrayCounter, droppedArrays, queueSize, queueFree;
    static const char *functionName = "driverCallback";
    this->lock();
    status |= getDoubleParam(NDPluginDriverMinCallbackTime, &minCallbackTime);
    status |= getIntegerParam(NDPluginDriverBlockingCallbacks, &blockingCallbacks);
    status |= getIntegerParam(NDPluginDriverQueueSize, &queueSize);
    epicsTimeGetCurrent(&tNow);
    deltaTime = epicsTimeDiffInSeconds(&tNow, &this->lastProcessTime);
    if ((minCallbackTime == 0.) || (deltaTime > minCallbackTime)) {  
        epicsTimeGetCurrent(&tNow);
        memcpy(&this->lastProcessTime, &tNow, sizeof(tNow));
        if (blockingCallbacks) {
            processCallbacks(pArray);
        } else {
            pArray->reserve();
            status = epicsMessageQueueTrySend(this->msgQId, &pArray, sizeof(&pArray));
            queueFree = queueSize - epicsMessageQueuePending(this->msgQId);
            setIntegerParam(NDPluginDriverQueueFree, queueFree);
            if (status) {
                status |= getIntegerParam(NDArrayCounter, &arrayCounter);
                status |= getIntegerParam(NDPluginDriverDroppedArrays, &droppedArrays);
                asynPrint(pasynUser, ASYN_TRACE_FLOW, 
                    "%s:%s message queue full, dropped array %d\n",
                    driverName, functionName, arrayCounter);
                droppedArrays++;
                status |= setIntegerParam(NDPluginDriverDroppedArrays, droppedArrays);
                pArray->release();
            }
        }
    }
    callParamCallbacks();
    this->unlock();
}
void NDPluginDriver :: driverCallback ( asynUser * pasynUser , void * genericPointer ) { NDArray * pArray = ( NDArray * ) genericPointer ; epicsTimeStamp tNow ; double minCallbackTime , deltaTime ; int status = 0 ; int blockingCallbacks ; int arrayCounter , droppedArrays , queueSize , queueFree ; static const char * functionName = " " ; this -> lock ( ) ; status |= getDoubleParam ( NDPluginDriverMinCallbackTime , & minCallbackTime ) ; status |= getIntegerParam ( NDPluginDriverBlockingCallbacks , & blockingCallbacks ) ; status |= getIntegerParam ( NDPluginDriverQueueSize , & queueSize ) ; epicsTimeGetCurrent ( & tNow ) ; deltaTime = epicsTimeDiffInSeconds ( & tNow , & this -> lastProcessTime ) ; if ( ( minCallbackTime == 0. ) || ( deltaTime > minCallbackTime ) ) { epicsTimeGetCurrent ( & tNow ) ; memcpy ( & this -> lastProcessTime , & tNow , sizeof ( tNow ) ) ; if ( blockingCallbacks ) { processCallbacks ( pArray ) ; } else { pArray -> reserve ( ) ; status = epicsMessageQueueTrySend ( this -> msgQId , & pArray , sizeof ( & pArray ) ) ; queueFree = queueSize - epicsMessageQueuePending ( this -> msgQId ) ; setIntegerParam ( NDPluginDriverQueueFree , queueFree ) ; if ( status ) { status |= getIntegerParam ( NDArrayCounter , & arrayCounter ) ; status |= getIntegerParam ( NDPluginDriverDroppedArrays , & droppedArrays ) ; asynPrint ( pasynUser , ASYN_TRACE_FLOW , " \n " , driverName , functionName , arrayCounter ) ; droppedArrays ++ ; status |= setIntegerParam ( NDPluginDriverDroppedArrays , droppedArrays ) ; pArray -> release ( ) ; } } } callParamCallbacks ( ) ; this -> unlock ( ) ; }
Method that is called from the driver with a new NDArray.
Method that is called from the driver with a new NDArray .
/* Time to process the next array */ /* The callbacks can operate in 2 modes: blocking or non-blocking.
         * If blocking we call processCallbacks directly, executing them
         * in the detector callback thread.
         * If non-blocking we put the array on the queue and it executes
         * in our background thread. */ /* Update the time we last posted an array */ /* Increase the reference count again on this array
             * It will be released in the background task when processing is done */ /* Try to put this array on the message queue.  If there is no room then return
             * immediately. */ /* This buffer needs to be released */