2138 lines
75 KiB
C++
2138 lines
75 KiB
C++
///
|
|
/// \file instant.cpp
|
|
/// \author Jan Chrin, PSI
|
|
/// \date Release: February 2015
|
|
/// \version CAFE 1.0.0
|
|
///
|
|
|
|
#ifndef INSTANT_CPP
|
|
#define INSTANT_CPP
|
|
|
|
/**
|
|
* \brief Set values of data type CTYPE
|
|
* \param _handle input: handle to CAFEConduit object
|
|
* \param _dbrType input: chtype
|
|
* \param _val value/array of values of datatype const CTYPE
|
|
* \return ECA_NORMAL if all OK else CAFE_ or ECA_ error
|
|
* \return CAFE_ error if CAFEConduit::putCallback() operation is not to be executed:
|
|
* \return ECAFE_INVALID_HANDLE - Invalid reference handle
|
|
* \return ECAFE_NOWTACCESS - Write access denied
|
|
* \return ICAFE_CA_OP_CONN_DOWN - Channel is not connected
|
|
* \return ECA_ error from CAFEConduit::putCallback() operation:
|
|
* \return (*) should not arise due to pre-checks
|
|
* \return ECA_NORMAL - Normal successful completion
|
|
* \return ECA_BADCHID - Corrupted Channel Identifier (chid)
|
|
* \return ECA_BADTYPE (*) - Invalid DBR_XXX type
|
|
* \return ECA_BADCOUNT (*) - Requested count larger than native element count
|
|
* \return ECA_NOWTACCESS (*) - Write access denied
|
|
* \return ECA_ALLOCMEM - Unable to allocate memory
|
|
* \return ECA_DISCONN (*) - Channel is disconnected
|
|
*/
|
|
template <class CTYPE> int Instant<CTYPE>::set(const unsigned int _handle, const chtype _dbrType,
|
|
const CTYPE * _val ) {
|
|
#define __METHOD__ "Instant::set(_handle, _dbrType, _val)"
|
|
|
|
status=ICAFE_NORMAL;
|
|
|
|
if (_dbrType > DBR_DOUBLE) {
|
|
std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
|
|
std::cout << "INTERNAL CAFE ERROR: HOW DID THIS PERCULIAR DATA TYPE: "
|
|
<< dbr_type_to_text(_dbrType) << " GET THROUGH!" << endl;
|
|
}
|
|
|
|
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
|
|
cafeConduit_set_by_handle::iterator it_handle;
|
|
it_handle = handle_index.find(_handle);
|
|
|
|
if (it_handle != handle_index.end()) {
|
|
|
|
if ( (status=cafeGranules.channelVerifyPut(_handle, _dbrType)) != ICAFE_NORMAL) {
|
|
return status;
|
|
}
|
|
|
|
if ( (status=cafeGranules.channelPreparePut(_handle)) != ICAFE_NORMAL) {
|
|
return status;
|
|
}
|
|
|
|
if ( (status=clientRequests(_handle, _dbrType, _val)) != ICAFE_NORMAL) {
|
|
return status;
|
|
}
|
|
|
|
if ( (status=cafeGranules.channelExecutePut(_handle)) != ICAFE_NORMAL) {
|
|
return status;
|
|
}
|
|
|
|
}
|
|
else {
|
|
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_HANDLE);
|
|
return ECAFE_INVALID_HANDLE;
|
|
}
|
|
|
|
if(MUTEX) {cafeMutex.lock();}; //lock
|
|
handle_index.modify(it_handle, change_status(status));
|
|
if(MUTEX) {cafeMutex.unlock();}; //unlock
|
|
|
|
return status;
|
|
|
|
#undef __METHOD__
|
|
}
|
|
|
|
/**
|
|
* \brief Retrieve values of data type CTYPE
|
|
* \param _handle input: handle to CAFEConduit object
|
|
* \param _dbrType input: chtype
|
|
* \param _val output: value/array of values of datatype const CTYPE
|
|
* \param alarmStatus output
|
|
* \param alarmSeverity output
|
|
* \param ts output: epicsTimeStamp
|
|
* \return ECA_NORMAL if all OK else CAFE_ or ECA_ error
|
|
* \return CAFE_ error if CAFEConduit::get() operation is not to be executed:
|
|
* \return ECAFE_INVALID_HANDLE - Invalid reference handle
|
|
* \return ECAFE_NORDACCESS - Read access denied
|
|
* \return ICAFE_CA_OP_CONN_DOWN - Channel is not connected
|
|
* \return ECA_ error from CAFEConduit::get() operation:
|
|
* \return (*) should not arise due to pre-checks
|
|
* \return ECA_NORMAL - Normal successful completion
|
|
* \return ECA_BADCHID - Corrupted Channel Identifier (chid)
|
|
* \return ECA_BADTYPE (*) - Invalid DBR_XXX type
|
|
* \return ECA_BADCOUNT (*) - Requested count larger than native element count
|
|
* \return ECA_NORDACCESS(*)- Read access denied
|
|
* \return ECA_ALLOCMEM - Unable to allocate memory
|
|
* \return ECA_DISCONN (*) - Channel is disconnected
|
|
*/
|
|
template <class CTYPE> int Instant<CTYPE>::get(const unsigned int _handle,
|
|
const chtype _dbrType, CTYPE * _val,
|
|
dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts) {
|
|
#define __METHOD__ "Instant::get(_handle, dbrType, _val, alarmStatus, alarmSeverity, ts) "
|
|
|
|
//cout << __FILE__ << " " << __LINE__ << " " << __METHOD__ << endl;
|
|
|
|
status=ICAFE_NORMAL;
|
|
|
|
if (_dbrType > DBR_CTRL_DOUBLE) {
|
|
std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
|
|
std::cout << "INTERNAL CAFE ERROR: HOW DID THIS PERCULIAR DATA TYPE: "
|
|
<< dbr_type_to_text(_dbrType) << " GET THROUGH!" << endl;
|
|
}
|
|
else if (_dbrType > DBR_TIME_DOUBLE) {
|
|
std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
|
|
std::cout << "INTERNAL CAFE ERROR: METHOD NOT MEANT FOR THIS DATA TYPE: "
|
|
<< dbr_type_to_text(_dbrType) << endl;
|
|
std::cout << "CAFE WILL THUS TAKE CONTROL OF ALLOCATING APPROPIATE DBR_TYPE" << endl;
|
|
}
|
|
|
|
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
|
|
cafeConduit_set_by_handle::iterator it_handle;
|
|
|
|
|
|
it_handle = handle_index.find(_handle);
|
|
|
|
if (it_handle != handle_index.end()) {
|
|
|
|
|
|
|
|
if ( (*it_handle).getChannelGetActionWhenMonitorPolicy().getActionKind() == CAFENUM::GET_FROM_CACHE) {
|
|
if ( helper.getNmonitorData(_handle) >0){
|
|
return Instant::getCache(_handle, _dbrType, _val, alarmStatus, alarmSeverity, ts);
|
|
}
|
|
}
|
|
|
|
if ( (status=cafeGranules.channelVerifyGet(_handle, _dbrType)) != ICAFE_NORMAL) {
|
|
return status;
|
|
}
|
|
|
|
//Here fill channelRequestMetaData
|
|
|
|
if ( (status=cafeGranules.channelPrepareGet(_handle)) != ICAFE_NORMAL) {
|
|
return status;
|
|
}
|
|
|
|
if ( (status=cafeGranules.channelExecuteGet(_handle)) != ICAFE_NORMAL) {
|
|
return status;
|
|
}
|
|
|
|
channelRequestMetaDataClient = (*it_handle).getChannelRequestMetaDataClient();
|
|
|
|
|
|
status=clientRequests( _handle, channelRequestMetaDataClient.getDbrDataType(),
|
|
_val, alarmStatus, alarmSeverity, ts, false);
|
|
|
|
}
|
|
else {
|
|
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_HANDLE);
|
|
return ECAFE_INVALID_HANDLE;
|
|
}
|
|
|
|
if(MUTEX) {cafeMutex.lock();}; //lock
|
|
handle_index.modify(it_handle, change_status(status));
|
|
if(MUTEX) {cafeMutex.unlock();}; //unlock
|
|
|
|
return status;
|
|
|
|
#undef __METHOD__
|
|
}
|
|
|
|
|
|
/**
|
|
* \brief Retrieve cached values of data type CTYPE
|
|
* \param _handle input: handle to CAFEConduit object
|
|
* \param _dbrType input: chtype
|
|
* \param _val output: value/array of values of datatype const CTYPE
|
|
* \param alarmStatus output
|
|
* \param alarmSeverity output
|
|
* \param ts output: epicsTimeStamp
|
|
* \return ECA_NORMAL if all OK else CAFE_ or ECA_ error
|
|
* \return CAFE_ error if CAFEConduit::get() operation is not to be executed:
|
|
* \return ECAFE_INVALID_HANDLE - Invalid reference handle
|
|
* \return ECAFE_NORDACCESS - Read access denied
|
|
* \return ICAFE_CA_OP_CONN_DOWN - Channel is not connected
|
|
* \return ECA_ error from CAFEConduit::get() operation:
|
|
* \return (*) should not arise due to pre-checks
|
|
* \return ECA_NORMAL - Normal successful completion
|
|
* \return ECA_BADCHID - Corrupted Channel Identifier (chid)
|
|
* \return ECA_BADTYPE (*) - Invalid DBR_XXX type
|
|
* \return ECA_BADCOUNT (*) - Requested count larger than native element count
|
|
* \return ECA_NORDACCESS(*)- Read access denied
|
|
* \return ECA_ALLOCMEM - Unable to allocate memory
|
|
* \return ECA_DISCONN (*) - Channel is disconnected
|
|
*/
|
|
template <class CTYPE> int Instant<CTYPE>::getCache(const unsigned int _handle,
|
|
const chtype _dbrType, CTYPE * _val,
|
|
dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts) {
|
|
#define __METHOD__ "Instant::getCache(_handle, dbrType, _val, alarmStatus, alarmSeverity, ts) "
|
|
|
|
//cout << __FILE__ << " " << __LINE__ << " " << __METHOD__ << endl;
|
|
|
|
status=ICAFE_NORMAL;
|
|
|
|
ts.secPastEpoch= 0; // default value if cache does not have timeStamp
|
|
ts.nsec = 0; // default value if cache does not have timeStamp
|
|
alarmStatus =-1; // default value if cache does not have alarmStatus
|
|
alarmSeverity =-1; // default value if cache does not have alarmSeverity
|
|
|
|
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
|
|
cafeConduit_set_by_handle::iterator it_handle;
|
|
it_handle = handle_index.find(_handle);
|
|
|
|
if (it_handle != handle_index.end()) {
|
|
|
|
//cout << __METHOD__ << "__" << __LINE__ << endl;
|
|
//cout << "(*it_handle).getChannelGetCacheWaitPolicy().getWaitKind()" <<
|
|
//(*it_handle).getChannelGetCacheWaitPolicy().getWaitKind() << " 0=NO_CHECK 1=NO_WAIT 2=WAIT " << endl;
|
|
|
|
|
|
//meant for use in callbacks in monitors!
|
|
if ( (*it_handle).getChannelGetCacheWaitPolicy().getWaitKind() == CAFENUM::GET_CACHE_NO_CHECK) {
|
|
status=clientRequests(_handle,
|
|
_dbrType, _val, alarmStatus, alarmSeverity, ts, true);
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
//ifNeverConnected - return error
|
|
if ( (*it_handle).getChannelRegalia().getCafeConnectionState() == ICAFE_CS_NEVER_CONN) {
|
|
|
|
return ICAFE_CS_NEVER_CONN;
|
|
}
|
|
|
|
|
|
if (_dbrType > DBR_CTRL_DOUBLE) {
|
|
std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
|
|
std::cout << "INTERNAL CAFE ERROR: HOW DID THIS PERCULIAR DATA TYPE: "
|
|
<< dbr_type_to_text(_dbrType) << " GET THROUGH!" << endl;
|
|
}
|
|
else if (_dbrType > DBR_TIME_DOUBLE) {
|
|
std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
|
|
std::cout << "INTERNAL CAFE ERROR: METHOD NOT MEANT FOR THIS DATA TYPE: "
|
|
<< dbr_type_to_text(_dbrType) << endl;
|
|
std::cout << "CAFE WILL THUS TAKE CONTROL OF ALLOCATING APPROPIATE DBR_TYPE" << endl;
|
|
}
|
|
|
|
chtype dbrtype =(*it_handle).getChannelRequestMetaData().getDbrDataType();
|
|
|
|
|
|
//MetaData will have true DBR_XXX_YYY type
|
|
//Client is asking from cache for DBR_MMM_NNN
|
|
//Therefore have to prepare DBR_MMM_NNN from DBR_XXX_YY
|
|
CAFENUM::DBR_TYPE cafedbrtype= (*it_handle).getChannelRequestMetaData().getCafeDbrType();
|
|
|
|
|
|
switch (cafedbrtype)
|
|
{
|
|
case CAFENUM::DBR_TIME:
|
|
dbrtype = dbf_type_to_DBR_TIME(_dbrType%DBR_STS_STRING);
|
|
break;
|
|
case CAFENUM::DBR_STS:
|
|
dbrtype = dbf_type_to_DBR_STS(_dbrType%DBR_STS_STRING);
|
|
break;
|
|
case CAFENUM::DBR_PRIMITIVE:
|
|
dbrtype = dbf_type_to_DBR(_dbrType%DBR_STS_STRING);
|
|
break;
|
|
default:
|
|
dbrtype = (*it_handle).getChannelRequestMetaData().getDbrDataType();
|
|
cout << __METHOD__ << "/" << __LINE__ <<endl;
|
|
cout << "CAFE INTERNAL FUNNY: This line should not appear!" << endl;
|
|
break;
|
|
}
|
|
|
|
|
|
status=ICAFE_NORMAL;
|
|
|
|
//What's in the buffer and is the status OK?
|
|
//Is using Callback finished??
|
|
// If No return
|
|
if ( (status=cafeGranules.channelVerifyGet(_handle, dbrtype)) != ICAFE_NORMAL) {
|
|
|
|
//See what's in buffer anyway!
|
|
clientRequests(_handle,
|
|
_dbrType, _val, alarmStatus, alarmSeverity, ts, true);
|
|
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
//Test callbackProgressKind
|
|
channelRequestStatusGet =(*it_handle).getChannelRequestStatusGet();
|
|
|
|
if (channelRequestStatusGet.getCallbackProgressKind() == CAFENUM::PENDING
|
|
&& helper.getNmonitorData(_handle)==0
|
|
&& (*it_handle).getChannelRequestPolicyGet().getMethodKind()
|
|
!= CAFENUM::WITH_CALLBACK_USER_SUPPLIED
|
|
&& (*it_handle).getChannelGetCacheWaitPolicy().getWaitKind() == CAFENUM::GET_CACHE_WAIT
|
|
&& (*it_handle).isConnected()
|
|
|
|
) {
|
|
|
|
channelTimeoutPolicyGet = (*it_handle).getChannelTimeoutPolicyGet();
|
|
|
|
ca_flush_io();
|
|
//usleep(500); //wait 0.5ms to give time for callback to complete
|
|
status=cafeGranules.waitForGetEvent(_handle, channelTimeoutPolicyGet.getTimeout());
|
|
|
|
if (status==ECAFE_TIMEOUT && channelTimeoutPolicyGet.getSelfGoverningTimeout()) {
|
|
unsigned short ntries=0;
|
|
while (status==ECAFE_TIMEOUT && ntries<channelTimeoutPolicyGet.getNtries()) {
|
|
status=cafeGranules.waitForGetEvent(_handle, channelTimeoutPolicyGet.getTimeout() +
|
|
channelTimeoutPolicyGet.getDeltaTimeout()*(++ntries));
|
|
}
|
|
|
|
std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
|
|
std::cout << "No of waitForGetEvent tries=" << ntries << std::endl;
|
|
|
|
if (status==ECAFE_TIMEOUT) {
|
|
std::cout << "is the MAXIMUM allowed as configured through TimeoutPolicy! " << std::endl;
|
|
std::cout << "TURNING OFF SELF-GOVERNING TIMEOUT FOR GET OPERATIONS FOR THIS CHANNEL" << std::endl;
|
|
channelTimeoutPolicyGet.setSelfGoverningTimeout(false);
|
|
channelTimeoutPolicyGet.setTimeout( channelTimeoutPolicyGet.getTimeout()); //not needed same as the old one
|
|
std::cout << "AND TIMEOUT RESTORED TO START VALUE OF " << channelTimeoutPolicyGet.getTimeout() << endl;
|
|
}
|
|
else {
|
|
std::cout << "Changing timeout for handle/pv "
|
|
<< _handle << "/" << (*it_handle).getPV() << " to: " <<
|
|
|
|
(channelTimeoutPolicyGet.getTimeout() +
|
|
channelTimeoutPolicyGet.getDeltaTimeout()*ntries) << " seconds" <<endl;
|
|
|
|
//modify timeout for handle
|
|
channelTimeoutPolicyGet.setTimeout( (channelTimeoutPolicyGet.getTimeout() +
|
|
channelTimeoutPolicyGet.getDeltaTimeout()*ntries));
|
|
}
|
|
|
|
if(MUTEX){cafeMutex.lock();}; //lock
|
|
handle_index.modify(it_handle, change_channelTimeoutPolicyGet(channelTimeoutPolicyGet));
|
|
if(MUTEX){cafeMutex.unlock();}; //unlock
|
|
|
|
if (status==ECAFE_TIMEOUT) {
|
|
std::cout << "CURRENT STATUS OF HANDLE: " << std::endl;
|
|
helper.printHandle(_handle);
|
|
}
|
|
}
|
|
|
|
|
|
if (status != ICAFE_NORMAL) {
|
|
//Check these in at end of routine
|
|
channelRequestStatusGet.setCallbackStatus (status);
|
|
|
|
channelRequestStatusGet.setCallbackKind(false, false); // NOT_INITIATED NOT_TRIGGERED
|
|
|
|
if(MUTEX){cafeMutex.lock();}; //lock
|
|
handle_index.modify(it_handle,
|
|
change_channelRequestStatusGet(channelRequestStatusGet));
|
|
|
|
if(MUTEX){cafeMutex.unlock();}; //unlock
|
|
}
|
|
|
|
if(MUTEX){cafeMutex.lock();}; //lock
|
|
handle_index.modify(it_handle, change_status(status));
|
|
if(MUTEX){cafeMutex.unlock();}; //unlock
|
|
|
|
|
|
if (status != ICAFE_NORMAL) {
|
|
cout << __METHOD__ << " status= " << status << endl;
|
|
cout << "Returning ICAFE_WAITING_FOR_PREV_CALLBACK " << endl;
|
|
//Why is this required - See what's in buffer anyway!
|
|
clientRequests(_handle,
|
|
_dbrType, _val, alarmStatus, alarmSeverity, ts, true);
|
|
|
|
return ICAFE_WAITING_FOR_PREV_CALLBACK;
|
|
}
|
|
|
|
//ca_flush_io();
|
|
//return ICAFE_CALLBACK_NOT_YET_INVOKED;
|
|
}//if
|
|
|
|
|
|
channelRequestStatusGet = (*it_handle).getChannelRequestStatusGet();
|
|
status=channelRequestStatusGet.getMessageStatus();
|
|
|
|
if (status != ICAFE_NORMAL) {
|
|
cafeStatus.report(status);
|
|
//Why is this required - See what's in buffer anyway!
|
|
clientRequests(_handle,
|
|
_dbrType, _val, alarmStatus, alarmSeverity, ts, true);
|
|
|
|
return status;
|
|
}
|
|
|
|
status=clientRequests(_handle,
|
|
_dbrType, _val, alarmStatus, alarmSeverity, ts, true);
|
|
|
|
}
|
|
|
|
else {
|
|
cafeStatus.report(ECAFE_INVALID_HANDLE);
|
|
return ECAFE_INVALID_HANDLE;
|
|
}
|
|
return status;
|
|
|
|
|
|
#undef __METHOD__
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* \brief retrieve cached data from an array of handles
|
|
* \param handleArray input: Array of handles to conduit object
|
|
* \param nelem input: Size of array
|
|
* \param _dbrType input: chtype
|
|
* \param val output: Array of doubles; if handle points to a wafeform only first element is read out
|
|
* \param statusArray output: Status array reporting from each get(handle)
|
|
* \param alarmStatus output
|
|
* \param alarmSeverity output
|
|
* \param ts output: epicsTimeStamp
|
|
* \return ICAFE_NORMAL if all OK else the first ECAFE error encountered
|
|
*/
|
|
template <class CTYPE> int Instant<CTYPE>::getCache(const unsigned int *handleArray, const unsigned int nelem,
|
|
const chtype _dbrType, CTYPE * val, int *statusArray,
|
|
dbr_short_t *alarmStatus, dbr_short_t *alarmSeverity, epicsTimeStamp *ts) {
|
|
#define __METHOD__ "Instant::getCache(handleArray, nelem, _dbrType, val, statusArray) "
|
|
|
|
unsigned int nelemPrevious=1;
|
|
HandleHelper helper;
|
|
int gStatus=ICAFE_NORMAL;
|
|
bool statusSet=false;
|
|
|
|
//cout << __FILE__ << " " << __LINE__ << " " << __METHOD__ << endl;
|
|
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
|
|
|
|
|
|
//Very possibly waveforems will need longer to report back!
|
|
if(helper.getNelemNative(handleArray[i])!=1) {
|
|
|
|
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
|
|
cafeConduit_set_by_handle::iterator it_handle;
|
|
it_handle = handle_index.find(handleArray[i]);
|
|
|
|
channelRequestStatusGet =(*it_handle).getChannelRequestStatusGet();
|
|
|
|
if (channelRequestStatusGet.getCallbackProgressKind() == CAFENUM::PENDING
|
|
&& helper.getNmonitorData(handleArray[i])==0
|
|
&& (*it_handle).getChannelRequestPolicyGet().getMethodKind()
|
|
!= CAFENUM::WITH_CALLBACK_USER_SUPPLIED
|
|
&& (*it_handle).getChannelGetCacheWaitPolicy().getWaitKind() == CAFENUM::GET_CACHE_WAIT
|
|
&& (*it_handle).isConnected()
|
|
) {
|
|
|
|
channelTimeoutPolicyGet = (*it_handle).getChannelTimeoutPolicyGet();
|
|
|
|
ca_flush_io();
|
|
status=cafeGranules.waitForGetEvent(handleArray[i], channelTimeoutPolicyGet.getTimeout());
|
|
|
|
|
|
if (status==ECAFE_TIMEOUT && channelTimeoutPolicyGet.getSelfGoverningTimeout()) {
|
|
unsigned short ntries=0;
|
|
while (status==ECAFE_TIMEOUT && ntries<channelTimeoutPolicyGet.getNtries()) {
|
|
status=cafeGranules.waitForGetEvent(handleArray[i], channelTimeoutPolicyGet.getTimeout() +
|
|
channelTimeoutPolicyGet.getDeltaTimeout()*(++ntries));
|
|
}
|
|
|
|
|
|
std::cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << std::endl;
|
|
std::cout << "No of waitForGetEvent tries=" << ntries << std::endl;
|
|
|
|
if (status==ECAFE_TIMEOUT) {
|
|
std::cout << "is the MAXIMUM allowed as configured through TimeoutPolicy! " << std::endl;
|
|
std::cout << "TURNING OFF SELF-GOVERNING TIMEOUT FOR GET OPERATIONS FOR THIS CHANNEL" << std::endl;
|
|
channelTimeoutPolicyGet.setSelfGoverningTimeout(false);
|
|
channelTimeoutPolicyGet.setTimeout( channelTimeoutPolicyGet.getTimeout() ); //not needed really(!)
|
|
std::cout << "AND TIMEOUT RESTORED TO START VALUE OF " << channelTimeoutPolicyGet.getTimeout() << endl;
|
|
}
|
|
else {
|
|
std::cout << "Changing timeout for handle/pv "
|
|
<< handleArray[i] << "/" << (*it_handle).getPV() << " to: " <<
|
|
|
|
(channelTimeoutPolicyGet.getTimeout() +
|
|
channelTimeoutPolicyGet.getDeltaTimeout()*ntries) << " seconds" <<endl;
|
|
|
|
//modify timeout for handle
|
|
channelTimeoutPolicyGet.setTimeout( (channelTimeoutPolicyGet.getTimeout() +
|
|
channelTimeoutPolicyGet.getDeltaTimeout()*ntries));
|
|
}
|
|
|
|
if(MUTEX){cafeMutex.lock();}; //lock
|
|
handle_index.modify(it_handle, change_channelTimeoutPolicyGet(channelTimeoutPolicyGet));
|
|
if(MUTEX){cafeMutex.unlock();}; //unlock
|
|
|
|
if (status==ECAFE_TIMEOUT) {
|
|
std::cout << "CURRENT STATUS OF HANDLE: " << std::endl;
|
|
helper.printHandle(handleArray[i]);
|
|
}
|
|
}
|
|
|
|
if (status != ICAFE_NORMAL) {
|
|
//Check these in at end of routine
|
|
channelRequestStatusGet.setCallbackStatus (status);
|
|
|
|
channelRequestStatusGet.setCallbackKind(false, false); // NOT_INITIATED NOT_TRIGGERED
|
|
|
|
if(MUTEX){cafeMutex.lock();}; //lock
|
|
handle_index.modify(it_handle,
|
|
change_channelRequestStatusGet(channelRequestStatusGet));
|
|
|
|
if(MUTEX){cafeMutex.unlock();}; //unlock
|
|
}
|
|
|
|
if(MUTEX){cafeMutex.lock();}; //lock
|
|
handle_index.modify(it_handle, change_status(status));
|
|
if(MUTEX){cafeMutex.unlock();}; //unlock
|
|
|
|
|
|
if (status != ICAFE_NORMAL) {
|
|
cout << __METHOD__ << " status " << status << endl;
|
|
cout << "Returning ICAFE_WAITING_FOR_PREV_CALLBACK " << endl;
|
|
return ICAFE_WAITING_FOR_PREV_CALLBACK;
|
|
}
|
|
|
|
//ca_flush_io();
|
|
//return ICAFE_CALLBACK_NOT_YET_INVOKED;
|
|
}//if status
|
|
|
|
nelemPrevious=helper.getNelemNative(handleArray[i]);
|
|
helper.setNelemToRetrieveFromCache(handleArray[i],1);
|
|
}; //big if
|
|
|
|
|
|
|
|
dbr_short_t a1, a2; epicsTimeStamp ts1;
|
|
|
|
statusArray[i]=Instant::getCache(handleArray[i], _dbrType, &val[i],
|
|
a1, a2, ts1);
|
|
|
|
|
|
chtype channelType= _dbrType;
|
|
|
|
if (dbr_type_is_TIME(channelType)) {
|
|
ts[i].secPastEpoch= ts1.secPastEpoch; // default value if cache does not have timeStamp
|
|
ts[i].nsec = ts1.nsec; // default value if cache does not have timeStamp
|
|
}
|
|
if (dbr_type_is_TIME(channelType) || dbr_type_is_STS(channelType) ) {
|
|
alarmStatus [i] = a1; // default value if cache does not have alarmStatus
|
|
alarmSeverity[i] = a2; // default value if cache does not have alarmSeverity
|
|
}
|
|
|
|
if (statusArray[i] != ICAFE_NORMAL && !statusSet) {
|
|
gStatus=statusArray[i];
|
|
statusSet=true;
|
|
}
|
|
if(helper.getNelemNative(handleArray[i])!=1) {
|
|
helper.setNelemToRetrieveFromCache(handleArray[i],nelemPrevious);
|
|
};
|
|
|
|
} //for
|
|
return gStatus;
|
|
|
|
#undef __METHOD__
|
|
}
|
|
|
|
/**
|
|
* \brief Sends ca_put messages to IOC and waits until end before flushing
|
|
* \param handleArray input: Array of handles to conduit object
|
|
* \param nelem input: Size of array
|
|
* \param _dbrType input: chtype
|
|
* \param val input: Array of CTYPE
|
|
* \param statusArray output: Status array reporting from each get(handle)
|
|
* \return overallStatus ICAFE_NORMAL if all OK else the first ECAFE error encountered
|
|
*/
|
|
template <class CTYPE> int Instant<CTYPE>::set(const unsigned int *handleArray, const unsigned int nelem,
|
|
const chtype _dbrType, const CTYPE * val, int *statusArray) {
|
|
#define __METHOD__ \
|
|
"Instant::set(unsigned int *handleArray, unsigned int nelem, const chtype _dbrType, dbr_double_t * val, int *statusArray)"
|
|
|
|
int overallStatus=ICAFE_NORMAL; bool isGood=true;
|
|
|
|
unsigned int nelemPrevious=1;
|
|
|
|
for (unsigned int i=0; i<nelem; ++i) {
|
|
|
|
if(helper.getNelemNative(handleArray[i])!=1) {
|
|
|
|
//cout << "Native =" << helper.getNelemNative(handleArray[i]) << endl;
|
|
//cout << "Client =" << helper.getNelemClient(handleArray[i]) << endl;
|
|
//cout << "Request =" << helper.getNelemRequest(handleArray[i]) << endl;
|
|
//getNelemClient replaces getNelemNative, as this is required in e.g. SetScalarArray from MATLAB
|
|
//whenever an offset for a wf is given. e.g. offset 12, setnelm=20, gives client=20, request=32, native=256
|
|
nelemPrevious=helper.getNelemClient(handleArray[i]);
|
|
helper.setNelem(handleArray[i],1);
|
|
}
|
|
|
|
|
|
|
|
//OveridePolicy
|
|
//NO_WAIT, FLUSH_DESIGNATED_TO_CLIENT
|
|
|
|
ChannelRequestPolicy originalPol;
|
|
ChannelRequestPolicy pol;
|
|
PolicyHelper policyHelper;
|
|
policyHelper.getChannelRequestPolicyPut(handleArray[i], originalPol);
|
|
policyHelper.getChannelRequestPolicyPut(handleArray[i], pol);
|
|
pol.setWaitKind(NO_WAIT);
|
|
pol.setWhenToFlushSendBuffer(FLUSH_DESIGNATED_TO_CLIENT);
|
|
policyHelper.setChannelRequestPolicyPut(handleArray[i], pol);
|
|
statusArray[i]=Instant::set(handleArray[i], _dbrType, &val[i]);
|
|
if ( (statusArray[i] != ICAFE_NORMAL) && isGood) {
|
|
overallStatus=statusArray[i];
|
|
isGood=false;
|
|
}
|
|
//Return policy to previous
|
|
policyHelper.setChannelRequestPolicyPut(handleArray[i], originalPol);
|
|
|
|
if(helper.getNelemNative(handleArray[i])!=1) {
|
|
helper.setNelem(handleArray[i],nelemPrevious);
|
|
};
|
|
}
|
|
// flush now!
|
|
|
|
ca_flush_io();
|
|
|
|
return overallStatus;
|
|
#undef __METHOD__
|
|
};
|
|
|
|
|
|
/**
|
|
* \brief Data converted into datatype requested by client
|
|
* \param _handle input: handle
|
|
* \param _dbrType input: chtype
|
|
* \param _val input:array of CTYPE
|
|
* \param alarmStatus output
|
|
* \param alarmSeverity output
|
|
* \param ts output: epicsTimeStamp
|
|
* \param isCacheRequest: input: bool true if cached data requested
|
|
* \return status ICAFE_NORMAL if all OK else the first ECAFE error encountered
|
|
*/
|
|
template <class CTYPE> int Instant<CTYPE>::clientRequests(
|
|
const unsigned int _handle,
|
|
const chtype _dbrType, CTYPE * _val,
|
|
dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts, bool isCacheRequest) {
|
|
#define __METHOD__ "Instant::clientRequests(*it_handle, _dbrType, _val, alarmStatus, alarmSeverity, ts) "
|
|
|
|
ts.secPastEpoch= 0; // default value if cache does not have timeStamp
|
|
ts.nsec = 0; // default value if cache does not have timeStamp
|
|
alarmStatus =-1; // default value if cache does not have alarmStatus
|
|
alarmSeverity =-1; // default value if cache does not have alarmSeverity
|
|
|
|
//this is what the client is requesting!
|
|
|
|
int status=ICAFE_NORMAL; //Use local value!!
|
|
|
|
switch( _dbrType) {
|
|
|
|
case DBR_TIME_STRING: //0
|
|
status = renderString.get( _handle, (dbr_string_t *) _val, alarmStatus, alarmSeverity, ts, isCacheRequest);
|
|
break;
|
|
case DBR_TIME_SHORT: //1
|
|
status = renderShort.get ( _handle, (dbr_short_t *) _val, alarmStatus, alarmSeverity, ts, isCacheRequest);
|
|
break;
|
|
case DBR_TIME_FLOAT: //2
|
|
status = renderFloat.get ( _handle, (dbr_float_t *) _val, alarmStatus, alarmSeverity, ts, isCacheRequest);
|
|
break;
|
|
case DBR_TIME_ENUM: //3
|
|
status = renderEnum.get ( _handle, (dbr_enum_t *) _val, alarmStatus, alarmSeverity, ts, isCacheRequest);
|
|
break;
|
|
case DBR_TIME_CHAR: //4
|
|
status = renderChar.get ( _handle, (dbr_char_t *) _val, alarmStatus, alarmSeverity, ts, isCacheRequest);
|
|
break;
|
|
case DBR_TIME_LONG: //5
|
|
status = renderLong.get ( _handle, (dbr_long_t *) _val, alarmStatus, alarmSeverity, ts, isCacheRequest);
|
|
break;
|
|
case DBR_TIME_DOUBLE: //6
|
|
status = renderDouble.get( _handle, (dbr_double_t *) _val, alarmStatus, alarmSeverity, ts, isCacheRequest);
|
|
break;
|
|
case DBR_STS_STRING: //0
|
|
status = renderString.get( _handle, (dbr_string_t *) _val, alarmStatus, alarmSeverity, isCacheRequest);
|
|
break;
|
|
case DBR_STS_SHORT: //1
|
|
status = renderShort.get ( _handle, (dbr_short_t *) _val, alarmStatus, alarmSeverity, isCacheRequest);
|
|
break;
|
|
case DBR_STS_FLOAT: //2
|
|
status = renderFloat.get ( _handle, (dbr_float_t *) _val, alarmStatus, alarmSeverity, isCacheRequest);
|
|
break;
|
|
case DBR_STS_ENUM: //3
|
|
status = renderEnum.get ( _handle, (dbr_enum_t *) _val, alarmStatus, alarmSeverity, isCacheRequest);
|
|
break;
|
|
case DBR_STS_CHAR: //4
|
|
status = renderChar.get ( _handle, (dbr_char_t *) _val, alarmStatus, alarmSeverity, isCacheRequest);
|
|
break;
|
|
case DBR_STS_LONG: //5
|
|
status = renderLong.get ( _handle, (dbr_long_t *) _val, alarmStatus, alarmSeverity, isCacheRequest);
|
|
break;
|
|
case DBR_STS_DOUBLE: //6
|
|
status = renderDouble.get( _handle, (dbr_double_t *) _val, alarmStatus, alarmSeverity, isCacheRequest);
|
|
break;
|
|
case DBR_STRING: //0
|
|
status = renderString.get( _handle, (dbr_string_t *) _val, isCacheRequest);
|
|
break;
|
|
case DBR_SHORT: //1
|
|
status = renderShort.get ( _handle, (dbr_short_t *) _val, isCacheRequest);
|
|
break;
|
|
case DBR_FLOAT: //2
|
|
status = renderFloat.get ( _handle, (dbr_float_t *) _val, isCacheRequest);
|
|
break;
|
|
case DBR_ENUM: //3
|
|
status = renderEnum.get ( _handle, (dbr_enum_t *) _val, isCacheRequest);
|
|
break;
|
|
case DBR_CHAR: //4
|
|
status = renderChar.get ( _handle, (dbr_char_t *) _val, isCacheRequest);
|
|
break;
|
|
case DBR_LONG: //5
|
|
status = renderLong.get ( _handle, (dbr_long_t *) _val, isCacheRequest);
|
|
break;
|
|
case DBR_DOUBLE: //6
|
|
status = renderDouble.get( _handle, (dbr_double_t *) _val, isCacheRequest);
|
|
break;
|
|
|
|
default:
|
|
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cout << "Method does not support this DBR_TYPE: " << dbr_type_to_text(_dbrType)
|
|
<< " This line should never appear!" << endl;
|
|
break;
|
|
}
|
|
|
|
return status;
|
|
#undef __METHOD__
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
* \brief Data converted from client dataType into native datatype required by put Method
|
|
* \param _handle input: handle
|
|
* \param _dbrType input: chtype
|
|
* \param _val input:array of CTYPE
|
|
* \return status ICAFE_NORMAL if all OK else the first ECAFE error encountered
|
|
*/
|
|
|
|
template <class CTYPE> int Instant<CTYPE>::clientRequests(
|
|
const unsigned int _handle, const chtype _dbrType, const CTYPE * _val) {
|
|
#define __METHOD__ "Instant::clientRequests(*it_handle, _dbrType, _val)"
|
|
|
|
cafeConduit_set_by_handle & handle_index = cs.get<by_handle> ();
|
|
cafeConduit_set_by_handle::iterator it_handle;
|
|
|
|
status=ICAFE_NORMAL;
|
|
|
|
it_handle = handle_index.find(_handle);
|
|
|
|
if (it_handle != handle_index.end()) {
|
|
|
|
//union db_access_val * PVDataL;
|
|
//unsigned int nelem;
|
|
|
|
//chtype dbrTypeRequest_DataBuffer;
|
|
|
|
//PVDataL = (*it_handle).getPutBuffer ();
|
|
//nelem = (*it_handle).getChannelRequestMetaPrimitive().getNelem();
|
|
|
|
//dbrTypeRequest_DataBuffer = (*it_handle).getChannelRequestMetaPrimitive().getDbrDataType();
|
|
|
|
switch(_dbrType) {
|
|
case DBR_STRING:
|
|
status=renderString.putString(_handle, (dbr_string_t *) _val);
|
|
break;
|
|
case DBR_SHORT:
|
|
status=renderShort.put(_handle, (dbr_short_t *) _val, _dbrType );
|
|
break;
|
|
case DBR_FLOAT:
|
|
status=renderFloat.put(_handle, (dbr_float_t *) _val, _dbrType);
|
|
break;
|
|
case DBR_ENUM:
|
|
status=renderEnum.put(_handle, (dbr_enum_t *) _val, _dbrType);
|
|
break;
|
|
case DBR_CHAR:
|
|
status=renderChar.put(_handle, (dbr_char_t *) _val, _dbrType);
|
|
break;
|
|
case DBR_LONG:
|
|
status=renderLong.put(_handle, (dbr_long_t *) _val, _dbrType);
|
|
break;
|
|
case DBR_DOUBLE:
|
|
status=renderDouble.put(_handle, (dbr_double_t *) _val, _dbrType);
|
|
break;
|
|
default:
|
|
cout << "ERROR: " << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
|
|
cafeStatus.report(ECAFE_INVALID_SWITCH_CASE);
|
|
cout << "SWITCH STATMENT NOT MEANT FOR CAFE DATATYPE=" <<
|
|
_dbrType <<endl;
|
|
cout << "ABORTING DATA CONVERTION TO LOCAL putBuffer" << endl;
|
|
return ECAFE_INVALID_SWITCH_CASE;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
cafeStatus.report(ECAFE_INVALID_HANDLE);
|
|
return ECAFE_INVALID_HANDLE;
|
|
}
|
|
return status;
|
|
#undef __METHOD__
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* \brief Set followed by an immediate get
|
|
* \param handleSet input: handle
|
|
* \param dbrType input: const chtype
|
|
* \param valSet input: value to set
|
|
* \param valGet output: value to get
|
|
* \return ECA_NORMAL if all OK else first ECAFE error encountered, else ICAFE_SET_AND_GET_MISMATCH;
|
|
*/
|
|
template <class CTYPE> int Instant<CTYPE>::setAndGet(const unsigned int handleSet, const chtype dbrType, CTYPE valSet, CTYPE &valGet) {
|
|
#define __METHOD__ "Instant<CTYPE>::setAndGet(const unsigned int handleSet,const chtype dbrType, CTYPE valSet, CTYPE &valGet"
|
|
//CheckPolicy
|
|
|
|
CTYPE valGetA[1]; CTYPE valSetA[1];
|
|
|
|
valGetA[0]=0; valGet=0;
|
|
|
|
valSetA[0] = (CTYPE) valSet;
|
|
|
|
status=Instant::set(handleSet, dbrType, valSetA);
|
|
if (status==ICAFE_NORMAL) {
|
|
|
|
unsigned int nelemPrevious, nelemRequestedCheck=0;
|
|
unsigned int nelemRequested=1;
|
|
nelemPrevious=helper.getNelemClient(handleSet);
|
|
//Check the number of elements requested?
|
|
if (nelemPrevious>1) {
|
|
nelemRequestedCheck = helper.setNelem(handleSet,nelemRequested);
|
|
if (nelemRequestedCheck != nelemRequested) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: "
|
|
<< nelemPrevious << endl;
|
|
cout << "to: " << nelemRequested << " but got instead: "
|
|
<< nelemRequestedCheck << endl;
|
|
}
|
|
}
|
|
status=Instant::get(handleSet, dbrType, valGetA);
|
|
|
|
if (nelemPrevious>1) {
|
|
helper.setNelem(handleSet,nelemPrevious);
|
|
}
|
|
|
|
valGet=valGetA[0];
|
|
}
|
|
else {
|
|
return status;
|
|
}
|
|
if(valSet==valGet) {
|
|
return ICAFE_NORMAL;
|
|
}
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Process Variable = " << helper.getPVFromHandle(handleSet) << endl;
|
|
cout << "Set Value: " << valSet << " Get Value: " << valGet << endl;
|
|
return ICAFE_SET_AND_GET_MISMATCH;
|
|
#undef __METHOD__
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* \brief Set Channels followed by a corresponding readback of Channels \n
|
|
* Method verifies whether or not the set/readback values agree within the given tolerance and timeout \n
|
|
* Method returns with ECA_NORMAL as soon as a match is reached
|
|
* \param handleSet input: vector of handleSet
|
|
* \param dbrType input: chtype of set value
|
|
* \param valSet input: vector of CTYPE values to set
|
|
* \param handleMatch input: vector of handles of readback channel
|
|
* \param tolerance input: CTYPE of tolerance margin
|
|
* \param timeout input: double value; maximum time allowed for agreement to occur
|
|
* \param printFlag input: bool, set to true for diagnostics
|
|
* \return ECA_NORMAL if all OK, else first ECAFE error encountered, else ECAFE_TIMEOUT_SET_AND_MATCH
|
|
*/
|
|
template <class CTYPE> int Instant<CTYPE>::setAndMatchMany(vector<unsigned int> handleSet, chtype dbrType, vector<CTYPE> valSet, vector<unsigned int> handleMatch,
|
|
CTYPE tolerance, double timeout, bool printFlag){
|
|
#define __METHOD__ "Instant<CTYPE>::setAndMatchMany(vector<unsigned int>handleSet, chtype, vector<CTYPE>valSet, vector<unsigned int>handleMatch, tolerance, timeout, printFlag)"
|
|
|
|
|
|
Connect connect;
|
|
CAFEStatus cstat;
|
|
|
|
CTYPE valGetA[1]; CTYPE valSetA[1];
|
|
|
|
status=ICAFE_NORMAL;
|
|
|
|
if (handleSet.size() != handleMatch.size() ) {
|
|
return ECAFE_HANDLE_MISMATCH_SET_AND_MATCH;
|
|
}
|
|
|
|
if (handleSet.size() != valSet.size() ) {
|
|
return ECAFE_HANDLE_MISMATCH_SET_AND_MATCH;
|
|
}
|
|
|
|
for (size_t i=0; i< handleSet.size(); ++i) {
|
|
|
|
if (!helper.isChannelConnected(handleSet[i])
|
|
|| !helper.isChannelConnected(handleMatch[i])) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "NOT ALL CHANNELS CONNECTED: " << endl;
|
|
if (!helper.isChannelConnected(handleSet[i])) {helper.printHandle(handleSet[i]); status=helper.getStatus(handleSet[i]);}
|
|
if (!helper.isChannelConnected(handleMatch[i])) {helper.printHandle(handleMatch[i]); status=helper.getStatus(handleMatch[i]);}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if (status!=ICAFE_NORMAL) {return status;}
|
|
|
|
if(printFlag) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
}
|
|
|
|
|
|
for (size_t i=0; i< handleSet.size(); ++i) {
|
|
|
|
|
|
if (printFlag) {
|
|
|
|
if (dbrType==DBR_CHAR) {
|
|
cout << "SETTING PV=" << helper.getPVFromHandle(handleSet[i]) << " to " << (unsigned short) valSet[i] << endl;
|
|
}
|
|
else {
|
|
cout << "SETTING PV=" << helper.getPVFromHandle(handleSet[i]) << " to " << valSet[i] << endl;
|
|
}
|
|
|
|
cout << "READBACK PV=" << helper.getPVFromHandle(handleMatch[i])
|
|
<< " tolerance= " << fabs( (double) tolerance) << endl;
|
|
cout << "TIME ALLOWED FOR MATCH IS " << timeout << " (sec) " << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
vector<CTYPE> valSetUpper; vector<CTYPE> valSetLower;
|
|
|
|
vector<unsigned int> monitorID;
|
|
vector<int> statMonitor;
|
|
vector<unsigned short> nMonitors;
|
|
vector<CTYPE> valGet;
|
|
|
|
|
|
vector<unsigned int> nelemPreviousCache;
|
|
|
|
valSetUpper.reserve( handleSet.size());
|
|
|
|
|
|
valSetLower.reserve( handleSet.size());
|
|
monitorID.reserve( handleSet.size());
|
|
statMonitor.reserve( handleSet.size());
|
|
valGet.reserve( handleSet.size());
|
|
nMonitors.reserve( handleSet.size() );
|
|
|
|
|
|
nelemPreviousCache.reserve(handleSet.size());
|
|
|
|
|
|
for (size_t i=0; i< handleSet.size(); ++i) {
|
|
|
|
|
|
switch (dbrType) {
|
|
case DBR_LONG :
|
|
case DBR_SHORT :
|
|
case DBR_ENUM:
|
|
valSetUpper[i] = valSet[i] + abs((int)tolerance);
|
|
valSetLower[i] = valSet[i] - abs((int)tolerance);
|
|
break;
|
|
case DBR_CHAR :
|
|
valSetUpper[i] = (unsigned short) valSet[i] + abs((unsigned short) tolerance);
|
|
valSetLower[i] = (unsigned short) valSet[i] - abs((unsigned short) tolerance);
|
|
break;
|
|
case DBR_FLOAT:
|
|
case DBR_DOUBLE:
|
|
default:
|
|
|
|
valSetUpper[i] = (CTYPE) (valSet[i] + fabs((double)tolerance));
|
|
valSetLower[i] = (CTYPE) (valSet[i] - fabs((double)tolerance));
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
vector<MonitorPolicy> mpVMatch;
|
|
mpVMatch.clear();
|
|
|
|
helper.getMonitorPolicyVector(handleMatch[i], mpVMatch);
|
|
|
|
|
|
nMonitors[i]=mpVMatch.size();
|
|
|
|
monitorID[i]=0;
|
|
|
|
////valGetA[0][i]=0;
|
|
valGet[i]=0;
|
|
|
|
statMonitor[i]=ICAFE_NORMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (size_t i=0; i< handleSet.size(); ++i) {
|
|
|
|
//what is monitorpolicy??
|
|
if (nMonitors[i]==0) {
|
|
|
|
unsigned int _nelemPrevious, _nelemRequestedCheck=0;
|
|
unsigned int _nelemRequested=1;
|
|
_nelemPrevious=helper.getNelemClient(handleMatch[i]);
|
|
//Check the number of elements requested?
|
|
if (_nelemPrevious>1) {
|
|
_nelemRequestedCheck = helper.setNelem(handleMatch[i],_nelemRequested); //change handleSet to handleMatch 23/3/17
|
|
if (_nelemRequestedCheck != _nelemRequested) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: "
|
|
<< _nelemPrevious << endl;
|
|
cout << "to: " << _nelemRequested << " but got instead: "
|
|
<< _nelemRequestedCheck << endl;
|
|
}
|
|
}
|
|
|
|
//first do get to update cache before monitor starts
|
|
status=Instant::get(handleMatch[i], dbrType, valGetA);
|
|
|
|
valGet[i]=valGetA[0];
|
|
|
|
if (_nelemPrevious>1) {
|
|
helper.setNelem(handleMatch[i],_nelemPrevious); //change handleSet to handleMatch 23/3/17
|
|
}
|
|
|
|
|
|
if (status!=ICAFE_NORMAL) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cstat.report(status);
|
|
}
|
|
|
|
ChannelWhenToFlushSendBufferPolicyKind whenKind=
|
|
connect.channelMonitorPolicy.getWhenToFlushSendBuffer();
|
|
connect.channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC);
|
|
|
|
statMonitor[i]=connect.monitorStart(handleMatch[i], monitorID[i]);
|
|
|
|
if (statMonitor[i]!=ICAFE_NORMAL) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cstat.report(statMonitor[i]);
|
|
}
|
|
else {
|
|
if(printFlag) {cout << "MONITOR NOW IN PLACE FOR READBACK CHANNEL " << helper.getPVFromHandle(handleMatch[i]) << " WITH ID=" << monitorID[i] << endl;}
|
|
}
|
|
//revert to previous
|
|
if (whenKind != FLUSH_AUTOMATIC) {
|
|
connect.channelMonitorPolicy.setWhenToFlushSendBuffer(whenKind);
|
|
}
|
|
|
|
} //if nMonitors
|
|
|
|
////valSetA[0][i]=valSet[i];
|
|
|
|
//set No of Elements to 1
|
|
|
|
unsigned int nelemPrevious, nelemRequestedCheck=0;
|
|
unsigned int nelemRequested=1;
|
|
|
|
nelemPrevious=helper.getNelemClient(handleSet[i]);
|
|
//Check the number of elements requested?
|
|
if (nelemPrevious>1) {
|
|
nelemRequestedCheck = helper.setNelem(handleSet[i],nelemRequested);
|
|
if (nelemRequestedCheck != nelemRequested) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: "
|
|
<< nelemPrevious << endl;
|
|
cout << "to: " << nelemRequested << " but got instead: "
|
|
<< nelemRequestedCheck << endl;
|
|
}
|
|
}
|
|
|
|
|
|
//policy set synchronous
|
|
ChannelRequestPolicy polPrevious, polNow;
|
|
|
|
policyHelper.getChannelRequestPolicyPut(handleSet[i], polPrevious);
|
|
|
|
polNow.setMethodKind(WITHOUT_CALLBACK);
|
|
polNow.setWaitKind(WAIT);
|
|
polNow.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC);
|
|
|
|
policyHelper.setChannelRequestPolicyPut(handleSet[i], polNow);
|
|
|
|
|
|
valSetA[0] = (CTYPE) valSet[i];
|
|
|
|
status=set(handleSet[i], dbrType, valSetA);
|
|
|
|
if (status!=ICAFE_NORMAL) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cstat.report(status);
|
|
}
|
|
|
|
policyHelper.setChannelRequestPolicyPut(handleSet[i], polPrevious);
|
|
|
|
unsigned int nelemPreviousCheck=nelemPrevious;
|
|
nelemRequested=1;
|
|
//Switch back to previous value
|
|
//if (nelemPrevious>1) {
|
|
if(helper.getNelemRequest(handleSet[i])!= nelemPrevious) {
|
|
nelemPreviousCheck= helper.setNelem(handleSet[i],nelemPrevious);
|
|
if (nelemPreviousCheck != nelemPrevious) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: "
|
|
<< nelemRequested << endl;
|
|
cout << "to the previous: " << nelemPrevious << " but got instead: "
|
|
<< nelemPreviousCheck << endl;
|
|
}
|
|
}
|
|
|
|
|
|
//No of elements to get from Cache
|
|
|
|
nelemPreviousCheck=0;
|
|
nelemRequested=1; nelemRequestedCheck=0;
|
|
nelemPreviousCache[i]=helper.getNelemRequest(handleMatch[i]);
|
|
|
|
//Check the number of elements requested
|
|
//See set and Match; this needs to be checked
|
|
//Avoid problem when readback channel is the very same as the set(!)
|
|
if (nelemPreviousCache[i]>0 && helper.getNelemNative(handleMatch[i])>1) {
|
|
nelemRequestedCheck = helper.setNelemToRetrieveFromCache(handleMatch[i],nelemRequested);
|
|
if (nelemRequestedCheck != nelemRequested) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: "
|
|
<< nelemPreviousCache[i] << endl;
|
|
cout << "to: " << nelemRequested << " but got instead: "
|
|
<< nelemRequestedCheck << endl;
|
|
}
|
|
}
|
|
|
|
|
|
} //for size_t
|
|
|
|
//start time
|
|
|
|
|
|
|
|
|
|
double timeElapsed=0; double timeElapsed2=0;
|
|
double timeElapsedBase=0;
|
|
using namespace boost::posix_time;
|
|
|
|
ptime timeStart(microsec_clock::local_time());
|
|
|
|
|
|
for (size_t i=0; i< handleSet.size(); ++i) {
|
|
|
|
|
|
|
|
valGetA[0]=0;
|
|
|
|
status=Instant::getCache(handleMatch[i], dbrType, valGetA);
|
|
|
|
valGet[i]=valGetA[0];
|
|
|
|
|
|
|
|
if (status !=ICAFE_NORMAL) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cstat.report(status);
|
|
}
|
|
|
|
///valGet[i]=valGetA[0][i];
|
|
if (dbrType==DBR_CHAR) {valGet[i] = (unsigned short) valGetA[0];}
|
|
|
|
if(printFlag) {
|
|
//cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
if (dbrType==DBR_CHAR) {
|
|
cout << "Current Cached Value = " << (unsigned short) valGet[i] << endl;
|
|
cout << "Lower/Upper Target Values = " << (unsigned short) valSetLower[i] << " and " << (unsigned short) valSetUpper[i] << endl;
|
|
}
|
|
else {
|
|
cout << "Current Cached Value = " << valGet[i] << endl;
|
|
cout << "Lower/Upper Target Values = " << valSetLower[i] << " and " << valSetUpper[i] << endl;
|
|
}
|
|
}
|
|
|
|
} //for size_t
|
|
|
|
|
|
|
|
ptime timeEnd(microsec_clock::local_time());
|
|
time_duration duration(timeEnd-timeStart);
|
|
timeElapsed= (double) duration.total_microseconds()/1000000.0;
|
|
|
|
|
|
for (size_t i=0; i< handleSet.size(); ++i) {
|
|
|
|
|
|
while ( (valGet[i]>valSetUpper[i] || valGet[i]<valSetLower[i] )
|
|
&& timeElapsed < timeout ) {
|
|
|
|
valGetA[0]=0;
|
|
|
|
status=Instant::getCache(handleMatch[i], dbrType, valGetA);
|
|
|
|
valGet[i]=valGetA[0];
|
|
|
|
|
|
//cout <<"Cached value " << valGet[i] << endl;
|
|
|
|
|
|
if (dbrType==DBR_CHAR) {valGet[i] = (unsigned short) valGetA[0];}
|
|
|
|
//cout << valSetUpper[i] << " U/L " << valSetLower[i] << endl;
|
|
|
|
ptime timeEnd(microsec_clock::local_time());
|
|
time_duration duration(timeEnd-timeStart);
|
|
timeElapsed= (double) duration.total_microseconds()/1000000.0;
|
|
|
|
timeElapsed2=timeElapsed-timeElapsedBase;
|
|
|
|
if (printFlag && timeElapsed2>1 && status==ICAFE_NORMAL) {
|
|
|
|
|
|
|
|
for (size_t ij=0; ij< handleMatch.size(); ++ij) {
|
|
status=Instant::getCache(handleMatch[ij], dbrType, valGetA);
|
|
valGet[ij]=valGetA[0];
|
|
if (valGet[ij]>valSetUpper[ij] || valGet[ij]<valSetLower[ij]) {
|
|
|
|
if (dbrType==DBR_CHAR) {
|
|
|
|
cout << "REPORTING " << helper.getPVFromHandle(handleSet[ij])
|
|
<< " SET VALUE=" << (unsigned short) valSet[ij]
|
|
<< "; READBACK " << helper.getPVFromHandle(handleMatch[ij])
|
|
<< " HAS CURRENT VALUE=" << (unsigned short) valGet[ij]
|
|
<< " TimeElapsed " << timeElapsed << " (sec) " << endl;
|
|
}
|
|
else {
|
|
cout << "REPORTING " << helper.getPVFromHandle(handleSet[ij])
|
|
<< " SET VALUE=" << valSet[ij]
|
|
<< "; READBACK " << helper.getPVFromHandle(handleMatch[ij])
|
|
<< " HAS CURRENT VALUE=" << valGet[ij]
|
|
<< " TimeElapsed " << timeElapsed << " (sec) " << endl;
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
timeElapsedBase=timeElapsed;
|
|
|
|
//cout << "REPORTING ON CHANNEL " << helper.getPVFromHandle(handleSet[i]) << " SET VALUE=" << valSet[i] << " // CURRENT READBACK VALUE=" << valGet[i]
|
|
// << " TimeElapsed " << timeElapsed << " (sec) " << endl;
|
|
//timeElapsedBase=timeElapsed;
|
|
|
|
}
|
|
|
|
|
|
#if HAVE_BOOST_THREAD
|
|
boost::this_thread::sleep_for(boost::chrono::microseconds(20));
|
|
#else
|
|
#if HAVE_LINUX
|
|
usleep(20);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
} //for size_t
|
|
|
|
|
|
|
|
if (timeout <=timeElapsed ) {
|
|
cout << "*****TIMEOUT REACHED****** AFTER " << timeout << " (sec) " << endl;
|
|
cout << "*****NOT ALL READBACK CHANNELS REACHED THEIR DESIRED VALUES WITHIN THE GIVEN TOLERANCE AND TIME PERIOD*****" << endl;
|
|
status=ECAFE_TIMEOUT_SET_AND_MATCH;
|
|
}
|
|
else {
|
|
|
|
for (size_t i=0; i< handleSet.size(); ++i) {
|
|
|
|
//if (printFlag) {cout << "MONITOR STARTED WITH ID/2-/=" << monitorID[i] << endl;}
|
|
if (printFlag) {
|
|
valGetA[0]=0;
|
|
status=Instant::getCache(handleMatch[i], dbrType, valGetA);
|
|
valGet[i]=valGetA[0];
|
|
if (dbrType==DBR_CHAR) {
|
|
cout << "GAME SET AND MATCH: " << helper.getPVFromHandle(handleSet[i]) << " SET VALUE= " << (unsigned short) valSet[i]
|
|
<< " // " << helper.getPVFromHandle(handleMatch[i]) << " READBACK VALUE= " << (unsigned short) valGet[i] //pvdMatch.getAsDouble()
|
|
<< " TimeElapsed " << timeElapsed << " (sec) " << endl;
|
|
}
|
|
else {
|
|
cout << "GAME SET AND MATCH: " << helper.getPVFromHandle(handleSet[i]) << " SET VALUE= " << valSet[i]
|
|
<< " // " << helper.getPVFromHandle(handleMatch[i]) << " READBACK VALUE= " << valGet[i] //pvdMatch.getAsDouble()
|
|
<< " TimeElapsed " << timeElapsed << " (sec) " << endl;
|
|
|
|
}
|
|
}
|
|
|
|
} //for
|
|
}
|
|
//
|
|
|
|
for (size_t i=0; i< handleSet.size(); ++i) {
|
|
unsigned int nelemPreviousCheck;
|
|
unsigned int nelemRequested=1;
|
|
|
|
|
|
if (nelemPreviousCache[i]>1) {
|
|
nelemPreviousCheck= helper.setNelemToRetrieveFromCache(handleMatch[i],nelemPreviousCache[i]);
|
|
if (nelemPreviousCheck != nelemPreviousCache[i]) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: "
|
|
<< nelemRequested << endl;
|
|
cout << "to the previous: " << nelemPreviousCache[i] << " but got instead: "
|
|
<< nelemPreviousCheck << endl;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (nMonitors[i]==0 && statMonitor[i]==ICAFE_NORMAL && printFlag) {
|
|
cout << "MONITOR NOW STOPPED FOR READBACK CHANNEL " << helper.getPVFromHandle(handleMatch[i]) << " WITH ID =" << monitorID[i] << endl;
|
|
int statm;
|
|
statm=connect.monitorStop(handleMatch[i], monitorID[i]);
|
|
if (status==ICAFE_NORMAL) {status=statm;}
|
|
}
|
|
|
|
} //for
|
|
|
|
|
|
return status;
|
|
#undef __METHOD__
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* \brief Set Channel 1 followed by a readback of Channel 2 \n
|
|
* Method verifies whether or not the 2 values agree within the given tolerance and timeout \n
|
|
* Method returns with ECA_NORMAL as soon as a match is reached
|
|
* \param handleSet input: handleSet
|
|
* \param dbrType input: chtype of set value
|
|
* \param valSet input: CTYPE value to set
|
|
* \param handleMatch input: handle of readback channel
|
|
* \param tolerance input: CTYPE of tolerance margin
|
|
* \param timeout input: double value; maximum time allowed for agreement to occur
|
|
* \param printFlag input: bool, set to true for diagnostics
|
|
* \return ECA_NORMAL if all OK else first ECAFE error encountered
|
|
*/
|
|
template <class CTYPE> int Instant<CTYPE>::setAndMatch(const unsigned int handleSet, const chtype dbrType, CTYPE valSet, const unsigned int handleMatch,
|
|
CTYPE tolerance, double timeout, bool printFlag){
|
|
#define __METHOD__ "Instant<CTYPE>::setAndMatch(handleSet, dbrType, valSet, handleMatch, tolerance, timeout, printFlag)"
|
|
//check both handles exists before proceeding
|
|
|
|
Connect connect;
|
|
CAFEStatus cstat;
|
|
|
|
if (!helper.isChannelConnected(handleSet)
|
|
|| !helper.isChannelConnected(handleMatch)) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "NOT ALL CHANNELS CONNECTED: " << endl;
|
|
if (!helper.isChannelConnected(handleSet)) {helper.printHandle(handleSet); return helper.getStatus(handleSet);}
|
|
if (!helper.isChannelConnected(handleMatch)) {helper.printHandle(handleMatch); return helper.getStatus(handleMatch);}
|
|
}
|
|
|
|
if (printFlag) {
|
|
|
|
if (dbrType==DBR_CHAR) {
|
|
cout << "SETTING PV=" << helper.getPVFromHandle(handleSet) << " to " << (unsigned short) valSet << endl;
|
|
}
|
|
else {
|
|
cout << "SETTING PV=" << helper.getPVFromHandle(handleSet) << " to " << valSet << endl;
|
|
}
|
|
cout << "READBACK PV=" << helper.getPVFromHandle(handleMatch)
|
|
<< " tolerance= " << fabs((double)tolerance) << endl;
|
|
cout << "TIME ALLOWED FOR MATCH " << timeout << " (sec) " << endl;
|
|
}
|
|
|
|
vector<MonitorPolicy> mpVMatch;
|
|
helper.getMonitorPolicyVector(handleMatch, mpVMatch);
|
|
|
|
unsigned short nMonitors=mpVMatch.size();
|
|
|
|
|
|
CTYPE valSetUpper; CTYPE valSetLower;
|
|
|
|
|
|
switch (dbrType) {
|
|
case DBR_LONG :
|
|
case DBR_SHORT :
|
|
case DBR_ENUM:
|
|
valSetUpper = valSet + abs((int)tolerance);
|
|
valSetLower = valSet - abs((int)tolerance);
|
|
break;
|
|
case DBR_CHAR :
|
|
valSetUpper = (unsigned short) valSet + abs((unsigned short) tolerance);
|
|
valSetLower = (unsigned short) valSet - abs((unsigned short) tolerance);
|
|
break;
|
|
case DBR_FLOAT:
|
|
case DBR_DOUBLE:
|
|
default:
|
|
valSetUpper = (CTYPE) (valSet + fabs((double)tolerance));
|
|
valSetLower = (CTYPE) (valSet - fabs((double)tolerance));
|
|
break;
|
|
}
|
|
|
|
|
|
CTYPE valGetA[1]={0};
|
|
CTYPE valGet=valGetA[0];
|
|
|
|
int statMonitor=ICAFE_NORMAL;
|
|
|
|
unsigned int monitorIDis=0;
|
|
|
|
//what is monitorpolicy??
|
|
if (nMonitors==0) {
|
|
|
|
unsigned int _nelemPrevious, _nelemRequestedCheck=0;
|
|
unsigned int _nelemRequested=1;
|
|
_nelemPrevious=helper.getNelemClient(handleMatch);
|
|
//Check the number of elements requested?
|
|
if (_nelemPrevious>1) {
|
|
_nelemRequestedCheck = helper.setNelem(handleMatch,_nelemRequested); ////change handleSet to handleMatch 23/3/17
|
|
if (_nelemRequestedCheck != _nelemRequested) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: "
|
|
<< _nelemPrevious << endl;
|
|
cout << "to: " << _nelemRequested << " but got instead: "
|
|
<< _nelemRequestedCheck << endl;
|
|
}
|
|
}
|
|
|
|
//first do get to update cache before monitor starts
|
|
status=Instant::get(handleMatch, dbrType, valGetA);
|
|
//valGet=valGetA[0];
|
|
|
|
|
|
if (_nelemPrevious>1) {
|
|
helper.setNelem(handleMatch,_nelemPrevious); ////change handleSet to handleMatch 23/3/17
|
|
}
|
|
|
|
if (status!=ICAFE_NORMAL) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cstat.report(status);
|
|
}
|
|
|
|
ChannelWhenToFlushSendBufferPolicyKind whenKind=
|
|
connect.channelMonitorPolicy.getWhenToFlushSendBuffer();
|
|
connect.channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC);
|
|
|
|
statMonitor=connect.monitorStart(handleMatch, monitorIDis);
|
|
|
|
if (statMonitor!=ICAFE_NORMAL) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cstat.report(statMonitor);
|
|
}
|
|
else {
|
|
if(printFlag) {cout << "MONITOR STARTED WITH ID=" << monitorIDis<< endl;}
|
|
}
|
|
//revert to previous
|
|
if (whenKind != FLUSH_AUTOMATIC) {
|
|
connect.channelMonitorPolicy.setWhenToFlushSendBuffer(whenKind);
|
|
}
|
|
}
|
|
|
|
CTYPE valSetA[1]; valSetA[0]=valSet;
|
|
|
|
//set No of Elements to 1
|
|
|
|
unsigned int nelemPrevious, nelemRequestedCheck=0;
|
|
unsigned int nelemRequested=1;
|
|
nelemPrevious=helper.getNelemClient(handleSet);
|
|
//Check the number of elements requested?
|
|
if (nelemPrevious>1) {
|
|
nelemRequestedCheck = helper.setNelem(handleSet,nelemRequested);
|
|
if (nelemRequestedCheck != nelemRequested) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: "
|
|
<< nelemPrevious << endl;
|
|
cout << "to: " << nelemRequested << " but got instead: "
|
|
<< nelemRequestedCheck << endl;
|
|
}
|
|
}
|
|
|
|
//policy set synchronous
|
|
ChannelRequestPolicy polPrevious, polNow;
|
|
|
|
policyHelper.getChannelRequestPolicyPut(handleSet, polPrevious);
|
|
|
|
polNow.setMethodKind(WITHOUT_CALLBACK);
|
|
polNow.setWaitKind(WAIT);
|
|
polNow.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC);
|
|
|
|
policyHelper.setChannelRequestPolicyPut(handleSet, polNow);
|
|
|
|
status=set(handleSet, dbrType, valSetA);
|
|
|
|
if (status!=ICAFE_NORMAL) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cstat.report(status);
|
|
}
|
|
|
|
policyHelper.setChannelRequestPolicyPut(handleSet, polPrevious);
|
|
|
|
unsigned int nelemPreviousCheck=nelemPrevious;
|
|
nelemRequested=1;
|
|
//Switch back to previous value
|
|
//if (nelemPrevious>1) {
|
|
if(helper.getNelemRequest(handleSet)!= nelemPrevious) {
|
|
nelemPreviousCheck= helper.setNelem(handleSet,nelemPrevious);
|
|
if (nelemPreviousCheck != nelemPrevious) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: "
|
|
<< nelemRequested << endl;
|
|
cout << "to the previous: " << nelemPrevious << " but got instead: "
|
|
<< nelemPreviousCheck << endl;
|
|
}
|
|
}
|
|
|
|
|
|
//start time
|
|
|
|
double timeElapsed=0; double timeElapsed2=0;
|
|
double timeElapsedBase=0;
|
|
using namespace boost::posix_time;
|
|
|
|
ptime timeStart(microsec_clock::local_time());
|
|
|
|
// PVDataHolder pvdMatch;
|
|
// status=getCache(handleMatch, dbrType, pvdMatch);
|
|
|
|
|
|
//No of elements to get from Cache
|
|
|
|
nelemPreviousCheck=0;
|
|
nelemRequested=1; nelemRequestedCheck=0;
|
|
nelemPrevious=helper.getNelemRequest(handleMatch);
|
|
|
|
|
|
|
|
//Check the number of elements requested
|
|
if (nelemPrevious>0) {
|
|
nelemRequestedCheck = helper.setNelemToRetrieveFromCache(handleMatch,nelemRequested);
|
|
if (nelemRequestedCheck != nelemRequested) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: "
|
|
<< nelemPrevious << endl;
|
|
cout << "to: " << nelemRequested << " but got instead: "
|
|
<< nelemRequestedCheck << endl;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
status=Instant::getCache(handleMatch, dbrType, valGetA);
|
|
|
|
|
|
|
|
|
|
///if (dbrType==DBR_CHAR) {valGet = (unsigned short) valGetA[0];}
|
|
|
|
|
|
|
|
if (status !=ICAFE_NORMAL) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cstat.report(status);
|
|
}
|
|
|
|
|
|
|
|
|
|
if(printFlag) {
|
|
//cout << __METHOD__ << endl;
|
|
cout << "Current Cached Value = " ;
|
|
if (dbrType==DBR_CHAR) {
|
|
cout << (unsigned short) valGetA[0] << cout << endl;
|
|
cout << "Lower/Upper Target Values = " << (unsigned short) valSetLower << " and " << (unsigned short) valSetUpper << endl;
|
|
}
|
|
else {
|
|
cout << valGetA[0] << endl;
|
|
cout << "Lower/Upper Target Values = " << valSetLower << " and " << valSetUpper << endl;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ptime timeEnd(microsec_clock::local_time());
|
|
time_duration duration(timeEnd-timeStart);
|
|
timeElapsed= (double) duration.total_microseconds()/1000000.0;
|
|
|
|
|
|
|
|
if (dbrType==DBR_CHAR) {valGet= (unsigned short) valGetA[0];}
|
|
|
|
else { valGet=valGetA[0];}
|
|
|
|
|
|
|
|
while ( (valGet>valSetUpper || valGet<valSetLower)
|
|
|
|
//while ( (pvdMatch.getAsDouble()>valSetUpper || pvdMatch.getAsDouble()<valSetLower)
|
|
&& timeElapsed < timeout ) {
|
|
//status=getCache(handleMatch, dbrType, pvdMatch);
|
|
|
|
/*
|
|
//Check the number of elements requested - again; in case overwritten by Monitor
|
|
if (nelemPrevious>1) {
|
|
nelemRequestedCheck = helper.setNelemToRetrieveFromCache(handleMatch,nelemRequested);
|
|
if (nelemRequestedCheck != nelemRequested) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: "
|
|
<< nelemPrevious << endl;
|
|
cout << "to: " << nelemRequested << " but got instead: "
|
|
<< nelemRequestedCheck << endl;
|
|
}
|
|
}
|
|
*/
|
|
|
|
status=Instant::getCache(handleMatch, dbrType, valGetA);
|
|
|
|
valGet=valGetA[0];
|
|
|
|
if (dbrType==DBR_CHAR) {valGet = (unsigned short) valGetA[0];}
|
|
//cout << "getCache(handleMatch, dbrType, valGetA) = " << valGet << endl;
|
|
//cout << valSetUpper << " U/L " << valSetLower << endl;
|
|
|
|
ptime timeEnd(microsec_clock::local_time());
|
|
time_duration duration(timeEnd-timeStart);
|
|
timeElapsed= (double) duration.total_microseconds()/1000000.0;
|
|
|
|
timeElapsed2=timeElapsed-timeElapsedBase;
|
|
|
|
if (printFlag && timeElapsed2>1 && status==ICAFE_NORMAL) {
|
|
|
|
if (dbrType==DBR_CHAR) {
|
|
cout << "SET VALUE " << (unsigned short) valSet << " CURRENT VALUE " << (unsigned short) valGetA[0]
|
|
<< " TimeElapsed " << timeElapsed << " (sec) " << endl;
|
|
} else {
|
|
cout << "SET VALUE " << valSet << " CURRENT VALUE " << valGetA[0] //pvdMatch.getAsDouble()
|
|
<< " TimeElapsed " << timeElapsed << " (sec) " << endl;
|
|
}
|
|
|
|
|
|
timeElapsedBase=timeElapsed;
|
|
|
|
}
|
|
|
|
|
|
#if HAVE_BOOST_THREAD
|
|
boost::this_thread::sleep_for(boost::chrono::microseconds(20));
|
|
#else
|
|
#if HAVE_LINUX
|
|
usleep(20);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
|
|
if (timeout <=timeElapsed ) {
|
|
cout << "*****TIMEOUT REACHED****** AFTER " << timeout << " (sec) " << endl;
|
|
|
|
status=ECAFE_TIMEOUT_SET_AND_MATCH;
|
|
}
|
|
else {
|
|
if (printFlag) {
|
|
status=Instant::getCache(handleMatch, dbrType, valGetA);
|
|
if (dbrType==DBR_CHAR) {
|
|
cout << "GAME SET AND MATCH: SET VALUE= " << (unsigned short) valSet
|
|
<< " LAST VALUE READ= " << (unsigned short) valGetA[0] //pvdMatch.getAsDouble()
|
|
<< " TimeElapsed " << timeElapsed << " (sec) " << endl;
|
|
}
|
|
else {
|
|
cout << "GAME SET AND MATCH: SET VALUE= " << valSet << " LAST VALUE READ= " << valGetA[0] //pvdMatch.getAsDouble()
|
|
<< " TimeElapsed " << timeElapsed << " (sec) " << endl;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nelemPrevious>1) {
|
|
nelemPreviousCheck= helper.setNelemToRetrieveFromCache(handleMatch,nelemPrevious);
|
|
if (nelemPreviousCheck != nelemPrevious) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: "
|
|
<< nelemRequested << endl;
|
|
cout << "to the previous: " << nelemPrevious << " but got instead: "
|
|
<< nelemPreviousCheck << endl;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nMonitors==0 && statMonitor==ICAFE_NORMAL) {
|
|
if (monitorIDis !=0 ) {
|
|
cout << "STOPPED MONITOR WITH ID =" << monitorIDis << endl;
|
|
int statm;
|
|
statm=connect.monitorStop(handleMatch, monitorIDis);
|
|
|
|
if (status==ICAFE_NORMAL) {status=statm;}
|
|
}
|
|
}
|
|
|
|
return status;
|
|
#undef __METHOD__
|
|
}
|
|
|
|
|
|
/**
|
|
* \brief Set Channel followed by a corresponding readback of Channel \n
|
|
* Method verifies whether or not the set/readback values agree within the given tolerance and timeout \n
|
|
* Method returns with ECA_NORMAL as soon as a match is reached
|
|
* \param dbrType input: chtype of set value
|
|
* \param valSet input: CTYPE value to set
|
|
* \param handleMatch input: handle of readback channel
|
|
* \param tolerance input: CTYPE of tolerance margin
|
|
* \param timeout input: double value; maximum time allowed for agreement to occur
|
|
* \param printFlag input: bool, set to true for diagnostics
|
|
* \return ECA_NORMAL if all OK else first ECAFE error encountered
|
|
*/
|
|
template <class CTYPE> int Instant<CTYPE>::match(const chtype dbrType, CTYPE valSet, unsigned int handleMatch,
|
|
CTYPE tolerance, double timeout, bool printFlag){
|
|
#define __METHOD__ "Instant<CTYPE>::match(const chtype dbrType, CTYPE valSet, unsigned int handleMatch, \
|
|
CTYPE tolerance,double timeout, bool printFlag)"
|
|
|
|
vector<CTYPE> valSetV;
|
|
vector<unsigned int>handleMatchV;
|
|
valSetV.reserve(1);
|
|
handleMatchV.reserve(1);
|
|
valSetV.push_back(valSet);
|
|
handleMatchV.push_back(handleMatch);
|
|
|
|
return matchMany(dbrType, valSetV, handleMatchV, tolerance, timeout, printFlag);
|
|
#undef __METHOD__
|
|
}
|
|
|
|
|
|
/**
|
|
* \brief Set Channels followed by a corresponding readback of Channels \n
|
|
* Method verifies whether or not the set/readback values agree within the given tolerance and timeout \n
|
|
* Method returns with ECA_NORMAL as soon as a match is reached
|
|
* \param dbrType input: chtype of set value
|
|
* \param valSet input: vector of CTYPE values to set
|
|
* \param handleMatch input: vector of handles of readback channel
|
|
* \param tolerance input: CTYPE of tolerance margin
|
|
* \param timeout input: double value; maximum time allowed for agreement to occur
|
|
* \param printFlag input: bool, set to true for diagnostics
|
|
* \return ECA_NORMAL if all OK else first ECAFE error encountered
|
|
*/
|
|
template <class CTYPE> int Instant<CTYPE>::matchMany(const chtype dbrType, vector<CTYPE> valSet, vector<unsigned int> handleMatch,
|
|
CTYPE tolerance, double timeout, bool printFlag){
|
|
#define __METHOD__ "Instant<CTYPE>::matchMany(const chtype dbrType, vector<CTYPE>valSet, vector<unsigned int>handleMatch, \
|
|
CTYPE tolerance, double timeout, bool printFlag)"
|
|
|
|
|
|
Connect connect;
|
|
CAFEStatus cstat;
|
|
|
|
CTYPE valGetA[1];
|
|
////CTYPE valSetA[1];
|
|
|
|
status=ICAFE_NORMAL;
|
|
|
|
|
|
if (handleMatch.size() != valSet.size() ) {
|
|
return ECAFE_HANDLE_MISMATCH_SET_AND_MATCH;
|
|
}
|
|
|
|
for (size_t i=0; i< handleMatch.size(); ++i) {
|
|
if ( !helper.isChannelConnected(handleMatch[i])) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "NOT ALL CHANNELS CONNECTED: " << endl;
|
|
|
|
helper.printHandle(handleMatch[i]);
|
|
status=helper.getStatus(handleMatch[i]);
|
|
}
|
|
}
|
|
|
|
|
|
if (status!=ICAFE_NORMAL) {return status;}
|
|
|
|
|
|
for (size_t i=0; i< handleMatch.size(); ++i) {
|
|
if (printFlag) {
|
|
cout << "SET VALUE IS = " << valSet[i] << endl;
|
|
cout << "READBACK PV=" << helper.getPVFromHandle(handleMatch[i])
|
|
<< " tolerance= " << fabs((double)tolerance) << endl;
|
|
cout << "TIME ALLOWED FOR MATCH IS " << timeout << " (sec) " << endl;
|
|
}
|
|
}
|
|
|
|
|
|
vector<CTYPE> valSetUpper; vector<CTYPE> valSetLower;
|
|
|
|
vector<unsigned int> monitorID;
|
|
vector<int> statMonitor;
|
|
vector<unsigned short> nMonitors;
|
|
vector<CTYPE> valGet;
|
|
|
|
vector<unsigned int> nelemPreviousCache;
|
|
|
|
valSetUpper.reserve( handleMatch.size());
|
|
valSetLower.reserve( handleMatch.size());
|
|
monitorID.reserve( handleMatch.size());
|
|
statMonitor.reserve( handleMatch.size());
|
|
valGet.reserve( handleMatch.size());
|
|
nMonitors.reserve( handleMatch.size() );
|
|
|
|
nelemPreviousCache.reserve(handleMatch.size());
|
|
|
|
for (size_t i=0; i< handleMatch.size(); ++i) {
|
|
|
|
switch (dbrType) {
|
|
case DBR_LONG :
|
|
case DBR_SHORT :
|
|
case DBR_ENUM:
|
|
valSetUpper[i] = valSet[i] + abs((int)tolerance);
|
|
valSetLower[i] = valSet[i] - abs((int)tolerance);
|
|
break;
|
|
case DBR_CHAR :
|
|
valSetUpper[i] = (unsigned short) valSet[i] + abs((unsigned short) tolerance);
|
|
valSetLower[i] = (unsigned short) valSet[i] - abs((unsigned short) tolerance);
|
|
break;
|
|
case DBR_FLOAT:
|
|
case DBR_DOUBLE:
|
|
default:
|
|
|
|
valSetUpper[i] = (CTYPE) (valSet[i] + fabs((double)tolerance));
|
|
valSetLower[i] = (CTYPE) (valSet[i] - fabs((double)tolerance));
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
vector<MonitorPolicy> mpVMatch;
|
|
mpVMatch.clear();
|
|
|
|
helper.getMonitorPolicyVector(handleMatch[i], mpVMatch);
|
|
|
|
nMonitors[i]=mpVMatch.size();
|
|
|
|
monitorID[i]=0;
|
|
|
|
////valGetA[0][i]=0;
|
|
valGet[i]=0;
|
|
|
|
statMonitor[i]=ICAFE_NORMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (size_t i=0; i< handleMatch.size(); ++i) {
|
|
|
|
//what is monitorpolicy??
|
|
if (nMonitors[i]==0) {
|
|
|
|
unsigned int _nelemPrevious, _nelemRequestedCheck=0;
|
|
unsigned int _nelemRequested=1;
|
|
_nelemPrevious=helper.getNelemClient(handleMatch[i]);
|
|
//Check the number of elements requested?
|
|
if (_nelemPrevious>1) {
|
|
_nelemRequestedCheck = helper.setNelem(handleMatch[i],_nelemRequested);
|
|
if (_nelemRequestedCheck != _nelemRequested) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: "
|
|
<< _nelemPrevious << endl;
|
|
cout << "to: " << _nelemRequested << " but got instead: "
|
|
<< _nelemRequestedCheck << endl;
|
|
}
|
|
}
|
|
|
|
//first do get to update cache before monitor starts
|
|
status=Instant::get(handleMatch[i], dbrType, valGetA);
|
|
|
|
valGet[i]=valGetA[0];
|
|
|
|
if (_nelemPrevious>1) {
|
|
helper.setNelem(handleMatch[i],_nelemPrevious);
|
|
}
|
|
|
|
|
|
if (status!=ICAFE_NORMAL) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cstat.report(status);
|
|
}
|
|
|
|
ChannelWhenToFlushSendBufferPolicyKind whenKind=
|
|
connect.channelMonitorPolicy.getWhenToFlushSendBuffer();
|
|
connect.channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_AUTOMATIC);
|
|
|
|
statMonitor[i]=connect.monitorStart(handleMatch[i], monitorID[i]);
|
|
|
|
if (statMonitor[i]!=ICAFE_NORMAL) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cstat.report(statMonitor[i]);
|
|
}
|
|
else {
|
|
if(printFlag) {cout << "MONITOR STARTED WITH ID=" << monitorID[i] << endl;}
|
|
}
|
|
//revert to previous
|
|
if (whenKind != FLUSH_AUTOMATIC) {
|
|
connect.channelMonitorPolicy.setWhenToFlushSendBuffer(whenKind);
|
|
}
|
|
|
|
} //if nMonitors
|
|
|
|
////valSetA[0][i]=valSet[i];
|
|
|
|
//set No of Elements to 1
|
|
|
|
unsigned int nelemPrevious, nelemRequestedCheck=0;
|
|
unsigned int nelemRequested=1;
|
|
|
|
|
|
nelemPrevious=helper.getNelemClient(handleMatch[i]);
|
|
//Check the number of elements requested?
|
|
if (nelemPrevious>1) {
|
|
nelemRequestedCheck = helper.setNelem(handleMatch[i],nelemRequested);
|
|
if (nelemRequestedCheck != nelemRequested) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: "
|
|
<< nelemPrevious << endl;
|
|
cout << "to: " << nelemRequested << " but got instead: "
|
|
<< nelemRequestedCheck << endl;
|
|
}
|
|
}
|
|
|
|
//No of elements to get from Cache
|
|
|
|
////unsigned int nelemPreviousCheck=0;
|
|
nelemRequested=1; nelemRequestedCheck=0;
|
|
nelemPreviousCache[i]=helper.getNelemRequest(handleMatch[i]);
|
|
|
|
//Check the number of elements requested
|
|
//See set and Match; this needs to be checked
|
|
//Avoid problem when readback channel is the very same as the set(!)
|
|
if (nelemPreviousCache[i]>0 && helper.getNelemNative(handleMatch[i])>1) {
|
|
nelemRequestedCheck = helper.setNelemToRetrieveFromCache(handleMatch[i],nelemRequested);
|
|
if (nelemRequestedCheck != nelemRequested) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to set the no. elements from: "
|
|
<< nelemPreviousCache[i] << endl;
|
|
cout << "to: " << nelemRequested << " but got instead: "
|
|
<< nelemRequestedCheck << endl;
|
|
}
|
|
}
|
|
|
|
} //if size_t
|
|
|
|
//start time
|
|
|
|
double timeElapsed=0; double timeElapsed2=0;
|
|
double timeElapsedBase=0;
|
|
using namespace boost::posix_time;
|
|
|
|
ptime timeStart(microsec_clock::local_time());
|
|
|
|
|
|
for (size_t i=0; i< handleMatch.size(); ++i) {
|
|
|
|
valGetA[0]=0;
|
|
|
|
status=Instant::getCache(handleMatch[i], dbrType, valGetA);
|
|
|
|
valGet[i]=valGetA[0];
|
|
|
|
if (status !=ICAFE_NORMAL) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cstat.report(status);
|
|
}
|
|
|
|
///valGet[i]=valGetA[0][i];
|
|
if (dbrType==DBR_CHAR) {valGet[i] = (unsigned short) valGet[i];}
|
|
|
|
if(printFlag) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Current Cached Value = " << valGet[i] << endl;
|
|
cout << "Lower/Upper Target Values = " << valSetLower[i] << " and " << valSetUpper[i] << endl;
|
|
}
|
|
|
|
} //for size_t
|
|
|
|
|
|
|
|
ptime timeEnd(microsec_clock::local_time());
|
|
time_duration duration(timeEnd-timeStart);
|
|
timeElapsed= (double) duration.total_microseconds()/1000000.0;
|
|
|
|
|
|
for (size_t i=0; i< handleMatch.size(); ++i) {
|
|
|
|
|
|
while ( (valGet[i]>valSetUpper[i] || valGet[i]<valSetLower[i] )
|
|
&& timeElapsed < timeout ) {
|
|
|
|
valGetA[0]=0;
|
|
|
|
status=Instant::getCache(handleMatch[i], dbrType, valGetA);
|
|
valGet[i]=valGetA[0];
|
|
|
|
|
|
//cout <<"Cached value " << valGet[i] << endl;
|
|
|
|
|
|
if (dbrType==DBR_CHAR) {valGet[i] = (unsigned short) valGet[i];}
|
|
|
|
//cout << valSetUpper[i] << " U/L " << valSetLower[i] << endl;
|
|
|
|
ptime timeEnd(microsec_clock::local_time());
|
|
time_duration duration(timeEnd-timeStart);
|
|
timeElapsed= (double) duration.total_microseconds()/1000000.0;
|
|
|
|
timeElapsed2=timeElapsed-timeElapsedBase;
|
|
|
|
if (printFlag && timeElapsed2>1 && status==ICAFE_NORMAL) {
|
|
|
|
for (size_t ij=0; ij< handleMatch.size(); ++ij) {
|
|
status=Instant::getCache(handleMatch[ij], dbrType, valGetA);
|
|
valGet[ij]=valGetA[0];
|
|
if (valGet[ij]>valSetUpper[ij] || valGet[ij]<valSetLower[ij]) {
|
|
cout << "REPORTING ON: " << helper.getPVFromHandle(handleMatch[ij]) << " SET VALUE= " << valSet[ij] \
|
|
<<" WHILE CURRENT READBACK VALUE=" << valGet[ij]
|
|
<< " TimeElapsed " << timeElapsed << " (sec) " << endl;
|
|
|
|
}
|
|
}
|
|
timeElapsedBase=timeElapsed;
|
|
|
|
}
|
|
|
|
|
|
#if HAVE_BOOST_THREAD
|
|
boost::this_thread::sleep_for(boost::chrono::microseconds(20));
|
|
#else
|
|
#if HAVE_LINUX
|
|
usleep(20);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
} //for size_t
|
|
|
|
|
|
|
|
if (timeout <=timeElapsed ) {
|
|
cout << "*****TIMEOUT REACHED****** AFTER " << timeout << " (sec) " << endl;
|
|
status=ECAFE_TIMEOUT_SET_AND_MATCH;
|
|
}
|
|
else {
|
|
|
|
for (size_t i=0; i< handleMatch.size(); ++i) {
|
|
|
|
//if (printFlag) {cout << "MONITOR STARTED WITH ID/2-/=" << monitorID[i] << endl;}
|
|
if (printFlag) {
|
|
valGetA[0]=0;
|
|
status=Instant::getCache(handleMatch[i], dbrType, valGetA);
|
|
valGet[i]=valGetA[0];
|
|
cout << "GAME SET AND MATCH: " << " SET VALUE= " << valSet[i] << " // " << helper.getPVFromHandle(handleMatch[i]) << " READBACK VALUE= " << valGet[i] //pvdMatch.getAsDouble()
|
|
<< " TimeElapsed " << timeElapsed << " (sec) " << endl;
|
|
}
|
|
|
|
} //for
|
|
}
|
|
|
|
|
|
for (size_t i=0; i< handleMatch.size(); ++i) {
|
|
unsigned int nelemPreviousCheck;
|
|
unsigned int nelemRequested=1;
|
|
|
|
|
|
if (nelemPreviousCache[i]>1) {
|
|
nelemPreviousCheck= helper.setNelemToRetrieveFromCache(handleMatch[i],nelemPreviousCache[i]);
|
|
if (nelemPreviousCheck != nelemPreviousCache[i]) {
|
|
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
|
|
cout << "Internal CAFE FUNNY: Wanted to re-set the no. elements from: "
|
|
<< nelemRequested << endl;
|
|
cout << "to the previous: " << nelemPreviousCache[i] << " but got instead: "
|
|
<< nelemPreviousCheck << endl;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (nMonitors[i]==0 && statMonitor[i]==ICAFE_NORMAL) {
|
|
cout << "STOPPING MONITOR WITH ID =" << monitorID[i] << endl;
|
|
int statm;
|
|
statm=connect.monitorStop(handleMatch[i], monitorID[i]);
|
|
if(status==ICAFE_NORMAL){status=statm;}
|
|
}
|
|
|
|
} //for
|
|
|
|
|
|
return status;
|
|
#undef __METHOD__
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif // instant.cpp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|