Initial commit

This commit is contained in:
2017-09-19 08:27:10 +02:00
commit 3b2e49f7b7
138 changed files with 199299 additions and 0 deletions

View File

@@ -0,0 +1,488 @@
///
/// \file conduitConnectionHandlerArgs.h
/// \author Jan Chrin, PSI
/// \date November 2014
/// \version CAFE 1.0.0
///
#ifndef CONDUITCONNECTIONHANDLERARGS_H
#define CONDUITCONNECTIONHANDLERARGS_H
#include <cstdio>
#include <conduit.h>
#include <statusCodes.h>
using namespace std;
/**
* Friend to Conduit/CAFEGroup records the connection_handler_args struct from callback fns
* in hash table
*/
struct change_connectionHandlerArgs
{
#define __METHOD__ "change_connectionHandlerArgs"
change_connectionHandlerArgs (const struct connection_handler_args & new_connectionHandlerArgs):
new_connectionHandlerArgs(new_connectionHandlerArgs){}
void operator() (Conduit& c) {
chtype nativeDataType = ca_field_type(new_connectionHandlerArgs.chid);
c.channelRegalia.connectionState=new_connectionHandlerArgs.op;
// Data type code will be one of DBF_. The constant TYPENOTCONN=-1 is
// returned if the channel is not connected
// but we do not overwrite it upon disconnect.
//connectFlag
if (new_connectionHandlerArgs.op == CA_OP_CONN_UP){
//cout << " change_connectionHandlerArgs: bytesize UP " << c.channelRequestMetaData.byteSize << endl;
//channelRegalia
c.channelRegalia.nelem = ca_element_count(new_connectionHandlerArgs.chid);
c.channelRegalia.connectFlag = true;
c.channelRegalia.hostName = (const char *) ca_host_name (new_connectionHandlerArgs.chid);
if (c.channelRegalia.channelID != new_connectionHandlerArgs.chid) {
cout << __FILE__ << "//" << __LINE__ << "//" << __METHOD__ << endl;
cout << "Internal CAFE WARNING for handle : " << c.handle << endl;
cout << "Channel ID has changed from " << c.channelRegalia.channelID
<< " to " << new_connectionHandlerArgs.chid << " " << endl;
cout << "This is a rare occurence and happens when the ca message buffer " << endl;
cout << "is flushed ahead of schedule (does that when full) and this callback is " << endl;
cout << "consequently activated before channel ID is written to the hash table " << endl;
c.channelRegalia.channelID = new_connectionHandlerArgs.chid;
}
//Data type code will be one of DBF_. The constant TYPENOTCONN=-1 is
//returned if the channel is not connected.
//Does not get overwritten on channel disconnection
c.channelRegalia.dataType = nativeDataType;
// DATA BUFFER ------------------------------------------------------------------
// data buffer CLIENT
// Check if c.channelRegalia.cafeConnectionState == ICAFE_CS_NEVER_CONN or not!
if (c.channelRegalia.cafeConnectionState == ICAFE_CS_NEVER_CONN ) {
c.channelRequestMetaDataClient.channelID = new_connectionHandlerArgs.chid;
c.channelRequestMetaDataClient.nelem = c.channelRegalia.nelem;
c.channelRequestMetaDataClient.nelemCache = c.channelRegalia.nelem;
c.channelRequestMetaDataClient.dataType = nativeDataType;
//cafeDbrType first filled with CAFENUM:DBR_TIME on initialization
//but will be overwritten by whatever the client needs
switch (c.channelRequestMetaDataClient.cafeDbrType)
{
case CAFENUM::DBR_TIME:
c.channelRequestMetaDataClient.dbrDataType = dbf_type_to_DBR_TIME(nativeDataType);
break;
case CAFENUM::DBR_STS:
c.channelRequestMetaDataClient.dbrDataType = dbf_type_to_DBR_STS(nativeDataType);
break;
case CAFENUM::DBR_PRIMITIVE:
c.channelRequestMetaDataClient.dbrDataType = dbf_type_to_DBR(nativeDataType);
break;
default:
c.channelRequestMetaDataClient.dbrDataType = dbf_type_to_DBR_TIME(nativeDataType);
c.channelRequestMetaDataClient.cafeDbrType = CAFENUM::DBR_TIME;
break;
}
//What client is actutally requesting
c.channelRequestMetaDataClient.byteSize=dbr_size_n(
c.channelRequestMetaDataClient.dbrDataType,
//dbf_type_to_DBR_TIME(nativeDataType),
c.channelRequestMetaDataClient.nelem);
}
//data Buffer requested by Cafe
c.channelRequestMetaData.channelID = new_connectionHandlerArgs.chid;
c.channelRequestMetaData.nelem = c.channelRegalia.nelem;
c.channelRequestMetaData.nelemCache = c.channelRegalia.nelem;
c.channelRequestMetaData.dataType = nativeDataType;
//cafeDbrType first filled with CAFENUM:DBR_TIME on initialization
//cafeDbrType can only be overwritten by an explicit method invocation
switch (c.channelRequestMetaData.cafeDbrType)
{
case CAFENUM::DBR_TIME:
c.channelRequestMetaData.dbrDataType = dbf_type_to_DBR_TIME(nativeDataType);
break;
case CAFENUM::DBR_STS:
c.channelRequestMetaData.dbrDataType = dbf_type_to_DBR_STS(nativeDataType);
break;
case CAFENUM::DBR_PRIMITIVE:
c.channelRequestMetaData.dbrDataType = dbf_type_to_DBR(nativeDataType);
break;
default:
c.channelRequestMetaData.dbrDataType = dbf_type_to_DBR_TIME(nativeDataType);
c.channelRequestMetaData.cafeDbrType = CAFENUM::DBR_TIME;
break;
}
// CTRL BUFFER ------------------------------------------------------------------
//No of elements for Ctrl Buffers
unsigned int nelem_ctrl_buffer=1;
if ( c.channelRegalia.nelem > MAX_NELEM_FOR_CTRL_BUFFER) {
nelem_ctrl_buffer = DEFAULT_NELEM_FOR_CTRL_BUFFER;
}
else {
nelem_ctrl_buffer = c.channelRegalia.nelem;
}
//ctrl data CLIENT
//Ctrl data requested by Client
if (c.channelRegalia.cafeConnectionState == ICAFE_CS_NEVER_CONN ) {
c.channelRequestMetaCtrlClient.channelID = new_connectionHandlerArgs.chid;
c.channelRequestMetaCtrlClient.nelem = c.channelRegalia.nelem; //nelem_ctrl_buffer;
c.channelRequestMetaCtrlClient.nelemCache = c.channelRegalia.nelem;
c.channelRequestMetaCtrlClient.dataType = nativeDataType;
//cafeDbrType first filled with CAFENUM:DBR_CTRL on initialization
//but will be overwritten by whatever the client needs
switch (c.channelRequestMetaCtrlClient.cafeDbrType)
{
case CAFENUM::DBR_CTRL:
c.channelRequestMetaCtrlClient.dbrDataType = dbf_type_to_DBR_CTRL(nativeDataType);
break;
case CAFENUM::DBR_GR:
c.channelRequestMetaCtrlClient.dbrDataType = dbf_type_to_DBR_GR (nativeDataType);
break;
default:
c.channelRequestMetaCtrlClient.dbrDataType = dbf_type_to_DBR_CTRL(nativeDataType);
c.channelRequestMetaCtrlClient.cafeDbrType = CAFENUM::DBR_CTRL;
break;
}
c.channelRequestMetaCtrlClient.byteSize=dbr_size_n(
c.channelRequestMetaCtrlClient.dbrDataType,c.channelRequestMetaCtrlClient.nelem);
}
//ctrl Data requested by Cafe
c.channelRequestMetaCtrl.channelID = new_connectionHandlerArgs.chid;
c.channelRequestMetaCtrl.nelem = nelem_ctrl_buffer;
c.channelRequestMetaCtrl.nelemCache = nelem_ctrl_buffer;
c.channelRequestMetaCtrl.dataType = nativeDataType;
//cafeDbrType first filled with CAFENUM:DBR_CTRL on initialization
//cafeDbrType can only be overwritten by an explicit method invocation
switch (c.channelRequestMetaCtrl.cafeDbrType)
{
case CAFENUM::DBR_CTRL:
c.channelRequestMetaCtrl.dbrDataType = dbf_type_to_DBR_CTRL(nativeDataType);
break;
case CAFENUM::DBR_GR:
c.channelRequestMetaCtrl.dbrDataType = dbf_type_to_DBR_GR (nativeDataType);
break;
default:
c.channelRequestMetaCtrl.dbrDataType = dbf_type_to_DBR_CTRL(nativeDataType);
c.channelRequestMetaCtrl.cafeDbrType = CAFENUM::DBR_CTRL;
break;
}
// STSACK BUFFER ------------------------------------------------------------------
//No of elements for STSACK Buffers
unsigned int nelem_stsack_buffer;
if ( c.channelRegalia.nelem > MAX_NELEM_FOR_STSACK_BUFFER) {
nelem_stsack_buffer = DEFAULT_NELEM_FOR_STSACK_BUFFER;
}
else {
nelem_stsack_buffer = c.channelRegalia.nelem;
}
//STSACK Buffer Repository
c.channelRequestMetaSTSACK.channelID = new_connectionHandlerArgs.chid;
c.channelRequestMetaSTSACK.nelem = nelem_stsack_buffer;
c.channelRequestMetaSTSACK.nelemCache = nelem_stsack_buffer;
c.channelRequestMetaSTSACK.dataType = DBR_STRING;
c.channelRequestMetaSTSACK.dbrDataType = DBR_STSACK_STRING;
c.channelRequestMetaSTSACK.cafeDbrType = CAFENUM::DBR_STSACK;
//PRIMITIVE Buffer Repository
c.channelRequestMetaPrimitive.channelID = new_connectionHandlerArgs.chid;
c.channelRequestMetaPrimitive.nelem = c.channelRegalia.nelem;
c.channelRequestMetaPrimitive.dataType = nativeDataType;;
c.channelRequestMetaPrimitive.dbrDataType= dbf_type_to_DBR(nativeDataType);
c.channelRequestMetaPrimitive.cafeDbrType= CAFENUM::DBR_PRIMITIVE;
///////////////////////////////////////////////////////////////////////////
if ( c.channelRegalia.nelem>1) {
double tout= ((unsigned int) (c.channelRegalia.nelem*0.000001)); // 1 sec per million
c.channelRequestDataTypePolicy.setRequestKind(CAFENUM::LOWEST_DATATYPE);
c.channelTimeoutPolicyGet.setTimeout(std::max(DEFAULT_TIMEOUT_PEND_IO_WF , tout));
c.channelTimeoutPolicyPut.setTimeout(std::max(DEFAULT_TIMEOUT_PEND_IO_WF , tout));
c.channelTimeoutPolicyGet.setDefaultTimeout(DEFAULT_TIMEOUT_PEND_IO_WF);
c.channelTimeoutPolicyPut.setDefaultTimeout(DEFAULT_TIMEOUT_PEND_IO_WF);
}
c.channelRegalia.cafeConnectionState = ICAFE_CS_CONN;
c.status = ICAFE_CA_OP_CONN_UP;
}
else {
//nativeType not known on disconnect!!
//Also callback done
c.channelRequestStatusGet.setCallbackKind(false, true); //fake completion
c.channelRequestStatusPut.setCallbackKind(false, true); //fake completion
c.channelRegalia.cafeConnectionState =ICAFE_CS_DISCONN;
c.channelRegalia.connectFlag = false;
c.status = ICAFE_CA_OP_CONN_DOWN;
}
}
private:
connection_handler_args new_connectionHandlerArgs;
#undef __METHOD__
};
/**
* Friend to Conduit/CAFEGroup permitting fast modification to the ctrlBuffer
* This is the ctrlBuffer for _CTRL data requested through ca_get
*/
struct change_dataBufferSize_CTRL
{
#define __METHOD__ "change_dataBufferSize_CTRL"
change_dataBufferSize_CTRL (const chtype & new_ctrlTypeBuffer): new_ctrlTypeBuffer(new_ctrlTypeBuffer){}
void operator() (Conduit& c) {
// Free buffer on re-connection
// Check Byte size first!!!
bool allocateMemory=false ;
if(c.ctrlBuffer==NULL) {
allocateMemory=true;
}
else if ( dbr_size_n(new_ctrlTypeBuffer,c.channelRequestMetaCtrl.getNelem()) > c.channelRequestMetaCtrl.getByteSize() ) {
cout << "ctrlBuffer already exists= " << c.ctrlBuffer << " for channel " << c.pv
<< " with handle " << c.handle << endl;
cout << "Freeing and reallocating ctrlBuffer" << endl;
free(c.ctrlBuffer);
allocateMemory=true;
}
if (allocateMemory) {
//cout << "sizeof c.ctrlBuffer " << dbr_size_n(new_ctrlTypeBuffer,c.channelRequestMetaCtrl.getNelem()) << endl;
c.ctrlBuffer = (db_access_val *) malloc ( dbr_size_n(new_ctrlTypeBuffer,c.channelRequestMetaCtrl.getNelem()) );
c.channelRequestMetaCtrl.byteSize=dbr_size_n(new_ctrlTypeBuffer,c.channelRequestMetaCtrl.getNelem());
}
if (c.ctrlBuffer==0){
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
printf ("Virtual memory exhausted for channel %s ", ca_name(c.channelID));
printf ("Exiting CAFE");
}
}
private:
chtype new_ctrlTypeBuffer;
#undef __METHOD__
};
/**
* Friend to CAFEConduit/CAFEGroup permitting fast modification to the dataBuffer of type DBR (putBuffer)
* This is used in ca_put methods when input data that is not already in native data type is thus converted
*/
struct change_dataBufferSize_PRIMITIVE
{
#define __METHOD__ "change_dataBufferSize_PRIMITIVE"
change_dataBufferSize_PRIMITIVE (const chtype & new_dataTypeBufferNative): new_dataTypeBufferNative(new_dataTypeBufferNative){}
void operator() (Conduit& c) {
bool allocateMemory=false ;
if(c.putBuffer==NULL) {
allocateMemory=true;
}
else if ( dbr_size_n(c.channelRequestMetaPrimitive.getDbrDataType(),
c.channelRequestMetaPrimitive.getNelem())
> c.channelRequestMetaPrimitive.getByteSize() ) {
cout << "putBuffer already exists= " << c.putBuffer << " for channel " << c.pv
<< " with handle " << c.handle << endl;
cout << "Freeing and reallocating putBuffer" << endl;
free(c.putBuffer);
allocateMemory=true;
}
if (allocateMemory) {
//cout << "sizeof c.putBuffer " << dbr_size_n(c.channelRequestMetaPrimitive.getDbrDataType(),
// c.channelRequestMetaPrimitive.getNelem()) << endl;
c.putBuffer = (db_access_val *) malloc (dbr_size_n(c.channelRequestMetaPrimitive.getDbrDataType(),
c.channelRequestMetaPrimitive.getNelem()));
c.channelRequestMetaPrimitive.byteSize
=dbr_size_n(c.channelRequestMetaPrimitive.getDbrDataType(),
c.channelRequestMetaPrimitive.getNelem());
}
if (c.putBuffer==0){
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
printf ("Virtual memory exhausted for channel %s ", ca_name(c.channelID));
printf ("Exiting CAFE");
exit(0);
}
}
private:
chtype new_dataTypeBufferNative;
#undef __METHOD__
};
/**
* Friend to CAFEConduit/CAFEGroup permitting fast modification to the ctrlBuffer
* This is the ctrlBuffer for _CTRL data requested through ca_get
*/
struct change_dataBufferSize_STSACK
{
#define __METHOD__ "change_dataBufferSize_STSACK"
change_dataBufferSize_STSACK (){}
void operator() (Conduit& c) {
bool allocateMemory=false ;
if(c.stsackBuffer==NULL) {
allocateMemory=true;
}
else if ( dbr_size_n(c.channelRequestMetaSTSACK.getDbrDataType(),
c.channelRequestMetaSTSACK.getNelem())
> c.channelRequestMetaSTSACK.getByteSize() ) {
cout << "stsackBuffer already exists= " << c.stsackBuffer << " for channel " << c.pv
<< " with handle " << c.handle << endl;
cout << "Freeing and reallocating putBuffer" << endl;
free(c.stsackBuffer);
allocateMemory=true;
}
if (allocateMemory) {
//cout << "sizeof c.stsackBuffer " << dbr_size_n(c.channelRequestMetaSTSACK.getDbrDataType(),
// c.channelRequestMetaSTSACK.getNelem()) << endl;
c.stsackBuffer = (db_access_val *) malloc (dbr_size_n(c.channelRequestMetaSTSACK.getDbrDataType(),
c.channelRequestMetaSTSACK.getNelem()));
c.channelRequestMetaSTSACK.byteSize
=dbr_size_n(c.channelRequestMetaSTSACK.getDbrDataType(),
c.channelRequestMetaSTSACK.getNelem());
}
}
#undef __METHOD__
};
/**
* Friend to CAFEConduit/CAFEGroup permitting fast modification to the dataBuffer of type DBR_TIME (dataBuffer)
* This is the main dataBuffer for data requested through ca_get
*/
struct change_dataBufferSize_TIME
{
#define __METHOD__ "change_dataBufferSize_PRIMITIVE"
change_dataBufferSize_TIME (const chtype & new_dataTypeBuffer): new_dataTypeBuffer(new_dataTypeBuffer){}
void operator() (Conduit& c) {
// Free buffer on re-connection
// Check Byte size first!!!
bool allocateMemory=false ;
if(c.dataBuffer==NULL) {
allocateMemory=true;
}
else if ( dbr_size_n(new_dataTypeBuffer,c.channelRegalia.getNelem()) > c.channelRequestMetaData.getByteSize() ) {
cout << "dataBuffer already exists= " << c.dataBuffer << " for channel " << c.pv
<< " with handle " << c.handle << endl;
cout << "Freeing and reallocating dataBuffer" << endl;
cout << dbr_size_n(new_dataTypeBuffer,c.channelRegalia.getNelem()) << " VERSUS "
<< c.channelRequestMetaData.getByteSize() << endl;
free(c.dataBuffer);
allocateMemory=true;
}
if (allocateMemory) {
//cout << "sizeof c.dataBuffer " << dbr_size_n(new_dataTypeBuffer,c.channelRegalia.getNelem()) << endl;
c.dataBuffer = (db_access_val *) malloc ( dbr_size_n(new_dataTypeBuffer,c.channelRegalia.getNelem()) );
c.channelRequestMetaData.byteSize=dbr_size_n(new_dataTypeBuffer,c.channelRequestMetaData.getNelem());
}
if (c.dataBuffer==NULL){
cout << __FILE__ << "/" << __LINE__ << "/" << __METHOD__ << endl;
printf ("Virtual memory exhausted for channel %s ", ca_name(c.channelID));
printf ("Exiting CAFE");
exit(0);
}
}
private:
chtype new_dataTypeBuffer;
#undef __METHOD__
};
/**
* Friend to CAFEConduit/CAFEGroup - releases resources
*/
struct free_dataBuffers
{
free_dataBuffers (){}
void operator() (Conduit& c) {
//cout << "c.handle=" << c.handle << " " << c.pv << endl;
if(c.dataBuffer) {
free(c.dataBuffer); // _TIME data buffer for ca_get
}
if(c.ctrlBuffer) {
free(c.ctrlBuffer); // _CTRL data buffer for ca_get
}
if(c.stsackBuffer) {
free(c.stsackBuffer); // _STSACK_STRING data buffer for ca_get
}
if(c.putBuffer) {
free(c.putBuffer); // data buffer for ca_put
}
}
};
#endif // CONDUITCONNECTIONHANDLERARGS_H