/// /// \file cafeCache.cpp /// \author Jan Chrin, PSI /// \date Release: February 2015 /// \version CAFE 1.0.0 /// #include using namespace std; /** * \fn int CAFE::getCache(const unsigned int *handleArray, unsigned int nelem, long long * val, * int *statusArray, dbr_short_t *alarmStatus, dbr_short_t *alarmSeverity, epicsTimeStamp *ts) * \brief Retrieves data (long long) from cache * \param handleArray input: Array of handles to Conduit object * \param nelem input: No. of array elements * \param val output: Array of long longs containing cached data * \param statusArray output: Array of status' * \param alarmStatus output: Alarm Status * \param alarmSeverity output: Corresponding severity of alarm * \param ts output: epics timestamp struct * \return overallStatus: ICAFE_NORMAL if all OK else first ECAFE error encountered */ int CAFE::getCache(const unsigned int *handleArray, unsigned int nelem, long long * val, int *statusArray, dbr_short_t *alarmStatus, dbr_short_t *alarmSeverity, epicsTimeStamp *ts) { #define __METHOD__ \ "CAFE::getCache(*handleArray, nelem, * val, *statusArray, *alarmStatus, *alarmSeverity, *ts" unsigned int * nelemPrevious = new unsigned int [nelem]; for (unsigned int i=0; i < nelem; ++i) { nelemPrevious[i] =CAFE::setNelemToRetrieveFromCacheToOne(handleArray[i]); } //Whatever is already there! //find biggest data type //what is the highest native type? chtype chtMax=DBF_CHAR; ChannelRegalia channelInfo; unsigned short nbyteChType=1; unsigned short nbyteMax=nbyteChType; for (unsigned int i=0; inbyteMax && channelInfo.getDataType()< CAFE_NO_ACCESS) { chtMax=channelInfo.getDataType(); nbyteMax=4; } } } switch (chtMax) { case DBR_STRING: { dbr_string_t * _sVal = new dbr_string_t[nelem]; status=cafeSoluble.getCache(handleArray, nelem, DBR_TIME_STRING, _sVal, statusArray, alarmStatus, alarmSeverity, ts); if (status==ICAFE_NORMAL) { istringstream ss; for (unsigned int i=0; i < nelem; ++i) { long long l=0; ss.clear(); ss.str(_sVal[i]); ss>>l; if ( !ss.fail()) { val[i] = (long long) l; std::string strInput=_sVal[i]; std::stringstream ssOut; ssOut << l; std::string strOutput=ssOut.str(); if (strInput!=strOutput) { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** STRING TO LONG LONG CONVERSION REPORTS: " << endl; cout << "STRING VALUE: " << strInput << " CONVERTED TO: " << strOutput << endl; } } else { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** NO STRING TO LONG LONG CONVERSION for ELEMENT " << i \ << " of " << nelem << " !! " << endl; cout << "***WARNING*** COULD NOT CONVERT: "; cout << _sVal[i]; cout << " TO LONG LONG ; CONVERSION NOT MADE!" << endl; cout << "Returning value 0 for element " << i << endl; cout << "Status value is ECAFE_NO_CONVERT for element " << i << endl; val[i]=0; statusArray[i]=ECAFE_NO_CONVERT; } } } delete [] _sVal; break; } case DBR_DOUBLE: { dbr_double_t * _dVal = new dbr_double_t[nelem]; status=cafeDoppio.getCache(handleArray, nelem, DBR_TIME_DOUBLE, _dVal, statusArray, alarmStatus, alarmSeverity, ts); if (status==ICAFE_NORMAL) { for (unsigned int i=0; i < nelem; ++i) { val[i] = (long long) _dVal[i]; } } delete [] _dVal; break; } case DBR_FLOAT: { dbr_float_t * _fVal = new dbr_float_t[nelem]; status=cafeFrappuccino.getCache(handleArray, nelem, DBR_TIME_FLOAT, _fVal, statusArray, alarmStatus, alarmSeverity, ts); if (status==ICAFE_NORMAL) { for (unsigned int i=0; i < nelem; ++i) { val[i] = (long long) _fVal[i]; } } delete [] _fVal; break; } case DBR_LONG: { dbr_long_t * _lVal = new dbr_long_t[nelem]; //std::cout << __METHOD__ << std::endl; status=cafeLatte.getCache(handleArray, nelem, DBR_TIME_LONG, _lVal, statusArray, alarmStatus, alarmSeverity, ts); if (status==ICAFE_NORMAL) { for (unsigned int i=0; i < nelem; ++i) { val[i] = (long long) _lVal[i]; } } //(std::cout << __METHOD__ << val[0] << std::endl; delete [] _lVal; break; } }//switch for (unsigned int i=0; i < nelem; ++i) { CAFE::setNelemToRetrieveFromCacheToPrevious(handleArray[i],nelemPrevious[i]); } return status; #undef __METHOD__ }; /** \fn int CAFE::getCache(const unsigned int *handleArray, unsigned int nelem, long long * val, * int *statusArray, dbr_short_t *alarmStatus, dbr_short_t *alarmSeverity) * \brief Retrieves data (long long) from cache * \param handleArray input: Array of handles to Conduit object * \param nelem input: No. of array elements * \param val output: Array of long longs containing cached data * \param statusArray output: Array of status' * \param alarmStatus output: Alarm Status * \param alarmSeverity output: Corresponding severity of alarm * \return overallStatus: ICAFE_NORMAL if all OK else first ECAFE error encountered */ int CAFE::getCache(const unsigned int *handleArray, unsigned int nelem, long long * val, int *statusArray, dbr_short_t *alarmStatus, dbr_short_t *alarmSeverity) { epicsTimeStamp *ts = new epicsTimeStamp[nelem]; status=CAFE::getCache(handleArray, nelem, val, statusArray, alarmStatus, alarmSeverity, ts); delete [] ts; return status; }; /** * \brief Retrieves data (long long) from cache * \param handleArray input: Array of handles to Conduit object * \param nelem input: No of array elements * \param val output: Array of long longs containing cached data * \param statusArray output: Array of status' * \return overallStatus: ICAFE_NORMAL if all OK else first ECAFE error encountered */ int CAFE::getCache (const unsigned int *handleArray, unsigned int nelem, long long * val, int *statusArray) { dbr_short_t *alarmStatus; dbr_short_t *alarmSeverity; epicsTimeStamp *ts; ts = new epicsTimeStamp[nelem]; alarmStatus = new dbr_short_t[nelem]; alarmSeverity = new dbr_short_t[nelem]; status=CAFE::getCache(handleArray, nelem, val, statusArray, alarmStatus, alarmSeverity, ts); delete [] ts; delete [] alarmStatus; delete [] alarmSeverity; return status; } /** * \brief Retrieves data (long long) from cache * \param handle input: Handle Conduit object * \param _val output: Array of long longs containing cached data * \param alarmStatus output: Alarm Status * \param alarmSeverity output: Corresponding severity of alarm * \param ts output: epics timestamp struct * \return overallStatus: ICAFE_NORMAL if all OK else first ECAFE error encountered */ //5+ long long getCache int CAFE::getCache(const unsigned int handle, long long * _val, \ dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts) { #define __METHOD__ \ "CAFE::getCache(const unsigned int handle, long long * _val, \ dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity, epicsTimeStamp &ts)" ChannelRegalia channelInfo; CAFE::getChannelInfo(handle, channelInfo); if ( channelInfo.getCafeConnectionState() == ICAFE_CS_NEVER_CONN) { return ICAFE_CS_NEVER_CONN; } else if ( channelInfo.getCafeConnectionState()==ICAFE_CS_CLOSED) { return ICAFE_CS_CLOSED; } int _status=ICAFE_NORMAL; unsigned int nn=handleHelper.getNelemRequest(handle); if ( channelInfo.getDataType() == DBR_STRING) { dbr_string_t * _sVal = new dbr_string_t[nn]; _status=cafeSoluble.getCache (handle, DBR_TIME_STRING, _sVal, alarmStatus, alarmSeverity, ts); if (_status!=ICAFE_NORMAL) { delete [] _sVal; return _status; } istringstream ss; for (unsigned short i=0; i>l; if ( !ss.fail()) { _val[i] = (long long) l; std::string strInput=_sVal[i]; std::stringstream ssOut; ssOut << l; std::string strOutput=ssOut.str(); if (strInput!=strOutput) { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** STRING TO LONG LONG CONVERSION REPORTS: " << endl; cout << "STRING VALUE: " << strInput << " CONVERTED TO: " << strOutput << endl; } } else { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** NO STRING TO LONG LONG CONVERSION for ELEMENT " << i \ << " of " << nn << " !! " << endl; cout << "***WARNING*** COULD NOT CONVERT: "; cout << _sVal[i]; cout << " TO LONG LONG ; CONVERSION NOT MADE!" << endl; cout << "Returning value 0 for element " << i << endl; _val[i]=0; } } delete [] _sVal; } else if ( channelInfo.getDataType() == DBR_DOUBLE) { dbr_double_t * _dVal = new dbr_double_t[nn]; _status=cafeDoppio.getCache (handle, DBR_TIME_DOUBLE, _dVal, alarmStatus, alarmSeverity, ts); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _dVal[i]; } delete [] _dVal; } else if ( channelInfo.getDataType() == DBR_FLOAT) { dbr_float_t * _fVal = new dbr_float_t[nn]; _status=cafeFrappuccino.getCache (handle, DBR_TIME_FLOAT, _fVal, alarmStatus, alarmSeverity, ts); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _fVal[i]; } delete [] _fVal; } else { dbr_long_t * _lVal = new dbr_long_t[nn]; _status=cafeLatte.getCache (handle, DBR_TIME_LONG, _lVal, alarmStatus, alarmSeverity, ts); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _lVal[i]; } delete [] _lVal; } return _status; #undef __METHOD__ }; /** * \brief Retrieves data (long long) from cache * \param handle input: Handle Conduit object * \param _val output: Array of long longs containing cached data * \param alarmStatus output: Alarm Status * \param alarmSeverity output: Corresponding severity of alarm * \return overallStatus: ICAFE_NORMAL if all OK else first ECAFE error encountered */ int CAFE::getCache(const unsigned int handle, long long * _val, \ dbr_short_t &alarmStatus, dbr_short_t &alarmSeverity) { #define __METHOD__ \ "CAFE::getCache(const unsigned int handle, long long * _val, dbr_short_t &alarmStatus, \ dbr_short_t &alarmSeverity)" ChannelRegalia channelInfo; CAFE::getChannelInfo(handle, channelInfo); if ( channelInfo.getCafeConnectionState() == ICAFE_CS_NEVER_CONN) { return ICAFE_CS_NEVER_CONN; } else if ( channelInfo.getCafeConnectionState()==ICAFE_CS_CLOSED) { return ICAFE_CS_CLOSED; } int _status=ICAFE_NORMAL; unsigned int nn=handleHelper.getNelemRequest(handle); if ( channelInfo.getDataType() == DBR_STRING) { dbr_string_t * _sVal = new dbr_string_t[nn]; _status=cafeSoluble.getCache (handle, DBR_STS_STRING, _sVal, alarmStatus, alarmSeverity); if (_status!=ICAFE_NORMAL) { delete [] _sVal; return _status; } istringstream ss; for (unsigned short i=0; i>l; if ( !ss.fail()) { _val[i] = (long long) l; std::string strInput=_sVal[i]; std::stringstream ssOut; ssOut << l; std::string strOutput=ssOut.str(); if (strInput!=strOutput) { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** STRING TO LONG LONG CONVERSION REPORTS: " << endl; cout << "STRING VALUE: " << strInput << " CONVERTED TO: " << strOutput << endl; } } else { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** NO STRING TO LONG LONG CONVERSION for ELEMENT " << i \ << " of " << nn << " !! " << endl; cout << "***WARNING*** COULD NOT CONVERT: "; cout << _sVal[i]; cout << " TO LONG LONG ; CONVERSION NOT MADE!" << endl; cout << "Returning value 0 for element " << i << endl; _val[i]=0; } } delete [] _sVal; } else if ( channelInfo.getDataType() == DBR_DOUBLE) { dbr_double_t * _dVal = new dbr_double_t[nn]; _status=cafeDoppio.getCache(handle, DBR_STS_DOUBLE, _dVal, alarmStatus, alarmSeverity); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _dVal[i]; } delete [] _dVal; } else if ( channelInfo.getDataType() == DBR_FLOAT) { dbr_float_t * _fVal = new dbr_float_t[nn]; _status=cafeFrappuccino.getCache (handle, DBR_STS_FLOAT, _fVal, alarmStatus, alarmSeverity); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _fVal[i]; } delete [] _fVal; } else { dbr_long_t * _lVal = new dbr_long_t[nn]; _status=cafeLatte.getCache (handle, DBR_STS_LONG, _lVal, alarmStatus, alarmSeverity); for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _lVal[i]; } delete [] _lVal; } return _status; #undef __METHOD__ }; /** * \brief Retrieves data (long long) from cache * \param handle input: Handle Conduit object * \param _val output: Array of long longs containing cached data * \return overallStatus: ICAFE_NORMAL if all OK else first ECAFE error encountered */ int CAFE::getCache(const unsigned int handle, long long * _val) { #define __METHOD__ \ "CAFE::get(const unsigned int handle, long long * _val)" ChannelRegalia channelInfo; CAFE::getChannelInfo(handle, channelInfo); if ( channelInfo.getCafeConnectionState() == ICAFE_CS_NEVER_CONN) { return ICAFE_CS_NEVER_CONN; } else if ( channelInfo.getCafeConnectionState()==ICAFE_CS_CLOSED) { return ICAFE_CS_CLOSED; } int _status=ICAFE_NORMAL; unsigned int nn=handleHelper.getNelemRequest(handle); if ( channelInfo.getDataType() == DBR_STRING) { dbr_string_t * _sVal = new dbr_string_t[nn]; _status=cafeSoluble.getCache (handle, DBR_STRING, _sVal); if (_status!=ICAFE_NORMAL) { delete [] _sVal; return _status; } istringstream ss; for (unsigned short i=0; i>l; if ( !ss.fail()) { _val[i] = (long long) l; std::string strInput=_sVal[i]; std::stringstream ssOut; ssOut << l; std::string strOutput=ssOut.str(); if (strInput!=strOutput) { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** STRING TO LONG LONG CONVERSION REPORTS: " << endl; cout << "STRING VALUE: " << strInput << " CONVERTED TO: " << strOutput << endl; } } else { cout << __METHOD__ << "//" << __LINE__ << endl; cout << "***WARNING*** NO STRING TO LONG LONG CONVERSION for ELEMENT " << i \ << " of " << nn << " !! " << endl; cout << "***WARNING*** COULD NOT CONVERT: "; cout << _sVal[i]; cout << " TO LONG LONG ; CONVERSION NOT MADE!" << endl; cout << "Returning value 0 for element " << i << endl; _val[i]=0; } } delete [] _sVal; } else if ( channelInfo.getDataType() == DBR_DOUBLE) { dbr_double_t * _dVal = new dbr_double_t[nn]; _status=cafeDoppio.getCache (handle, DBR_DOUBLE, _dVal); if (_status!=ICAFE_NORMAL) { delete [] _dVal; return _status; } for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _dVal[i]; } delete [] _dVal; } else if ( channelInfo.getDataType() == DBR_FLOAT) { dbr_float_t * _fVal = new dbr_float_t[nn]; _status=cafeFrappuccino.getCache (handle, DBR_FLOAT, _fVal); if (_status!=ICAFE_NORMAL) { delete [] _fVal; return _status; } for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _fVal[i]; } delete [] _fVal; } else { dbr_long_t * _lVal = new dbr_long_t[nn]; _status=cafeLatte.getCache (handle, DBR_LONG, _lVal); if (_status!=ICAFE_NORMAL) { delete [] _lVal; return _status; } for (unsigned int i=0; i < handleHelper.getNelemRequest(handle); ++i) { _val[i] = (long long) _lVal[i]; } delete [] _lVal; } return _status; #undef __METHOD__ }; /** * \brief Retrieves data from cache, packaged into the PVDataHolder class * \param handleArray input: Array of handles to Conduit object * \param nelem input: No of array elements * \param pvdArray outout: Array of PVDataHolder containing cached data * \return overallStatus: ICAFE_NORMAL if all OK else first ECAFE error encountered */ int CAFE::getCache(const unsigned int * handleArray, unsigned int nelem, PVDataHolder * pvdArray) { #define __METHOD__ \ "CAFE::getCache(unsigned int * handleArray, unsigned int nelem, PVDataHolder * pvdArray)" int overallStatus=ICAFE_NORMAL; bool isGood=true; for (unsigned int i=0; i (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); // std::cout << __FILE__ << " " << __METHOD__ << std::endl; if (it_handle != handle_index.end()) { //Reset any possible put error that preceded call to getCache if ( (*it_handle).getStatus() == ECAFE_NOWTACCESS || (*it_handle).getStatus() == ECA_PUTFAIL || (*it_handle).getStatus() == ECA_PUTCBINPROG) { if(MUTEX) { cafeMutex.lock(); }; //lock //std::cout << "getStatus - before:" << (*it_handle).getStatus() << std::endl; handle_index.modify(it_handle, change_status(ICAFE_NORMAL)); pvd.status = ICAFE_NORMAL; //std::cout << "getStatus - after:" << (*it_handle).getStatus() << std::endl; if(MUTEX) { cafeMutex.unlock(); }; //unlock } //meant for use in callbacks in monitors! if ( (*it_handle).getChannelGetCacheWaitPolicy().getWaitKind() == CAFENUM::GET_CACHE_NO_CHECK) { (*it_handle).getPVDataHolder(pvd); //pvd.status = ICAFE_NORMAL; //return status; return pvd.status; } //std::cout << "=============================================================================" << std::endl; //std::cout << __METHOD__ << " PV= " << (*it_handle).getPV() << std::endl; //std::cout << (*it_handle).getChannelRegalia().getCafeConnectionState() << std::endl; //std::cout << (*it_handle).isConnected() << std::endl; //Newly added!! //ifNeverConnected - return error if ( (*it_handle).getChannelRegalia().getCafeConnectionState() == ICAFE_CS_NEVER_CONN) { pvd.status= ICAFE_CS_NEVER_CONN; return ICAFE_CS_NEVER_CONN; } else if ( (*it_handle).getChannelRegalia().getCafeConnectionState()==ICAFE_CS_CLOSED) { pvd.status= ICAFE_CS_CLOSED; return ICAFE_CS_CLOSED; } else if ( (*it_handle).getChannelRegalia().getCafeConnectionState()==ICAFE_CS_DISCONN) { pvd.status= ICAFE_CS_DISCONN; return ICAFE_CS_DISCONN; } //Whatever is already there! chtype dbrtype= (*it_handle).getChannelRequestMetaData().getDbrDataType(); //Find Native DataType if ( (status=cafeGranules.channelVerifyGet(handle, dbrtype)) != ICAFE_NORMAL) { (*it_handle).getPVDataHolder(pvd); pvd.status = status; return status; } //Add CAFENUM::WITH_CALLBACK_USER_SUPPLIED if ((*it_handle).getChannelRequestStatusGet().getCallbackProgressKind() == CAFENUM::PENDING && handleHelper.getNmonitorData(handle)==0 && (*it_handle).getChannelRequestPolicyGet().getMethodKind() != CAFENUM::WITH_CALLBACK_USER_SUPPLIED && (*it_handle).getChannelGetCacheWaitPolicy().getWaitKind() == CAFENUM::GET_CACHE_WAIT && (*it_handle).isConnected() ) { ChannelTimeoutPolicy channelTimeoutPolicyGet = (*it_handle).getChannelTimeoutPolicyGet(); ca_poll(); status=cafeGranules.waitForGetEvent(handle, channelTimeoutPolicyGet.getTimeout() ); if (status==ECAFE_TIMEOUT && channelTimeoutPolicyGet.getSelfGoverningTimeout()) { unsigned short ntries=0; while (status==ECAFE_TIMEOUT && ntries (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); //std::cout << __METHOD__ << " " << std::endl; if (it_handle != handle_index.end()) { std::deque mapPulseID; try { if(MUTEX) { cafeMutex.lock(); } mapPulseID=(*it_handle).getPulsePVData(); //std::cout << __METHOD__ << " " << std::endl; //std::cout << " Size =====================================>>>> " << mapPulseID.size() << " handle=" << handle << std::endl; //std::cout << " Handle " << handle << " " << handleHelper.getPVFromHandle(handle) << std::endl; if(MUTEX) { cafeMutex.unlock(); } if (mapPulseID.size()==0) { //std::cout << "Map Size is zero " << std::endl; (*it_handle).getPVDataHolder(pvd); //pvd.print(); return ICAFE_NORMAL; //This case can happen if the monitored event is the pulseID PV itself! } } catch (std::bad_alloc &e) { //Would eventually happen if there were no mutex for getPulsePVDataMap which accesses a dynamic map std::cout << __FILE__ << "//" << __METHOD__ << " Force exit!! " << std::endl; std::cout << e.what() << std:: endl; exit(1); } //using namespace boost::posix_time; //double timeElapsed=0; //ptime timeStart(microsec_clock::local_time()); pvd=mapPulseID[mapPulseID.size()-1]; if ( pvd.getPulseID() > globalPulseID ) { if (SF_WITH_PULSE_ID) { cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; std::cout << (*it_handle).getPV() << " " << (*it_handle).getHandle() << std::endl; std::cout << "WARNING: mapPulseIDBufferSize is too shallow to match data to pulseID. " << std::endl; std::cout << "WARNING: Current IDBufferSize= " << (*it_handle).getMapPulseIDBufferSize() << " and can be expanded by user if required. " << std::endl; std::cout << "key: pulseID " << pvd.getPulseID() << " is > global pid " << globalPulseID << std::endl; //" in loop idx:" << mpos << std::endl; } return ICAFE_NORMAL; } for (unsigned int mpos=0; mpos < mapPulseID.size(); ++mpos) { //cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; //std::cout << (*it_handle).getPV() << " " << (*it_handle).getHandle() << std::endl; //std::cout << "WARNING: Current Value= " << (*it_handle).getMapPulseIDBufferSize() << " can be expanded by user if required. " << std::endl; //std::cout << "key: pulseID " << mapPulseID[mpos].getPulseID() << " and gobal pid " << globalPulseID << " in loop idx:" << mpos << std::endl; if ( mapPulseID[mpos].getPulseID() == globalPulseID) { std::cout << "key: EQUAL" << mapPulseID[mpos].getPulseID() << " pid " << globalPulseID << " " << mpos << std::endl; pvd=mapPulseID[mpos]; return ICAFE_NORMAL; } else if ( mapPulseID[mpos].getPulseID() > globalPulseID) { //Missed the event; get event before pvd=mapPulseID[mpos-1]; return ICAFE_NORMAL; } //else //{ // std::cout << "key: LT " << mapPulseID[mpos].getPulseID() << " pid " << globalPulseID << " " << mpos << std::endl; // //pvd=mapPulseID[mpos]; //} } //ptime timeEnd(microsec_clock::local_time()); //time_duration duration(timeEnd-timeStart); //timeElapsed= (double) duration.total_microseconds()/1000000.0; //std::cout << "time for getPulsePVDataMap = " << timeElapsed << std::endl; } else { if (printErrorPolicy.getInvalidHandle()) { cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cafeStatus.report(ECAFE_INVALID_HANDLE); } return ECAFE_INVALID_HANDLE; } return status; #undef __METHOD__ } /** * \brief reset callback for set operation to NOT_INITIATED / NOT_TRIGGERED * \param handle input: handle to Conduit object * \return ICAFE_NORMAL if all OK else ECAFE_INVALID_HANDLE */ int CAFE::resetCallbackPut(const unsigned int handle) { #define __METHOD__ "CAFE::resetCallbackPut(unsigned int)" status=ICAFE_NORMAL; cafeConduit_set_by_handle & handle_index = cs.get (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { if(MUTEX) { cafeMutex.lock(); //lock } ChannelRequestStatus channelRequestStatusPut = (*it_handle).getChannelRequestStatusPut(); channelRequestStatusPut.setCallbackStatus (status); channelRequestStatusPut.setCallbackKind(false, false); // NOT_INITIATED NOT_TRIGGERED handle_index.modify(it_handle, change_channelRequestStatusPut(channelRequestStatusPut)); if(MUTEX) { cafeMutex.unlock(); //unlock } } else { if (printErrorPolicy.getInvalidHandle()) { cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cafeStatus.report(ECAFE_INVALID_HANDLE); } return ECAFE_INVALID_HANDLE; } return status; #undef __METHOD__ } /** * \brief reset callback for get operation to NOT_INITIATED / NOT_TRIGGERED * \param handle input: handle to Conduit object * \return ICAFE_NORMAL if all OK else ECAFE_INVALID_HANDLE */ int CAFE::resetCallbackGet(const unsigned int handle) { #define __METHOD__ "CAFE::resetCallbackGet(unsigned int)" status=ICAFE_NORMAL; cafeConduit_set_by_handle & handle_index = cs.get (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { if(MUTEX) { cafeMutex.lock(); //lock } ChannelRequestStatus channelRequestStatusGet = (*it_handle).getChannelRequestStatusGet(); channelRequestStatusGet.setCallbackStatus (status); channelRequestStatusGet.setCallbackKind(false, false); // NOT_INITIATED NOT_TRIGGERED handle_index.modify(it_handle, change_channelRequestStatusGet(channelRequestStatusGet)); if(MUTEX) { cafeMutex.unlock(); //unlock } } else { if (printErrorPolicy.getInvalidHandle()) { cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cafeStatus.report(ECAFE_INVALID_HANDLE); } return ECAFE_INVALID_HANDLE; } return status; #undef __METHOD__ } /** * \brief Retrieves data from cache, packaged into the PVDataHolder class * \param handle input: handle to Conduit object * \param pvd outout: PVDataHolder containing cached data * \return ICAFE_NORMAL if all OK */ int CAFE::getCacheNoWait(const unsigned int handle, PVDataHolder & pvd) { #define __METHOD__ "CAFE::getCacheNoWait(unsigned int handle, PVDataHolder & pvd)" //status=ICAFE_NORMAL; cafeConduit_set_by_handle & handle_index = cs.get (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); int local_status = ICAFE_NORMAL; if (it_handle != handle_index.end()) { //std::cout << __METHOD__ << " pvd.getStatus() start STATUS ===> " << pvd.getStatus() << endl; //Whatever is already there! chtype dbrtype= (*it_handle).getChannelRequestMetaData().getDbrDataType(); //Find Native DataType if ( (status=cafeGranules.channelVerifyGet(handle, dbrtype)) != ICAFE_NORMAL) { (*it_handle).getPVDataHolder(pvd); //std::cout << __METHOD__ << status << " is status of VerifyGet" << std::endl; pvd.status = status; return status; } if (!(*it_handle).isConnected() ) { if(MUTEX) { cafeMutex.lock(); //lock } ChannelRequestStatus channelRequestStatusGet = (*it_handle).getChannelRequestStatusGet(); channelRequestStatusGet.setCallbackStatus (status); channelRequestStatusGet.setCallbackKind(false, false); // NOT_INITIATED NOT_TRIGGERED handle_index.modify(it_handle, change_channelRequestStatusGet(channelRequestStatusGet)); handle_index.modify(it_handle, change_status(ICAFE_CS_DISCONN)); if(MUTEX) { cafeMutex.unlock(); //unlock } (*it_handle).getPVDataHolder(pvd); cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cafeStatus.report(ICAFE_CS_DISCONN); return ICAFE_CS_DISCONN; } (*it_handle).getPVDataHolder(pvd); pvd.status = local_status; //cout << __METHOD__ << " pvd.getStatus() STATUS ===> " << pvd.getStatus() << endl; } else { if (printErrorPolicy.getInvalidHandle()) { cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl; cafeStatus.report(ECAFE_INVALID_HANDLE); } pvd.status=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 pvd.getStatus(); #undef __METHOD__ }; /** * \brief Retrieves PV DBR_CTRL data from cache, packaged into the PVCtrlHolder class * \param handleArray input: Array of handles to Conduit object * \param nelem input: No of array elements * \param pvcArray outout: Array of PVCtrlHolder containing cached data * \return overallStatus: ICAFE_NORMAL if all OK else first ECAFE error encountered */ int CAFE::getCtrlCache(const unsigned int * handleArray, unsigned int nelem, PVCtrlHolder * pvcArray) { #define __METHOD__ \ "CAFE::getCtrlCache(unsigned int * handleArray, unsigned int nelem, PVCtrlHolder * pvcArray)" int overallStatus=ICAFE_NORMAL; bool isGood=true; for (unsigned int i=0; i (); cafeConduit_set_by_handle::iterator it_handle; it_handle = handle_index.find(handle); if (it_handle != handle_index.end()) { //Whatever is already there! chtype dbrtype= (*it_handle).getChannelRequestMetaData().getDbrDataType(); //Use Native DataType if ( (status=cafeGranules.channelVerifyGetCtrl(handle, dbrtype)) != ICAFE_NORMAL) { (*it_handle).getPVCtrlHolder(pvc); pvc.status=status; return status; } if ((*it_handle).getChannelRequestStatusGetCtrl().getCallbackProgressKind() == CAFENUM::PENDING && handleHelper.getNmonitorCtrl(handle)==0 && (*it_handle).getChannelRequestPolicyGetCtrl().getMethodKind() != CAFENUM::WITH_CALLBACK_USER_SUPPLIED && (*it_handle).getChannelGetCacheWaitPolicy().getWaitKind() == CAFENUM::GET_CACHE_WAIT && (*it_handle).isConnected() ) { ChannelTimeoutPolicy channelTimeoutPolicyGet=(*it_handle).getChannelTimeoutPolicyGet(); ca_poll(); status=cafeGranules.waitForGetCtrlEvent(handle, channelTimeoutPolicyGet.getTimeout() ); if (status==ECAFE_TIMEOUT && channelTimeoutPolicyGet.getSelfGoverningTimeout() && (*it_handle).isConnected() ) { unsigned short ntries=0; while (status==ECAFE_TIMEOUT && ntries