policies.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef POLICIES_H
00018 #define POLICIES_H
00019
00020 #include <cafeEnum.h>
00021 #include <defines.h>
00022 #include <statusCodes.h>
00023 #include <algorithm>
00024 #include <cstring>
00025 #include <iostream>
00026
00027
00028 #include <methodCallbacks.h>
00029
00030
00031
00032 using namespace CAFENUM;
00033 using namespace std;
00034
00035
00040 class ChannelCreatePolicy{
00041 private:
00042 unsigned short priority;
00043 static void callbackHandlerCreate(struct connection_handler_args args);
00044
00045 pCallbackConnection handler;
00046 public:
00047 pCallbackConnection getHandler(){return handler;};
00048 void setHandler(pCallbackConnection h){handler=h;};
00049 unsigned short getPriority() const {return priority;}
00050 unsigned short setPriority(unsigned short p){
00051 priority=std::min(p,(unsigned short) CA_SERVER_DISPATCH_PRIORITY_MAX);
00052 return priority;
00053 }
00054 ChannelCreatePolicy():priority(CA_SERVER_DISPATCH_PRIORITY_DEFAULT),handler(callbackHandlerCreate){};
00055 };
00056
00057
00062 class ChannelOpenPolicy{
00063 public:
00064
00065
00066 ChannelOpenPolicy():whenKind(FLUSH_AFTER_EACH_CHANNEL_CREATION), flushKind(WITH_PEND_EVENT),
00067 timeout(DEFAULT_TIMEOUT_PEND_EVENT),defaultTimeout(DEFAULT_TIMEOUT_PEND_EVENT){};
00068
00069 ChannelOpenPolicy(ChannelFlushSendBufferPolicyKind f,
00070 ChannelWhenToFlushSendBufferPolicyKind w, double t){
00071 if (f>=WITH_PEND_EVENT && f<=WITH_POLL)
00072 {setFlushSendBufferKind(f);} else {std::cout << f << " is an INVALID ChannelFlushSendBufferPolicyKind" << endl;}
00073 if (w>=FLUSH_AFTER_EACH_CHANNEL_CREATION && w<=FLUSH_DESIGNATED_TO_CLIENT)
00074 {setWhenToFlushSendBuffer(w);} else {std::cout << w << " is an INVALID ChannelWhenToFlushSendBufferPolicyKind" << endl;}
00075 setTimeout(t), setDefaultTimeout(DEFAULT_TIMEOUT_PEND_EVENT);
00076 };
00077 ~ChannelOpenPolicy(){};
00078 private:
00079 ChannelWhenToFlushSendBufferPolicyKind whenKind;
00080 ChannelFlushSendBufferPolicyKind flushKind;
00081 double timeout;
00082 double defaultTimeout;
00083 public:
00084 void flushSendBufferNow() {
00085 switch(flushKind){
00086 case WITH_PEND_EVENT:
00087 ca_pend_event(timeout);
00088 break;
00089 case WITH_PEND_IO:
00090 ca_pend_io(timeout);
00091 break;
00092 case WITH_FLUSH_IO:
00093 ca_flush_io();
00094 break;
00095 case WITH_POLL:
00096 ca_poll();
00097 break;
00098 default:
00099 ca_pend_event(timeout);
00100 break;
00101 }
00102
00103 setWhenToFlushSendBuffer(FLUSH_AFTER_EACH_CHANNEL_CREATION);
00104 };
00105 ChannelFlushSendBufferPolicyKind getFlushSendBufferKind() const {return flushKind;}
00106 ChannelWhenToFlushSendBufferPolicyKind getWhenToFlushSendBuffer() const {return whenKind;}
00107 double getTimeout() const {
00108
00109 return timeout;
00110 }
00111
00112 double getDefaultTimeout() const {return defaultTimeout;}
00113
00114 void setFlushSendBufferKind(ChannelFlushSendBufferPolicyKind f){if (f>=WITH_FLUSH_IO && f<=WITH_POLL)
00115 {flushKind=f;} else {std::cout << f << " is an INVALID ChannelFlushSendBufferPolicyKind" << endl;}};
00116
00117 void setWhenToFlushSendBuffer(ChannelWhenToFlushSendBufferPolicyKind w) {
00118 if (w>=FLUSH_AFTER_EACH_CHANNEL_CREATION && w<=FLUSH_DESIGNATED_TO_CLIENT)
00119 {whenKind=w;} else {std::cout << w << " is an INVALID ChannelWhenToFlushSendBufferPolicyKind" << endl;}};
00120
00121
00122 double setTimeout(double t) {
00123 if (t<0){
00124 std::cout << "CHANNELOPENPOLICY:setTimeout " << t << " seconds is an illegal value!" << endl;
00125 return timeout;
00126 }
00127 else if (t==0) {
00128 timeout=0.001;
00129 std::cout << "CHANNELOPENPOLICY:setTimeout " << " A value of zero would block the ioc for ever! "<< endl;
00130 std::cout << "CHANNELOPENPOLICY:setTimeout " << " Setting timeout to " << timeout << endl;
00131 return timeout=0.001;
00132 }
00133 return timeout=t;}
00134
00135 double setDefaultTimeout(double t) {
00136 if (t<0){
00137 std::cout << "CHANNELOPENPOLICY:setDefaultTimeout " << t << " seconds is an illegal value!" << endl;
00138 return defaultTimeout;
00139 }
00140 else if (t==0) {
00141 defaultTimeout=0.001;
00142 std::cout << "CHANNELOPENPOLICY:setDefaultTimeout " << " A value of zero would block the ioc for ever! "<< endl;
00143 std::cout << "CHANNELOPENPOLICY:setDefaultTimeout " << " Setting timeout to " << defaultTimeout << endl;
00144 return defaultTimeout;
00145 }
00146 return defaultTimeout=t;}
00147
00148 double setTimeoutToDefault() {return timeout=defaultTimeout;}
00149
00150 void setPolicy(ChannelWhenToFlushSendBufferPolicyKind w, ChannelFlushSendBufferPolicyKind f, double t){
00151 if (f>=WITH_FLUSH_IO && f<=WITH_POLL){flushKind=f;}
00152 else {std::cout << f << " is an INVALID ChannelFlushSendBufferPolicyKind" << endl;}
00153 if (w>=FLUSH_AFTER_EACH_CHANNEL_CREATION && w<=FLUSH_DESIGNATED_TO_CLIENT)
00154 {whenKind=w;}
00155 else {std::cout << w << " is an INVALID ChannelWhenToFlushSendBufferPolicyKind" << endl;}
00156 timeout = t;
00157 defaultTimeout = t;
00158
00159 };
00160 };
00161
00162
00163
00167 class ChannelRequestDataTypePolicy{
00168 private:
00169 CAFENUM::ChannelRequestDataTypePolicyKind requestKind;
00170 public:
00171 void setRequestKind(CAFENUM::ChannelRequestDataTypePolicyKind rk) {
00172 if (rk>=CAFENUM::NATIVE_DATATYPE && rk<=CAFENUM::LOWEST_DATATYPE)
00173 {requestKind=rk;}
00174 else {std::cout << rk << " is an INVALID ChannelDataTypePolicyKind" << endl;}
00175 };
00176
00177 CAFENUM::ChannelRequestDataTypePolicyKind getRequestKind() const {return requestKind;}
00178
00179 ChannelRequestDataTypePolicy():requestKind(CAFENUM::NATIVE_DATATYPE){};
00180 ChannelRequestDataTypePolicy(CAFENUM::ChannelRequestDataTypePolicyKind rk){requestKind=rk;};
00181 };
00182
00183
00184
00188 class ChannelGetCacheWaitPolicy{
00189 private:
00190 CAFENUM::ChannelGetCacheWaitPolicyKind getCacheWaitKind;
00191 public:
00192 void setWaitKind(CAFENUM::ChannelGetCacheWaitPolicyKind wk) {
00193 if (wk>=CAFENUM::GET_CACHE_NO_WAIT && wk<=CAFENUM::GET_CACHE_WAIT)
00194 {getCacheWaitKind=wk;}
00195 else {std::cout << wk << " is an INVALID ChannelGetCacheWaitKind" << endl;}
00196 };
00197
00198 CAFENUM::ChannelGetCacheWaitPolicyKind getWaitKind() const {return getCacheWaitKind;}
00199
00200 ChannelGetCacheWaitPolicy():getCacheWaitKind(CAFENUM::GET_CACHE_WAIT){};
00201 ChannelGetCacheWaitPolicy(CAFENUM::ChannelGetCacheWaitPolicyKind wk){getCacheWaitKind=wk;};
00202 };
00203
00204
00205
00209 class ChannelGetActionWhenMonitorPolicy{
00210 private:
00211 CAFENUM::ChannelGetActionWhenMonitorPolicyKind getActionWhenMonitorKind;
00212 public:
00213 void setActionKind(CAFENUM::ChannelGetActionWhenMonitorPolicyKind ak) {
00214 if (ak>=CAFENUM::GET_FROM_CACHE && ak<=CAFENUM::GET_FROM_IOC)
00215 {getActionWhenMonitorKind=ak;}
00216 else {std::cout << ak << " is an INVALID ChannelGetActionWhenMonitorKind" << endl;}
00217 };
00218
00219 CAFENUM::ChannelGetActionWhenMonitorPolicyKind getActionKind() const {return getActionWhenMonitorKind;}
00220
00221 ChannelGetActionWhenMonitorPolicy():getActionWhenMonitorKind(CAFENUM::GET_FROM_IOC){};
00222 ChannelGetActionWhenMonitorPolicy(CAFENUM::ChannelGetActionWhenMonitorPolicyKind ak){getActionWhenMonitorKind=ak;};
00223 };
00224
00225
00226
00233 class ChannelTimeoutPolicy{
00234 private:
00235 bool selfGoverningTimeout;
00236 double timeout;
00237 double deltaTimeout;
00238 unsigned short ntries;
00239 double defaultTimeout;
00240 public:
00241 bool getSelfGoverningTimeout() const {return selfGoverningTimeout;};
00242 void setSelfGoverningTimeout(bool sgt){selfGoverningTimeout=sgt;};
00243 double getTimeout() const {return timeout;};
00244 double getDefaultTimeout() const {return defaultTimeout;}
00245 double getDeltaTimeout() const {return deltaTimeout;};
00246 unsigned short getNtries() const {return ntries;};
00247 double setTimeout(double t) {timeout=max(t,TIMEOUT_PEND_IO_MIN);
00248 return timeout=min(timeout,TIMEOUT_PEND_IO_MAX);};
00249 double setDeltaTimeout(double dt) { deltaTimeout=max(dt,PEND_IO_INCREMENT_TIME_MIN);
00250 return deltaTimeout=min(deltaTimeout,PEND_IO_INCREMENT_TIME_MAX);};
00251 unsigned short setNtries(unsigned short nt) {return ntries=min(nt, PEND_IO_MAX_TRIES);};
00252
00253 double setDefaultTimeout(double t) {return defaultTimeout=t;}
00254 double setTimeoutToDefault() {return timeout=defaultTimeout;}
00255
00256 ChannelTimeoutPolicy():selfGoverningTimeout(DEFAULT_SELF_GOVERNING_TIMEOUT),
00257 timeout(DEFAULT_TIMEOUT_PEND_IO),deltaTimeout(DEFAULT_PEND_IO_INCREMENT_TIME),
00258 ntries(DEFAULT_PEND_IO_NO_TRIES),defaultTimeout(DEFAULT_TIMEOUT_PEND_IO){};
00259
00260 };
00261
00262
00267 class ChannelRequestPolicy{
00268 private:
00269
00270 ChannelWhenToFlushSendBufferPolicyKind whenKind;
00271 ChannelWaitForResponsePolicyKind waitKind;
00272
00273 ChannelRequestPolicyKind methodKind;
00274
00275 pCallback handler;
00276 int callbackStatus;
00277
00278 public:
00279
00280 ChannelWhenToFlushSendBufferPolicyKind getWhenToFlushSendBuffer() const {return whenKind;}
00281 ChannelWaitForResponsePolicyKind getWaitKind() const {return waitKind;};
00282
00283 ChannelRequestPolicyKind getMethodKind() const {return methodKind;};
00284
00285 pCallback getHandler() const {return handler;};
00286
00287 int getCallbackStatus() const {return callbackStatus;};
00288
00289 void setHandler(pCallback h){if (h!=NULL) {handler=h; methodKind=WITH_CALLBACK_USER_SUPPLIED;}};
00290
00291 #if HAVE_PYTHON_H
00292 void setPyHandlerGet(){handler= CALLBACK_CAFE::PyHandlerGet; methodKind=WITH_CALLBACK_USER_SUPPLIED;};
00293 void setPyHandlerPut(){handler= CALLBACK_CAFE::PyHandlerPut; methodKind=WITH_CALLBACK_USER_SUPPLIED;};
00294 #endif
00295
00296 void setMethodKind(ChannelRequestPolicyKind m) { if (m>=WITHOUT_CALLBACK && m<=WITH_CALLBACK_USER_SUPPLIED)
00297 {methodKind=m;} else {std::cout << m << " is an INVALID ChannelRequestPolicyKind" << std::endl;} };
00298
00299 void setWhenToFlushSendBuffer(ChannelWhenToFlushSendBufferPolicyKind w) {
00300 if (w>=FLUSH_AFTER_EACH_MESSAGE && w<=FLUSH_DESIGNATED_TO_CLIENT)
00301 {whenKind=w;} else {std::cout << w << " is an INVALID ChannelWhenToFlushSendBufferPolicyKind" << std::endl;}};
00302
00303 void setWaitKind(ChannelWaitForResponsePolicyKind r) { if (r>=WAIT && r<=NO_WAIT)
00304 {waitKind=r;} else {std::cout << r << " is an INVALID ChannelWaitForResponsePolicyKind" << std::endl;}};
00305
00306 void setCallbackStatus (int cstatus) {callbackStatus =cstatus;};
00307
00308 void setPolicy(
00309 ChannelWhenToFlushSendBufferPolicyKind w, ChannelWaitForResponsePolicyKind r,
00310 ChannelRequestPolicyKind m)
00311 {
00312 if (w>=FLUSH_AFTER_EACH_MESSAGE && w<=FLUSH_DESIGNATED_TO_CLIENT)
00313 {whenKind=w;} else {std::cout << "ERROR in setting ChannelRequestPolicy " << std::endl;
00314 std::cout << w << " is an INVALID ChannelWhenToFlushSendBufferPolicyKind" << endl;
00315 std::cout << "Sticking to default value ChannelWhenToFlushSendBufferPolicyKind=" << whenKind << std::endl;
00316 }
00317 if (r>=WAIT && r<=NO_WAIT)
00318 {waitKind=r;} else {std::cout << "ERROR in setting ChannelRequestPolicy " << std::endl;
00319 std::cout << r<< " is an INVALID ChannelWaitForResponsePolicyKind" << endl;
00320 std::cout << "Sticking to default value ChannelWaitForRespomsePolicyKind=" << waitKind << std::endl;
00321 }
00322 if (m>=WITHOUT_CALLBACK && m<=WITH_CALLBACK_USER_SUPPLIED)
00323 {methodKind=m;} else {std::cout << "ERROR in setting ChannelRequestPolicy " << std::endl;
00324 std::cout << r<< " is an INVALID ChannelRequestPolicyKind" << endl;
00325 std::cout << "Sticking to default value ChannelRequestPolicyKind=" << methodKind << std::endl;
00326 }
00327
00328 if (methodKind==WITHOUT_CALLBACK && waitKind==NO_WAIT) {
00329 std::cout << "WARNING when setting ChannelRequestPolicy " << std::endl;
00330 std::cout << "waitKind=NO_WAIT does not apply when methodKind=WITHOUT_CALLBACK " << std::endl;
00331
00332 }
00333 };
00334
00335
00336 ChannelRequestPolicy():
00337 whenKind(FLUSH_AFTER_EACH_MESSAGE),waitKind(WAIT),methodKind(WITHOUT_CALLBACK),
00338 callbackStatus(ICAFE_NORMAL){
00339 handler=NULL;
00340 };
00341
00342 ChannelRequestPolicy(ChannelRequestPolicyKind b){
00343 if (b>=WITHOUT_CALLBACK && b<=WITH_CALLBACK_USER_SUPPLIED)
00344 {methodKind=b;} else {cout << b << " is anINVALID ChannelRequestPolicyKind" << endl;}
00345 handler=NULL;
00346 callbackStatus=ICAFE_NORMAL;
00347 whenKind=FLUSH_AFTER_EACH_MESSAGE;
00348 waitKind=WAIT;
00349 };
00350
00351 ChannelRequestPolicy(pCallback h){
00352 handler=h;
00353 methodKind=WITH_CALLBACK_DEFAULT;
00354 whenKind=FLUSH_AFTER_EACH_MESSAGE;
00355 waitKind=WAIT;
00356 callbackStatus =ICAFE_NORMAL;
00357 }
00358
00359 ~ChannelRequestPolicy(){};
00360 };
00361
00362
00363
00372 class MonitorPolicy
00373 {
00374 friend class Conduit;
00375 friend class Connect;
00376 private:
00377 static unsigned int idNext;
00378 chtype dataType;
00379 chtype dbrDataType;
00380 CAFENUM::DBR_TYPE cafeDbrType;
00381 unsigned int nelem;
00382
00383 unsigned int mask;
00384 pCallback handler;
00385 void * userArgs;
00386 evid eventID;
00387 int status;
00388 unsigned int id;
00389
00390 static void callbackHandlerMonitor(struct event_handler_args args);
00391 static void PyCallbackHandlerMonitorData(struct event_handler_args args);
00392 static void PyCallbackHandlerMonitor(struct event_handler_args args);
00393
00394 void setEventID(evid e){eventID=e;};
00395
00396 public:
00397 MonitorPolicy():dataType((CAFE_DATATYPE) CAFE_NOT_REQUESTED),
00398 dbrDataType((CAFE_DATATYPE) CAFE_NOT_REQUESTED),
00399 cafeDbrType((CAFENUM::DBR_TYPE) CAFENUM::DBR_TIME),
00400 nelem(0), mask(DBE_VALUE | DBE_LOG | DBE_ALARM),
00401 handler(callbackHandlerMonitor), userArgs(NULL), eventID(NULL),
00402 status(ICAFE_NORMAL){
00403 ++idNext;
00404 id = idNext;
00405 };
00406 chtype getDataType() const {return dataType;};
00407 chtype getDbrDataType() const {return dbrDataType;};
00408 CAFENUM::DBR_TYPE getCafeDbrType() const {return cafeDbrType;};
00409 unsigned int getNelem() const {return nelem;};
00410
00411 unsigned int getMask() const {return mask;};
00412
00413 bool maskHasDBE_PROPERTY() const {bool has=false;
00414 # if (EPICS_MAJOR==3 && EPICS_MINOR>=14 && EPICS_PATCH >=11)
00415 mask & DBE_PROPERTY ? has=true : has=false;
00416 # endif
00417 return has;
00418 };
00419 bool maskHasDBE_VALUE() const {bool has=false; mask & DBE_VALUE ? has=true : has=false; return has;};
00420 bool maskHasDBE_LOG() const {bool has=false; mask & DBE_LOG ? has=true : has=false; return has;};
00421 bool maskHasDBE_ALARM() const {bool has=false; mask & DBE_ALARM ? has=true : has=false; return has;};
00422 pCallback getHandler() const {return handler;};
00423 void * getUserArgs() const {return userArgs;};
00424
00425
00426
00427 unsigned int getUserArgsAsInt() const {return (unsigned int) ((long long) (void *)userArgs);};
00428 evid getEventID() const {return eventID;};
00429 unsigned int getMonitorID() const {return id;};
00430 int getStatus() const {return status;};
00431 unsigned int getID() const {return id;};
00432
00433
00434 void setMask(unsigned int m) {mask=m;};
00435
00436 void setPyHandler(){handler= PyCallbackHandlerMonitor;};
00437 void setPyHandlerData(){handler= PyCallbackHandlerMonitorData;};
00438 void setDefaultHandler(){handler= callbackHandlerMonitor;};
00439
00440 void setHandler(pCallback h){handler=h;};
00441 void setNelem(unsigned int n){nelem=n;};
00442 void setDataType(chtype dt){ if (dt < DBR_PUT_ACKT) {
00443 dataType=dt%(LAST_TYPE+1);} else {
00444 cout << "monitorPolicy FUNNY! " << dt << " is an INVALID DATATYPE! " << endl;
00445 return;}
00446 switch(cafeDbrType) {
00447 case CAFENUM::DBR_TIME:
00448 dbrDataType=(dbf_type_to_DBR_TIME(dataType));
00449 break;
00450 case CAFENUM::DBR_STS:
00451 dbrDataType=(dbf_type_to_DBR_STS (dataType));
00452 break;
00453 case CAFENUM::DBR_PRIMITIVE:
00454 dbrDataType=(dbf_type_to_DBR (dataType));
00455 break;
00456 case CAFENUM::DBR_CTRL:
00457 dbrDataType=(dbf_type_to_DBR_CTRL(dataType));
00458 break;
00459 case CAFENUM::DBR_GR:
00460 dbrDataType=(dbf_type_to_DBR_GR (dataType));
00461 break;
00462 default:
00463 dbrDataType=(dbf_type_to_DBR_TIME(dataType));
00464 }
00465 };
00466
00467 void setCafeDbrType( CAFENUM::DBR_TYPE cdt) {if (cdt > DBR_PUT) {
00468 cout << "monitorPolicy FUNNY! " << cdt << " is an INVALID CAFENUM::DBR_TYPE! " << endl;
00469 return;} else { cafeDbrType=cdt;}
00470
00471
00472 switch(cafeDbrType) {
00473 case CAFENUM::DBR_TIME:
00474 dbrDataType=(dbf_type_to_DBR_TIME(dataType));
00475 break;
00476 case CAFENUM::DBR_STS:
00477 dbrDataType=(dbf_type_to_DBR_STS (dataType));
00478 break;
00479 case CAFENUM::DBR_PRIMITIVE:
00480 dbrDataType=(dbf_type_to_DBR (dataType));
00481 break;
00482 case CAFENUM::DBR_CTRL:
00483 dbrDataType=(dbf_type_to_DBR_CTRL(dataType));
00484 break;
00485 case CAFENUM::DBR_GR:
00486 dbrDataType=(dbf_type_to_DBR_GR (dataType));
00487 break;
00488 default:
00489 dbrDataType=(dbf_type_to_DBR_TIME(dataType));
00490 }
00491
00492 }
00493
00494
00495
00496 void setUserArgs(void * u){userArgs=u;};
00497 void setStatus(int s){status=s;};
00498 void print() {
00499 cout << "-------------------------------" << endl;
00500 cout << "Monitor Policy " << endl;
00501 cout << "-------------------------------" << endl;
00502 cout << "dbrDataType = " << dbr_type_to_text(dbrDataType) << endl;
00503 cout << "nelem = " << nelem << endl;
00504 cout << "eventID = " << eventID << endl;
00505 cout << "monitorID = " << id << endl;
00506 cout << "-------------------------------" << endl;
00507 }
00508 };
00509
00510
00511
00512 #endif // POLICIES_H