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